【.NET进阶】函数调用--函数栈
原文:http://www.cnblogs.com/rain-lei/p/3622057.html
int print_out(int begin, int end)
{
printf("%d ", begin++);
int *p;
p = (int*)(int(&begin) - 4);
if(begin <= end)
*p -= 5;
return 1;
}
int add(int a, int b)
{
return a+b;
}
int pass(int a, int b, int c) {
char buffer[4] = {0};
int sum = 0;
int *ret;
ret = (int*)(buffer+28);
//(*ret) += 0xA;
sum = a + b + c;
return sum;
}
int main()
{
print_out(0, 2);
printf("\n");
int a = 1;
int b = 2;
int c;
c = add(a, b);
pass(a, b, c);
int __sum;
__asm
{
mov __sum, eax
}
printf("%d\n", __sum);
system("pause");
}
28: int main()
29: {
011C1540 push ebp //压栈,保存ebp,注意push操作隐含esp-4
011C1541 mov ebp,esp //把esp的值传递给ebp,设置当前ebp
011C1543 sub esp,0F0h //给函数开辟空间,范围是(ebp, ebp-0xF0)
011C1549 push ebx
011C154A push esi
011C154B push edi
011C154C lea edi,[ebp-0F0h] //把edi赋值为ebp-0xF0
011C1552 mov ecx,3Ch //函数空间的dword数目,0xF0>>2 = 0x3C
011C1557 mov eax,0CCCCCCCCh
011C155C rep stos dword ptr es:[edi]
//rep指令的目的是重复其上面的指令.ECX的值是重复的次数.
//STOS指令的作用是将eax中的值拷贝到ES:EDI指向的地址,然后EDI+4
30: print_out(0, 2);
013D155E push 2 //第二个实参压栈
013D1560 push 0 //第一个实参压栈
013D1562 call print_out (13D10FAh)//返回地址压栈,本例中是013D1567,然后调用print_out函数
013D1567 add esp,8 //两个实参出栈
//注意在call命令中,隐含操作是把下一条指令的地址压栈,也就是所谓的返回地址
013D141C mov eax,1 //返回值传入eax中
013D1421 pop edi
013D1422 pop esi
013D1423 pop ebx //寄存器出栈
013D1424 add esp,0D0h //以下3条命令是调用VS的__RTC_CheckEsp,检查栈溢出
013D142A cmp ebp,esp
013D142C call @ILT+315(__RTC_CheckEsp) (13D1140h)
013D1431 mov esp,ebp //ebp的值传给esp,也就是恢复调用前esp的值
013D1433 pop ebp //弹出ebp,恢复ebp的值
013D1434 ret //把返回地址写入EIP中,相当于pop EIP
int *p;
p = (int*)(int(&begin) - 4);
if(begin <= end)
*p -= 5;
013D1560 push 0 //第一个实参压栈
013D1562 call print_out (13D10FAh)//返回地址压栈,本例中是013D1567,然后调用print_out函数
013D1567 add esp,8 //两个实参出栈
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。