「计算机基础」栈结构

Stack Layout

说到栈,就必须要提及function函数,所以我们可以从一个函数中来看。

栈结构

void func(int a,int b)
{
	int x,y;
	x = a+b;
	y = a-b;
}

在这里插入图片描述
当调用func时,会把这些数据压入到stack中,如图所示,High Address代表栈底,a和b是形式参数,先被压入栈中(注意C语言形参压栈的顺序是按照形参从右向左的顺序压栈的,原因可以自行百度或者参考这里

接下来压入 Return AddressPrevious Frame Pointer,接下来压入函数的局部变量x和y(x和y的入栈顺序一般与声明的顺序相同,一般和编译器有关)

其中Return Address用来存储调用后的下一条指令的地址,以便执行结束后返回。

另外,从栈底到Previous Frame Pointer这部分在函数调用后是固定的,fixed,不可修改的,而且挨在一起。但是这里和下面的局部变量之间可能会存在一个操作系统给的gap,也就是地址可能不是相连的。

接下来在介绍更深入的内容之前(觍着脸这么说,因为我也只了解了皮毛,甚至还不懂更不用说讲清楚),首先来看一下这个程序所要做的事情,然后从汇编角度来看一看。

x=a+b;,在程序中,想要把a、b相加得到x,在OS中需要转换为汇编语言代码(最终为机器语言)来执行,就必须要知道a和b的地址,那么问题就来了,我们怎么知道这里的a和b的地址呢?

这里可以知道一种思路就是使用偏移量offset,但是想使用offset偏移量就必须有一个基址base。但是run这个程序的时候,我们并不知道stack是从哪里开始的,因此不可以把stack开始的SP(Stack Point)作为base。这里引入了一个base point,在运行的时候规定了一个寄存器ebp,在运行过程中这个值是可以确定的,这里指向Previous Frame Pointer。(后面会解释为什么)

那么根据我们前面的图示,这是一个32bit机,那么可以得到形参的地址:

  • a : ebp+8
  • b : ebp+12

同理我们可以知道x的地址,如果是紧挨着ebp的话,x : ebp-4。

对应的汇编代码:

movl 12(%ebp),%eax // 把ebp-12复制到eax也就是b中
movl 8(%ebp),%eax 
addl %edx,%eax  // 相加,值会存在eax中
movl %eax,-8(%ebp) // eax移到ebp-8中

由上述代码可以知道,实际上ebp和x之间可能存在一个gap,并且compiler知道这个gap是多少,因此也可以知道x、y的值。

Local Variables是用户自己的,什么顺序入栈都是可以的;但是Argument不可以,它是为了其他人调用,所以必须遵从编译器的标准,否则会出错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值