c++函数调用

Origin

寄存器:

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  阅读(152)  评论(0编辑  收藏  举报

导航