汇编局部变量和参数

时间:2016-10-05 20:06:23

标签: c assembly

我有以下代码

#include<stdio.h>

int adunare(int a,int b)
{
  int c=3;
  int d=6;

  while(c>10) c++;
  if(c>15) return a+b+c+d;
  else return a+b+c-d;
}

int main()
{
  int w=5;
  int y=6;
  printf("%d",adunare(w,y));
}

我的问题是在汇编中它将变量w,y放在[esp + 24],[esp + 28]。

为什么把变量放在那里?

我知道局部变量总是[ebp -....]。

为什么这里不是[ebp- ..]?

2 个答案:

答案 0 :(得分:9)

  

我知道局部变量总是[ebp -....]

他们不是(我的问题也证明了这一点。)

编译器非常天真地编译是合法的,总是使用帧指针(即使在不执行可变大小堆栈分配的函数中)并且始终将局部放在堆栈中(这绝对不是一个)规则)。在大学的第一年课程中,为了简单起见,有时会假装这是正常的。

通常不使用帧指针,它的工作方式与使用其中的指针大致相同,只是相对于堆栈指针计算偏移量,现在只允许以可预测的方式移动。因为它必须是可预测的(即,引用堆栈槽的每个指令都可以使用常量偏移量来执行此操作),所以此优化不能用于使用alloca或VLA的函数。在您的示例函数中都没有使用,因此不需要帧指针。

另外一般情况下,你应该期望局部变量首先对应于特定的堆栈槽,而不管它们是如何被寻址的。在变量的整个生命周期内将变量保存在寄存器中是允许的,常见的,并且通常是好事。特别是如果寿命很短或者使用密度非常高。最重要的是,具有不重叠生命周期的变量可以(并且应该,因为它减少了堆栈大小)共享堆栈插槽,因为在任何一个时刻最多其中一个需要存储的情况(由于假设不重叠的生命时间)。

它还允许从一个堆栈槽到另一个堆栈槽的变量跳转,这可能发生在以允许交换“虚拟”解析的方式交换两个变量时,只需更改变量所在的堆栈槽实际上并没有交换数据。

答案 1 :(得分:1)

这可能是编译器优化。变量不在main范围内使用,因此直接放在堆栈上,为函数调用做好准备。