函数在内存中的具体执行

    如果程序要调用某个函数,那么计算机就会自动将函数返回后要执行的指令地址先压入栈里,
等待函数返回以后再从中取出,跳到该处继续执行。

#include <stdio.h>
void TestFunction()
{
 int i = 10;
 return;
}
void main()
{
 TestFunction();
 return;
}

 

 

 EAX = CCCCCCCC EBX = 7FFD5000 ECX = 00000000 EDX = 00591030 ESI = 00000000 EDI = 0012FF48 EIP = 0040D468 ESP = 0012FEFC EBP = 0012FF48 EFL = 00000202


 

0012FEE4  00 00 00 00 02 00 00 00 30 2F  ........0/
0012FEEE  42 00 83 00 00 00 E0 06 59 00  B.......Y.
0012FEF8  1C FF 12 00 00 00 00 00 00 00  ..........
0012FF02  00 00 00 50 FD 7F CC CC CC CC  ...P?烫烫
0012FF0C  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF16  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF20  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF2A  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF34  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF3E  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF48  88 FF 12 00 89 11 40 00 01 00  ......@...
0012FF52  00 00 B8 0F 59 00 30 10 59 00  ....Y.0.Y.

 

9:        TestFunction();
0040D468   call        @ILT+5(TestFunction) (0040100a)
10:       return;
11:   }
0040D46D   pop         edi
0040D46E   pop         esi
0040D46F   pop         ebx

 

我们可以看到TestFunction下一条指令是0040D46D,也就是函数返回的地址,我们按F11键单步执行就会发现,0040D46D被压入

了栈中。

 

 EAX = CCCCCCCC EBX = 7FFD5000 ECX = 00000000 EDX = 00591030 ESI = 00000000 EDI = 0012FF48 EIP = 0040100A ESP = 0012FEF8 EBP = 0012FF48 EFL = 00000202

0012FEE4  00 00 00 00 02 00 00 00 30 2F  ........0/
0012FEEE  42 00 83 00 00 00 E0 06 59 00  B.......Y.
0012FEF8  6D D4 40 00 00 00 00 00 00 00  m訞.......
0012FF02  00 00 00 50 FD 7F CC CC CC CC  ...P?烫烫
0012FF0C  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF16  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF20  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF2A  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF34  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF3E  CC CC CC CC CC CC CC CC CC CC  烫烫烫烫烫
0012FF48  88 FF 12 00 89 11 40 00 01 00  ......@...
0012FF52  00 00 B8 0F 59 00 30 10 59 00  ....Y.0.Y.

 

然后单步执行到TestFunction函数里,

 

4:        int i = 10;
00401028   mov         dword ptr [ebp-4],0Ah
5:        return;
6:    }
0040102F   pop         edi
00401030   pop         esi
00401031   pop         ebx
00401032   mov         esp,ebp
00401034   pop         ebp
00401035   ret

 

当执行到ret之后,TestFunction函数就会返回,跳转到0040D46D这个地址。

 

0040D46D   pop         edi
0040D46E   pop         esi
0040D46F   pop         ebx
0040D470   add         esp,40h
0040D473   cmp         ebp,esp
0040D475   call        __chkesp (00401060)
0040D47A   mov         esp,ebp
0040D47C   pop         ebp
0040D47D   ret

 

    正是因为先放入栈里的地址在前,而后进入栈的数据一旦很长,就会覆盖到前面的地址,

这就会导致程序发生错误。这也就是溢出的原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值