2

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].

Why it puts my variables there?

I know that local variables are always [ebp-....].

Why here it is not [ebp-..]?

2
  • there is no requirement for C to even have a "stack" so if it does, the detail is implementation specific. If there is a user stack which is also the same stack as the hardware stack, so long as the local variables are not in damage from function calls or interrupts, they are safe. Whether they are indexed by a negative offset from ebp or a positive offest from esp is just the implementation's convention. Commented Oct 5, 2016 at 20:34
  • In extreme case the variable can be removed completely (if it's usage doesn't have any effect on other things, like for (size_t i = 0; i < 1e6; ++i) {} will be removed completely by optimizer, thus i doesn't exist anywhere except source. Still the binary is valid (by C++ language definition). Commented Oct 6, 2016 at 9:27

2 Answers 2

9

I know that local variables are always [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. 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.

Sign up to request clarification or add additional context in comments.

2 Comments

@user6575913 sure, if that's what you want to call it
ok.thx for clarification. i just started study this (a security course) and i am willing to learn more.
1

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.

2 Comments

but in theory it is like i said,no?
@user6575913 - I'm not certain but I believe there's no definition of how code should be compiled, only how it should "behave". Obviously different platforms have different compilations.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.