According to some textbooks, the compiler will use sub* to allocate memory for local variables.
For example, I write a Hello World program:
int main()
{
puts("hello world");
return 0;
}
I guess this will be compiled to some assembly code on the 64 bit OS:
subq $8, %rsp
movq $.LC0, (%rsp)
calq puts
addq $8, %rsp
The subq allocates 8 byte memory (size of a point) for the argument and the addq deallocates it.
But when I input gcc -S hello.c (I use the llvm-gcc on Mac OS X 10.8), I get some assembly code.
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
subq $16, %rsp
Ltmp2:
xorb %al, %al
leaq L_.str(%rip), %rcx
movq %rcx, %rdi
callq _puts
movl $0, -8(%rbp)
movl -8(%rbp), %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
addq $16, %rsp
popq %rbp
ret
.......
L_.str:
.asciz "hello world!"
Around this callq without any addq and subq. Why? And what is the function of addq $16, %rsp?
Thanks for any input.
You don’t have any local variables in your
main(). All you may have in it is a pseudo-variable for the parameter passed toputs(), the address of the"hello world"string.According to your last disassembly, the calling conventions appear to be such that the first parameter to
puts()is passed in therdiregister and not on the stack, which is why there isn’t any stack space allocated for this parameter.However, since you’re compiling your program with optimization disabled, you may encounter some unnecessary stack space allocations and reads and writes to and from that space.
This code illustrates it:
Those four
movinstructions are equivalent to just one simplemovl $0, %eax, no memory is needed to do that.If you add an optimization switch like
-O2in your compile command, you’ll see more meaningful code in the disassembly.Also note that some space allocations may be needed solely for the purpose of keeping the stack pointer aligned, which improves performance or avoids issues with misaligned memory accesses (you could get the #AC exception on misaligned accesses if it’s enabled).
The above code shows it too. See, those four
movinstructions only use 8 bytes of memory, while theaddandsubinstructions grow and shrink the stack by 16.