1

我正在学习 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 中查看相应的反汇编代码,但我什至在其中找不到我的函数。

非常感谢你。

4

2 回答 2

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 堆栈和操作码来进行算术运算。我已经有一段时间没有使用它了,不幸的是,我不记得头顶上的说明了。

于 2011-09-02T13:01:31.740 回答
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

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

于 2011-09-25T06:57:38.110 回答