help on GCC calling convention

Programming, for all ages and all languages.
Post Reply
yuq
Posts: 17
Joined: Tue Jan 11, 2011 2:06 am

help on GCC calling convention

Post by yuq »

Hello,

I'm studying the GCC calling convention. I compile a C function:

Code: Select all

int add2(int a, int b)  //add two numbers
{
  int tmp;
  tmp = a+b;
  return tmp;
}
using GCC 4.4.3 with no optimization: gcc -S add2.c. And I got:

Code: Select all

add2:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$16, %esp
	movl	12(%ebp), %eax
	movl	8(%ebp), %edx
	leal	(%edx,%eax), %eax
	movl	%eax, -4(%ebp)
	movl	-4(%ebp), %eax
	leave
	ret
So the stack seems like this:

Code: Select all

      |     arg b    |             |     stack grow direction
      +--------------+             |
      |     arg a    |            \ /
      +--------------+
      |  return eip  |
      +--------------+
      |     ebp      |
      +--------------+
      |      ??      |
      +--------------+
      |      tmp     |
      +--------------+
      |      ??      |
      +--------------+
      |      ??      |
      +--------------+
I don't understand why the GCC reserves 12 Byte in the stack. What the "??" place store?
mindentropy
Member
Member
Posts: 42
Joined: Thu Jan 13, 2011 3:33 pm

Re: help on GCC calling convention

Post by mindentropy »

Maybe stack alignment. Try it without the alignment option. The amount of alignment depends on the processors.
Last edited by mindentropy on Wed May 25, 2011 6:53 am, edited 1 time in total.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: help on GCC calling convention

Post by Owen »

My guess is that GCC has assigned a stack slot for every variable, then added one for alignment purposes (IIRC i386 SysV ABI defines 8 byte aligned stacks). With no optimizations enabled, GCC generates pretty dumb code.

Also: tmp is immediately below EBP; there is no gap between them
yuq
Posts: 17
Joined: Tue Jan 11, 2011 2:06 am

Re: help on GCC calling convention

Post by yuq »

Owen wrote: Also: tmp is immediately below EBP; there is no gap between them
Yes, you are right. The tmp is following ebp.

I have tried some different cases and find a rule: in function which will call other functions, the stack is 16 byte aligned. In function which won't call other functions (like the above add2()), the stack is increased by 16 byte when increase local variables. But plus the first pushed ebp, the stack seems not aligned. And I find a new question:

Code: Select all

int add3(int a, int b, int c)

int main()
{
  int c;
  c = add3(1, 2, 3);
  return c;
}
I got:

Code: Select all

main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$28, %esp
	movl	$3, 8(%esp)
	movl	$2, 4(%esp)
	movl	$1, (%esp)
	call	add3
	movl	%eax, -4(%ebp)
	movl	-4(%ebp), %eax
	leave
	ret
But function:

Code: Select all

int add3(int a, int b, int c);

int add(void)
{
  int c;
  c = add3(1, 2, 3);
  return c;
}
I got:

Code: Select all

add:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$40, %esp
	movl	$3, 8(%esp)
	movl	$2, 4(%esp)
	movl	$1, (%esp)
	call	add3
	movl	%eax, -12(%ebp)
	movl	-12(%ebp), %eax
	leave
	ret
It seems the main() function is special? The alignment is different between main() and add(). Why?
Post Reply