Передача элементов массива

Тема в разделе "WASM.ASSEMBLER", создана пользователем YanDr, 5 июн 2009.

  1. YanDr

    YanDr New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2009
    Сообщения:
    3
    Доброго времени суток!
    Есть проблема. Необходимо передать массив вещественных чисел из модуля С++ в модуль ассемблера.
    С++
    Код (Text):
    1. #include <stdio.h>
    2. #include <conio.h>
    3. extern "C" {int Calculat(float far * ValuePtr, int NumberOfValues);}
    4. extern "C" int FlagC;
    5. extern "C" double Result;
    6. #define NUMBER_OF_TEST_VALUES 10
    7. float A[NUMBER_OF_TEST_VALUES] = {1, 4, 3, 4, 5, 6, 7, 8, 9, 10};
    8. long C=5;
    9. long D=8;
    10.  
    11. int main(void)
    12. {
    13.   int i;
    14.   Сalculat(A,NUMBER_OF_TEST_VALUES);
    15.   return 0;
    16. }
    АСМ
    Код (Text):
    1. .486            
    2. .MODEL   COMPACT        ; выбрать малую модель памяти
    3. .data
    4. EXTRN   _C:DWORD        ; внешний идентификатор C
    5. EXTRN   _D:DWORD        ; внешний идентификатор
    6.  
    7. PUBLIC  _FlagC  ; внешний идентификатор
    8.     _FlagC DW 01h ; внешний идентификатор
    9.  
    10. PUBLIC  _Result ; внешний идентификатор
    11.     _Result DQ 1h ; внешний идентификатор
    12.  
    13. .data?
    14.     Powr    DW      0h
    15.     Temp    DD      0h
    16.  
    17. .CODE                   ; сегмент кода, совместимый с Borland C++
    18. PUBLIC  _Calculat
    19. _Calculat PROC          ; функция (в малой модели памяти вызывается с помощью вызова
    20.               ARG    FillArray:DWORD, Count:WORD
    21.               push   ebp           ; сохранить указатель стека
    22.                                   ; вызывающей программы
    23.               mov    ebp,esp        ; установить свой собственный
    24.                                   ; указатель стека
    25.               mov    ebx,[FillArray] ; получить указатель на
    26.                                   ; заполняемый массив
    27.               mov    ecx,[Count]   ; получить заполняемую длину
    28.      FillLoop:
    29.               mov    eax,[ebx]      ; заполнить символ
    30.               add    ebx,04           ; ссылка на следующий символ
    31.               loop   FillLoop     ; обработать следующий символ
    32.               pop    ebp           ; восстановить указатель стека
    33.               ret
    34.  
    35. _Calculat        ENDP
    36. END
    Как правильно извлечь в асме элементы массива?
     
  2. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    Count = word
    Код (Text):
    1. movzx    ecx,[Count]   ; получить заполняемую длину
    Куда указывает eax
    Код (Text):
    1. mov    eax,[ebx]      ; заполнить символ
    Что значит извлечь?
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    полагаю YanDr интересует команда FLD и иже с ней.
    http://www.wasm.ru/article.php?article=edfpu01
    http://www.wasm.ru/article.php?article=edfpu02
     
  4. YanDr

    YanDr New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2009
    Сообщения:
    3
    Получить доступ к элементам массива из ассемблерного модуля

    JCronuz дело в том что после выполнения
    movzx ecx,[Count] в ecx содержится 0, вместо 10
    mov ebx,[FillArray] по адресу содержатся не те данные.

    Y_Mur с обработкой проблем нет, имеется проблема имеено с доступам к элементам массива
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    YanDr
    Глянь в отладчике - скорее всего директива PROC сама вставляет push ebp; mov ebp,esp; и сделав это второй раз ты естественно получаешь сдвинутые ссылки.
     
  6. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    И ещё - тебя же и в С++ и в .MODEL COMPACT базовый размер операнда 16 бит, значит ссылка на массив должна быть в формате сегмент:смещение. Сегмент грузишь в ds
    mov ax, [...]
    mov ds, ax
    поскольку в DOS всё с оглядкой на сегментацию памяти делать нужно ;)
    И стековый кадр функции нужно формировать
    push bp
    mov bp,sp
    если конечно у тебя пролог функции не генерируется автоматически директивой PROC
     
  7. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    У меня movzx нормально передает 10, в отладчике смотрел, а mov не компилируется
     
  8. YanDr

    YanDr New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2009
    Сообщения:
    3
    Решил следующим образом
    Код (Text):
    1. .MODEL   SMALL          ; выбрать малую модель памяти (ближний код и данные)
    2. .data
    3. EXTRN   _C:DWORD        ; внешний идентификатор C
    4. EXTRN   _D:DWORD        ; внешний идентификатор
    5.  
    6. PUBLIC  _FlagC  ; внешний идентификатор
    7.     _FlagC DW 01h ; внешний идентификатор
    8.  
    9. PUBLIC  _Result ; внешний идентификатор
    10.     _Result DD 01h ; внешний идентификатор
    11.  
    12. .data?
    13.     Temp    DD      0h
    14.     Status87 label Word
    15.  
    16. .CODE                   ; сегмент кода, совместимый с Borland C++
    17. PUBLIC  _Calculat
    18. _Calculat PROC  near
    19.     push   bp           ; сохранить указатель стека вызывающей программы
    20.     finit  
    21.     mov    bp,sp
    22.     les bx,[bp+4]       ; ES:BX указывает на массив значений
    23.     mov cx,[bp+8]       ; получить заполняемую длину
    24. FillLoop:
    25.  
    26.     mov    ax,[bx]          ; заполнить символ
    27.     push bx
    28.     LEA  bx, Temp           ; загрузим текущий адрес Temp в BX
    29.     MOV WORD PTR [bX], AX   ; сохранение младшего слова результата в Temp.
    30.     pop bx
    31.     mov ax,[bx+2]      
    32.     push bx
    33.     LEA  bx, Temp           ; загрузим текущий адрес REZ в BX
    34.     MOV WORD PTR [bX+2], AX ; сохранение старшего слова результата в Temp.
    35.     pop bx
    36.  
    37.            .   .   .
    38.            обработка чисел в сопроцессоре
    39.            .   .   .
    40.  
    41. nxt:
    42.     add    bx,04           ; ссылка на следующий символ
    43.     loop   FillLoop     ; обработать следующий символ
    44.     pop    bp           ; восстановить указатель стека вызывающей программы
    45.     ret
    46. _Calculat        ENDP
    47. END