extern "C" void fun(int a, int b) {
int x = a;
int y = b;
int z = x + y;
return;
}
int main() {
fun(5, 10);
return 0;
}
对于这样的一个C函数的调用过程,我们可以用下面的汇编代码来描述:
1.前提8086CPU中,bsp用来保存栈的指针,esp用来保存新建立的栈的指针
2.形参会保存在ebp + x 的地方, 而函数内部的局部变量被保存在ebp - x的地方,
3.对于一个函数的调用之前,编译器都会在函数调用之前插入一段代码,用于将形参入栈!
所以对于上面的C代码,产生的汇编代码应该象下面这样:
1.调用的代码:
push 10 ; 0000000aH
push 5
call _fun@8
2.函数代码:
push ebp ;保存先前地址
mov ebp, esp ;将新的栈地址放入ebp
sub esp, 12
mov eax, DWORD PTR _a$[ebp]
mov DWORD PTR _x$[ebp], eax
mov ecx, DWORD PTR _b$[ebp]
mov DWORD PTR _y$[ebp], ecx
mov edx, DWORD PTR _x$[ebp]
add edx, DWORD PTR _y$[ebp]
mov DWORD PTR _z$[ebp], edx
mov esp, ebp
pop ebp
ret 0
_x _y是什么呢??让我们来看看!
_a$ = 8
_b$ = 12
_x$ = -4
_y$ = -8
_z$ = -12
实际上 就是一些数而已。
所以说,我们可以这样来队X,Y赋值
; int x = a;
mov eax, DWORD PTR [ebp + 8];加八的原因是因为+4的地方用来保存返回的值的地址
mov DWORD PTR [ebp - 4], eax
; int y = b;
mov ecx, DWORD PTR [ebp + 12]
mov DWORD PTR [ebp - 8], ecx
; int z = x + y;
mov edx, DWORD PTR [ebp - 4]
add edx, DWORD PTR [ebp - 8]
mov DWORD PTR [ebp - 12], edx