You didn't show the compilation command, that could be useful, but it seems that you have optimizations enabled, so there are actually no space for local variables, they are optimized out:
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
All this code above set the stack frame. Since it is the main
it is a bit different from a standard stack frame: it ensures the alignment of the stack with andl $-16, %esp
, just in case.
pushl %ecx
It saves the original value of esp
before the alignment correction, to restore it at the end.
subl $36, %esp
It allocates 36 bytes of stack space, not for local variables but for calling parameters.
movl $11, 8(%esp)
movl $6, 4(%esp)
movl $2, (%esp)
It sets the arguments for calling calc
from right to left, that is, the constants, (2, 6, 11)
.
call calc // function call to calc
It calls function calc
with the arguments pointed to by esp
.
movl %eax, 20(%esp)
movl $11, 16(%esp)
movl $6, 12(%esp)
movl $2, 8(%esp)
movl $.LC0, 4(%esp)
movl $1, (%esp)
These are the arguments for calling __printf_chk
, from right to left: (1, .LC0, 2, 6, 11, %eax)
, where %eax
is the return value of calc()
(remember, no local variables!) and .LC0
is the address of the literal string, look at these lines at the top of the assembly:
.LC0:
.string "x=%d, y=%d, z=%d, result=%d\n"
But what about that mysterious 1
?. Well, in Ubuntu the standard compilation options (-D_FORTIFY_SOURCE
) will make printf
an inline function that forwards to __printf_chk(1, ...)
or something like that, that does extra checks to the arguments.
call __printf_chk
This is the call to the printf
substitute function.
addl $36, %esp
This removes the 36 bytes added to the stack with subl $36, %esp
.
popl %ecx
This restores the possibly unaligned stack pointer into ecx
.
popl %ebp
leal -4(%ecx), %esp
This restores the previous stack frame.
ret
And this returns without a value, because you didn't write a return for main
.