Varun
Varun

Reputation: 189

Related to procedural calls and assembly language

I was going through some concepts of C when I came across this:

int add (int a, int b)
{
return a+b;
}

int main()
{
int a,b;
a = 3;
b = 4;
int ret = add(a,b);
printf("Result: %u\n", ret);
exit(0);
}

The assembler code generated for it as follows:

<main>:

1: push ebp

2: mov ebp, esp

3: sub esp, 0x18

4: mov eax, 0x0

.........(some more code but not relevant to the question)

The question I want to ask is why in the 3rd step value of stack pointer(esp) decreased by 24(0x18).

Upvotes: 2

Views: 149

Answers (2)

Turix
Turix

Reputation: 4490

It's making room for six 4-byte ints on the stack. The exact usage of these depends on the compiler and architecture, but these definitely include one each for a, b, and ret.

Incidentally, when I try this code on my MacBook Pro (x86, 64-bit, SnowLeopard) with gcc 4.2.1, it makes room for eight 4-byte ints. In addition to the above, these include one for storing the value of eax prior to the calls to add() and printf(), since the results of each are returned in it (apparently due to the "cdecl" calling convention). The layout on my machine looks like this:

-32:  unused
-28:  unused
-24:  unused
-20:  stores eax prior to each function call
-16:  ret
-12:  b
 -8:  a
 -4:  unused (potentially return value for main())
 ----------------
  0:  original base pointer

My guess is that the first unused slot at -4 is for a potential return value for main(). I somewhat confirmed this by replacing exit() with return -1;. In that case, it allocated two ints on the stack at -4 and -8 for a duplicate copy of the return value. (This seems to be my compiler's way, as add() also duplicated the return value.)

For the other 3 unused slots, my guess is my compiler is trying to align on 8-byte boundaries (at least). That doesn't explain why it added another 8 bytes (two unused ints) to the top of the stack though. (I'm not really sure what's going on there -- maybe it prefers to align on 16-byte boundaries?)

Your compiler is probably aligning things differently (and potentially using some other calling convention and/or optimizing as well).

Upvotes: 3

A. K.
A. K.

Reputation: 38234

The compiler stores the return address of the function, the temporaries used in the function and the parameters passed to the function before transferring the control to the function call. All these are stored in the stack frame and hence the stack-pointer is decremented. I'm not sure why it decrements sp by 0x18 (probably you are on a 64bit machine hence 3(two temporaries+one return address) * 8 byte(64bit) ::= 0x18)

Upvotes: 0

Related Questions