首先我自己编译个代码,无非就是调用函数吗。
在这里我先大致手绘了一张整个程序在存储空间的汇编代码(根据P239上的汇编代码)
然后对其进行汇编。进入gdb,获得main的汇编代码。
给 sum 设置断点 获取sum的汇编代码
首先我分析一下该汇编代码:
按照书上P238所讲的,首先会初始化&esp和%ebp,这里并没有看到,我猜测是因为我们所设置的断电是给main函数的,所以只显示执行main时的汇编代码。
初始化栈指针和帧指针之后,就执行call main,然后%ebp入栈,%ebp保存%esp。
因为代码向电脑空间申请了三个int型变量。
之后:给申请的变量赋值,因为申请了3个int所以这时偏移量为12,对应:
之后进入sum函数:
%ebp入栈,保存main的帧指针,%esp又给%ebp赋给当前sum函数的帧。
将运算后的结果保存在%eax,返回给主函数,pop %ebp返回上一帧:
主函数将返回值 %eax 赋给 偏移量为4的空间,对应开始分配空间 int z。
下面开始一步一步分析代码:
主函数main的基地址%ebp的值为:
这个时候,给y赋值2,对应开辟存储空间偏移量加8.
当执行完:对应 z=(x,y);由三条汇编指令构成,牵扯到了入栈,两次入栈,总共8字节。所以%esp发生了变化:入栈栈指针向上增加8。
然后进入sum函数
看着时候%ebp的值发生了变化,为sum函数的基地址
当执行完运算,%eax保存了所要返回的值3:对应1+2
将先前的函数的帧弹栈给%ebp,之后ret指令,结束sum函数的调用:
int z 所在的存储空间为 main函数基地址加偏移量4 ,所以返回值赋给了该存储地址。
leave指令结束后 用0覆盖%eax。
到这里代码分析完毕。下面是对应的表格
栈底:0x0bfffefec 栈顶:0x08048413
感想:
在学习第四章P239页讲的很详细,这次GDB分析是用gdb调试来巩固下之前所学的知识通过这次实践,对栈帧的掌握就已经相当牢固了,感谢娄老师。
问题 :
当main函数将基地址赋给%ebp后,%esp就马上减少0x10,这是为什么,我想了一下不可能是因为去开辟变量的存储空间,我能想到的只有是去保存当前栈帧的参数,因为之后将两个参数压栈了,希望老师给我指点一下,谢谢老师。