将数组传递给x86 asm中的函数

时间:2011-09-02 12:45:40

标签: windows assembly masm masm32

我正在学习x86 asm并使用masm,并且我正在尝试编写一个与以下c函数具有等效签名的函数:

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

我不确定如何实施它?

asm文件将被编译为win32 DLL。

为了让我能理解如何做到这一点,有人可以将这个非常简单的功能翻译成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中编写这样的函数,编译它,并使用OllyDbg查看exe中相应的反汇编代码,但我甚至找不到我的函数。

谢天谢地。

2 个答案:

答案 0 :(得分: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堆栈和操作码来进行算术运算。我有一段时间没有使用它,不幸的是忘记了我头顶的指令。

答案 1 :(得分:0)

您必须传递数组的内存地址。请考虑以下代码:

.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

我刚刚写了这段代码,让你理解这个概念。我留给你来弄清楚如何正确地计算寄存器的用法以实现你的程序目标。