Доброго времени суток! Есть проблема. Необходимо передать массив вещественных чисел из модуля С++ в модуль ассемблера. С++ Код (Text): #include <stdio.h> #include <conio.h> extern "C" {int Calculat(float far * ValuePtr, int NumberOfValues);} extern "C" int FlagC; extern "C" double Result; #define NUMBER_OF_TEST_VALUES 10 float A[NUMBER_OF_TEST_VALUES] = {1, 4, 3, 4, 5, 6, 7, 8, 9, 10}; long C=5; long D=8; int main(void) { int i; Сalculat(A,NUMBER_OF_TEST_VALUES); return 0; } АСМ Код (Text): .486 .MODEL COMPACT ; выбрать малую модель памяти .data EXTRN _C:DWORD ; внешний идентификатор C EXTRN _D:DWORD ; внешний идентификатор PUBLIC _FlagC ; внешний идентификатор _FlagC DW 01h ; внешний идентификатор PUBLIC _Result ; внешний идентификатор _Result DQ 1h ; внешний идентификатор .data? Powr DW 0h Temp DD 0h .CODE ; сегмент кода, совместимый с Borland C++ PUBLIC _Calculat _Calculat PROC ; функция (в малой модели памяти вызывается с помощью вызова ARG FillArray:DWORD, Count:WORD push ebp ; сохранить указатель стека ; вызывающей программы mov ebp,esp ; установить свой собственный ; указатель стека mov ebx,[FillArray] ; получить указатель на ; заполняемый массив mov ecx,[Count] ; получить заполняемую длину FillLoop: mov eax,[ebx] ; заполнить символ add ebx,04 ; ссылка на следующий символ loop FillLoop ; обработать следующий символ pop ebp ; восстановить указатель стека ret _Calculat ENDP END Как правильно извлечь в асме элементы массива?
Count = word Код (Text): movzx ecx,[Count] ; получить заполняемую длину Куда указывает eax Код (Text): mov eax,[ebx] ; заполнить символ Что значит извлечь?
полагаю YanDr интересует команда FLD и иже с ней. http://www.wasm.ru/article.php?article=edfpu01 http://www.wasm.ru/article.php?article=edfpu02
Получить доступ к элементам массива из ассемблерного модуля JCronuz дело в том что после выполнения movzx ecx,[Count] в ecx содержится 0, вместо 10 mov ebx,[FillArray] по адресу содержатся не те данные. Y_Mur с обработкой проблем нет, имеется проблема имеено с доступам к элементам массива
YanDr Глянь в отладчике - скорее всего директива PROC сама вставляет push ebp; mov ebp,esp; и сделав это второй раз ты естественно получаешь сдвинутые ссылки.
И ещё - тебя же и в С++ и в .MODEL COMPACT базовый размер операнда 16 бит, значит ссылка на массив должна быть в формате сегмент:смещение. Сегмент грузишь в ds mov ax, [...] mov ds, ax поскольку в DOS всё с оглядкой на сегментацию памяти делать нужно И стековый кадр функции нужно формировать push bp mov bp,sp если конечно у тебя пролог функции не генерируется автоматически директивой PROC
Решил следующим образом Код (Text): .MODEL SMALL ; выбрать малую модель памяти (ближний код и данные) .data EXTRN _C:DWORD ; внешний идентификатор C EXTRN _D:DWORD ; внешний идентификатор PUBLIC _FlagC ; внешний идентификатор _FlagC DW 01h ; внешний идентификатор PUBLIC _Result ; внешний идентификатор _Result DD 01h ; внешний идентификатор .data? Temp DD 0h Status87 label Word .CODE ; сегмент кода, совместимый с Borland C++ PUBLIC _Calculat _Calculat PROC near push bp ; сохранить указатель стека вызывающей программы finit mov bp,sp les bx,[bp+4] ; ES:BX указывает на массив значений mov cx,[bp+8] ; получить заполняемую длину FillLoop: mov ax,[bx] ; заполнить символ push bx LEA bx, Temp ; загрузим текущий адрес Temp в BX MOV WORD PTR [bX], AX ; сохранение младшего слова результата в Temp. pop bx mov ax,[bx+2] push bx LEA bx, Temp ; загрузим текущий адрес REZ в BX MOV WORD PTR [bX+2], AX ; сохранение старшего слова результата в Temp. pop bx . . . обработка чисел в сопроцессоре . . . nxt: add bx,04 ; ссылка на следующий символ loop FillLoop ; обработать следующий символ pop bp ; восстановить указатель стека вызывающей программы ret _Calculat ENDP END