передача массивов в функции в x86 asm - PullRequest
1 голос
/ 02 сентября 2011

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

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

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

Файл asm будет скомпилирован в DLL-библиотеку win32.

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

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, но я даже не смог найти в нем свою функцию.

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

Ответы [ 2 ]

2 голосов
/ 02 сентября 2011

Я давно не писал 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 и коды операций.Некоторое время я этим не пользовался и, к сожалению, не мог вспомнить инструкции на макушке.

0 голосов
/ 25 сентября 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

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

...