我正在学习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中相应的反汇编代码,但我甚至找不到我的函数。
谢天谢地。
答案 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
我刚刚写了这段代码,让你理解这个概念。我留给你来弄清楚如何正确地计算寄存器的用法以实现你的程序目标。