简体   繁体   English

汇编局部变量和参数

[英]Assembly local variable and parameters

I have the following code 我有以下代码

#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));
}

My question is in assembly it puts the variable w,y at the [esp+24] ,[esp+28]. 我的问题是在汇编中它将变量w,y放在[esp + 24],[esp + 28]。

Why it puts my variables there? 为什么它把我的变量放在那里?

I know that local variables are always [ebp-....]. 我知道局部变量总是[ebp -....]。

Why here it is not [ebp-..]? 为什么这里不是[ebp- ..]?

I know that local variables are always [ebp-....] 我知道局部变量总是[ebp -....]

They're not (as evidenced by your question too, I suppose). 它们不是(我猜你的问题也证明了这一点)。

It's legal for a compiler to compile really naively, always using a frame pointers (even in functions that don't do variable-size stack allocations) and always putting locals on the stack in the first place (which is definitely not a rule). 编译器非常天真地编译是合法的,总是使用帧指针(即使在不执行可变大小的堆栈分配的函数中),并且总是首先将局部放在堆栈中(这绝对不是一个规则)。 In a first year course in university, it is sometimes pretended that that's normal, to keep things simple. 在大学的第一年课程中,有时假装这是正常的,以保持简单。

Not using a frame pointer is usually possible, it works mostly the same as if you had used one except that offsets are calculated relative to the stack pointer, which you are now only allowed to move in predictable ways. 通常不使用帧指针,它的工作方式与使用其中的指针大致相同,只是相对于堆栈指针计算偏移量,现在只允许以可预测的方式移动。 Because it has to be predictable (that is, every instructions that references a stack slot can use a constant offset to do so), this optimization cannot be used in functions that use alloca or VLAs. 因为它必须是可预测的(即,每个引用堆栈槽的指令都可以使用常量偏移量来执行此操作),所以此优化不能用于使用alloca或VLA的函数。 In your example function neither are used, so no frame pointer is necessary. 在您的示例函数中都没有使用,因此不需要帧指针。

Also in general you should not expect local variables to correspond to specific stack slots in the first place, regardless of how they are addressed. 此外,在一般你应该期望局部变量对应于特定的栈槽摆在首位,而不管它们是如何解决的。 It is allowed, common, and often a good thing, to keep a variable in a register over the entire lifetime of the variable. 在变量的整个生命周期内将变量保存在寄存器中是允许的,常见的,并且通常是好事。 Especially if that life time is short or if the usage-density is very high. 特别是如果寿命很短或者使用密度非常高。 On top of that, variables with non-overlapping life times can (and should, because it reduces the stack size) share stack slots, since it would be the case that at most one of them needs storage at any one moment (thanks to the assumption of non-overlapping life times). 最重要的是,具有不重叠生命周期的变量可以(并且应该,因为它减少了堆栈大小)共享堆栈插槽,因为在任何一个时刻最多其中一个需要存储的情况(由于假设不重叠的生命时间)。

It's also allowed to have a variable hop from one stack slot to an other, this might happen when you swap two variables in a way that allows the swap to be resolved "virtually", by just changing which stack slot the variables live in and not actually exchanging the data. 它也允许从一个堆栈槽到另一个堆栈槽的变量跳转,这可能发生在以允许交换“虚拟”解析的方式交换两个变量时,只需更改变量所在的堆栈槽而不是实际上交换数据。

That's probably a compiler optimization. 这可能是编译器优化。 The variables aren't used within main scope so are placed directly on the stack, ready for the function call. 变量不在main范围内使用,因此直接放在堆栈上,为函数调用做好准备。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM