передача массивов в функции в x86 asm

Я изучаю x86 asm и использую masm и пытаюсь написать функцию, которая имеет эквивалентную сигнатуру следующей функции c:

void func(double a[], double b[], double c[], int len);

Я не уверен, как это реализовать?

Ассемблерный файл будет скомпилирован в win32 DLL.

Чтобы я мог понять, как это сделать, может кто-нибудь перевести эту очень простую функцию на ассемблер для меня:

void func(double a[], double b[], double c[], int len)
{
  // a, b, and c have the same length, given by len
  for (int i = 0; i < length; i++)
    c[i] = a[i] + b[i];
}

Я пытался написать подобную функцию на C, скомпилировать ее и посмотреть соответствующий дизассемблированный код в exe с помощью OllyDbg, но я даже не смог найти в нем свою функцию.

Спасибо любезно.


person mNa0s0mB    schedule 02.09.2011    source источник
comment
почему бы вам не опубликовать здесь ASM, который у вас есть. может быть полезно!   -  person Stefano    schedule 02.09.2011
comment
У меня пока нет... Я примерно знаю, какие операции мне нужны в функции, но я не знаю, как определить процедуру или как ссылаться на переменные массива. Если я увижу перевод этого цикла, я буду знать все, что мне нужно, чтобы написать свою функцию ASM.   -  person mNa0s0mB    schedule 02.09.2011
comment
извините .... я имею в виду код, который вы получили с помощью компилятора. Я признаю, что я никогда не передавал некоторые массивы.... но, может быть, если я увижу код, сгенерированный компилятором, у меня появятся некоторые идеи...:)   -  person Stefano    schedule 02.09.2011
comment
Попросите компилятор сгенерировать файл .cod. Он содержит ассемблерную версию вашей функции, готовую к сборке.   -  person Raymond Chen    schedule 02.09.2011
comment
@ Raymond Вау, я не знал, что ты можешь это сделать ... Я только что попробовал, и это сработало. Это значительно облегчит изучение ASM. Спасибо!   -  person mNa0s0mB    schedule 02.09.2011


Ответы (2)


Я некоторое время не писал x86, но могу дать вам общее представление о том, как это сделать. Так как у меня нет под рукой ассемблера, это написано в блокноте.

func proc a:DWORD, b:DWORD, c:DWORD, len:DWORD

  mov eax, len
  test eax, eax
  jnz @f
  ret

    @@:

  push ebx
  push esi

  xor eax, eax

  mov esi, a
  mov ebx, b
  mov ecx, c

    @@:

  mov edx, dword ptr ds:[ebx+eax*4]
  add edx, dword ptr ds:[ecx+eax*4]
  mov [esi+eax*4], edx
  cmp eax, len
  jl @b

  pop esi
  pop ebx

  ret  

func endp

Приведенная выше функция соответствует stdcall и приблизительно соответствует тому, как вы бы транслировали в x86, если бы ваши аргументы были целыми числами. К сожалению, вы используете двойники. Цикл будет таким же, но вам нужно будет использовать стек FPU и коды операций для выполнения арифметических операций. Я не использовал это какое-то время и, к сожалению, не мог вспомнить инструкции навскидку.

person Mike Kwan    schedule 02.09.2011

Вы должны передать адреса памяти массивов. Рассмотрим следующий код:

.data?
array1 DWORD 4 DUP(?)

.code
         main PROC

                      push LENGTHOF array1
                      push OFFSET array1
                      call arrayFunc             
         main ENDP

         arrayFunc PROC
                                   push ebp
                                   mov ebp, esp
                                   push edi

                                   mov edi, [ebp+08h] 
                                   mov ecx, [ebp+0Ch]
                                   L1:

                                  ;reference each element of given array by [edi]
                                  ;add "TYPE" *array* to edi to increment
                                   loop L1:
                                   pop edi
                                   pop ebp
                                   ret 8
         arrayFunc ENDP
         END main

Я просто написал этот код, чтобы вы поняли концепцию. Я оставляю это вам, чтобы выяснить, как правильно использовать регистры для достижения целей вашей программы.

person devjeetroy    schedule 25.09.2011