C源码#include 'stdio.h' int test(int x, int y, double& z) { z = x + y; return 0; } void main() { double sum = 1.2; int a = 2 ,b = 3 , ret = 0; ret = test(a, b, sum); printf('ret:%d', ret); } 对应的汇编代码void main() 11: { 寄存器 栈单元地址 栈单元内容或解释
00410990 push ebp //压入之前调用栈的栈底地址,栈元素增加1 00410991 mov ebp,esp //新栈空间的栈底地址EBP设置为增加的这个栈元素地址(即调用者栈栈帧的栈底地址) 00410993 sub esp,54h //分配54h 即84字节栈内存 00410996 push ebx //保存各寄存器内容 00410997 push esi 00410998 push edi 00410999 lea edi,[ebp-54h] //取新分配内存的低地址 0041099C mov ecx,15h //计数器设置15h, 及21个4字节 004109A1 mov eax,0CCCCCCCCh //写入eax, 0CCCCCCCCh表示初始化的内存 004109A6 rep stos dword ptr [edi] //将eax内容写入内存地址,计数,写15h次。 12: double sum = 1.2; 004109A8 mov dword ptr [ebp-8],33333333h 004109AF mov dword ptr [ebp-4],3FF33333h 13: int a = 2 ,b = 3 , ret = 0; 004109B6 mov dword ptr [ebp-0Ch],2 004109BD mov dword ptr [ebp-10h],3 004109C4 mov dword ptr [ebp-14h],0 //变量初始化, EBP-X 表示变量地址,先分配的变量减的少,后分配的减的多 14: ret = test(a, b, sum); 004109CB lea eax,[ebp-8] 004109CE push eax 004109CF mov ecx,dword ptr [ebp-10h] 004109D2 push ecx 004109D3 mov edx,dword ptr [ebp-0Ch] 004109D6 push edx 004109D7 call @ILT+10(test) (0040100f) //跳转到test的函数执行,请先看test部分,test执行完 标记A 004109DC add esp,0Ch //释放调用时压栈参数再看这边。 004109DF mov dword ptr [ebp-14h],eax //将返回值保存到栈临时变量 15: printf('ret:%d', ret); //此段不解释 004109E2 mov eax,dword ptr [ebp-14h] 004109E5 push eax 004109E6 push offset string 'ret:%d' (00426fd8) 004109EB call printf (00410910) 004109F0 add esp,8 16: } 004109F3 pop edi //恢复各寄存器 004109F4 pop esi 004109F5 pop ebx 004109F6 add esp,54h //释放临时变量 004109F9 cmp ebp,esp //此时两者应该相等 004109FB call __chkesp (00401170) 00410A00 mov esp,ebp //恢复上层调用者栈顶 00410A02 pop ebp //恢复上层调用者栈底 00410A03 ret //调转到上层调用者执行 至此主函数执行结束。 main ret后的代码 00401299 add esp,0Ch 0040129C mov dword ptr [mainret],eax 0040129F mov edx,dword ptr [mainret] 004012A2 push edx 004012A3 call exit (00402360) ---------------------------------------------------------------------------------------------------------------------- Test函数源码 3: int test(int x, int y, double& z) 4: { 00401020 push ebp 00401021 mov ebp,esp 00401023 sub esp,44h 00401026 push ebx 00401027 push esi 00401028 push edi 00401029 lea edi,[ebp-44h] 0040102C mov ecx,11h 00401031 mov eax,0CCCCCCCCh 00401036 rep stos dword ptr [edi] 5: z = x + y; 00401038 mov eax,dword ptr [ebp+8] //ebp+X引用调用者传入参数变量 0040103B add eax,dword ptr [ebp+0Ch] 0040103E mov dword ptr [ebp-4],eax //ebp-X 引用本函数块分配的变量 00401041 fild dword ptr [ebp-4] //fild是将整数转化为长双精FP80压栈(压到st0 00401044 mov ecx,dword ptr [ebp+10h] 00401047 fstp qword ptr [ecx] //fstp是将弹栈指令,将st0弹出。 6: return 0; 00401049 xor eax,eax 7: } 0040104B pop edi //各寄存器值出栈恢复 0040104C pop esi 0040104D pop ebx 0040104E mov esp,ebp //释放本函数栈空间 00401050 pop ebp //恢复EBP指针,同时ESP指针下移一个 push 指令ESP自动上移,pop自动下移。至此,栈空间又恢复到main函数的栈空间。 00401051 ret //函数调用结束弹出栈顶元素(返回地址),跳转到此地址执行。请回到标记A处继续阅读。 |
|