c++函数调用
寄存器:
stack pointer(ESP): 保存栈的栈顶指针
base pointer (EBP): 保存栈的栈底指针
instruction ponter(EIP): register containing the address of the instruction to be executed
add esp, Och //指令引起栈缩小了12字节
sub esp, Och //指令引起栈增加了12字节
一下按照下面代码进行说明:
```cpp
int test( int x,int y)
{
int z;
z = x + y;
return z;
}
int main()
{
int i;
i = test(2,3);
return 0;
}
得到的汇编:
int test( int x,int y)
{
010C3840 55 push ebp
010C3841 8B EC mov ebp,esp
010C3843 81 EC CC 00 00 00 sub esp,0CCh
010C3849 53 push ebx
010C384A 56 push esi
010C384B 57 push edi
010C384C 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
010C3852 B9 33 00 00 00 mov ecx,33h
010C3857 B8 CC CC CC CC mov eax,0CCCCCCCCh
010C385C F3 AB rep stos dword ptr es:[edi]
int z;
z = x + y;
010C385E 8B 45 08 mov eax,dword ptr [x]
010C3861 03 45 0C add eax,dword ptr [y]
int z;
z = x + y;
010C3864 89 45 F8 mov dword ptr [z],eax
return z;
010C3867 8B 45 F8 mov eax,dword ptr [z]
}
010C386A 5F pop edi
010C386B 5E pop esi
010C386C 5B pop ebx
010C386D 8B E5 mov esp,ebp
010C386F 5D pop ebp
010C3870 C3 ret
int main() {
010C38B0 55 push ebp
010C38B1 8B EC mov ebp,esp
010C38B3 81 EC CC 00 00 00 sub esp,0CCh
010C38B9 53 push ebx
010C38BA 56 push esi
010C38BB 57 push edi
010C38BC 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
010C38C2 B9 33 00 00 00 mov ecx,33h
010C38C7 B8 CC CC CC CC mov eax,0CCCCCCCCh
010C38CC F3 AB rep stos dword ptr es:[edi]
int i;
i = test(2,3);
010C38CE 6A 03 push 3
010C38D0 6A 02 push 2
010C38D2 E8 D2 DD FF FF call test (010C16A9h)
010C38D7 83 C4 08 add esp,8
010C38DA 89 45 F8 mov dword ptr [i],eax
return 0;
010C38DD 33 C0 xor eax,eax
}
010C38DF 5F pop edi
}
010C38E0 5E pop esi
010C38E1 5B pop ebx
010C38E2 81 C4 CC 00 00 00 add esp,0CCh
010C38E8 3B EC cmp ebp,esp
010C38EA E8 7C DA FF FF call __RTC_CheckEsp (010C136Bh)
010C38EF 8B E5 mov esp,ebp
010C38F1 5D pop ebp
010C38F2 C3 ret
010C3840 55 push ebp
上面指令中"010C3840"就是寄存器EIP的值,
当指针调试到i = test(2,3)这行的时候,此时寄存器和栈分别如下:
然后继续进行到指令:
010C38D0 6A 02 push 2
后,此时此时寄存器和栈:
后面到了关键指令:
010C38D2 E8 D2 DD FF FF call test (010C16A9h)
指令 call 表示调用函数,test后括号内的值(010C16A9h)为目标地址,还有一个关键就是此时系统会自动将函数返回值(),压入esp+4中,执行该指令后,查看变化:
首先跳到了指令:
010C16A9 E9 92 21 00 00 jmp test (010C3840h)
同时栈和寄存器变化:
** 注意此时的返回地址是call 指令的下一条指令的地址 **
jmp指令就进入了test函数:
函数test 紧接着通过下面两条指令:
010C3840 55 push ebp
010C3841 8B EC mov ebp,esp
为保存原有EBP,和设置新的EBP
posted on 2021-06-23 17:33 Ultraman_X 阅读(175) 评论(0) 收藏 举报