I'm trying to learn x86 on my own and I decided to dissect a simple c program and see what GCC outputs. The program is this:
#include <stdio.h>
int main() {
printf("%s","Hello World");
return 0;
}
I compiled the code with -S and then stripped out things that I found unnecessary and reduced the assembly code to this.
.pfArg:
.string "%s"
.text
.Hello:
.string "Hello World"
.text
.globl main
.type main, @function
main:
pushq %rbp # push what was in base pointer onto stack
movq %rsp, %rbp # move stack pointer to base pointer
subq $16, %rsp # subtract 16 from sp and store in stack pointer
# prepare arguments for printf
movl $.Hello, %esi # put & of "Hello World" into %esi
movq $.pfArg, %rdi # put & of "%d" into %eax
call printf
leave
ret
Now almost everything in the code above makes sense to me except the first two under main. Although this is what I get without stripping things out.
.LC0:
.string "%s"
.LC1:
.string "Hello World"
.text
.globl main
.type main, @function
main:
.LFB0:
pushq %rbp # push what was in base pointer onto stack
movq %rsp, %rbp # move stack pointer to base pointer
# prepare arguments for printf
movl $.LC0, %eax # put arg into %eax
movl $.LC1, %esi # put second arg into %esi
movq %rax, %rdi # move value in %rax to %rdi ???? ( why not just put $.LCO into %rax directly )
movl $0, %eax # clear out %eax ???? ( why do we need to clear it out )
call printf
movl $0, %eax # return 0
leave
ret
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
.section .note.GNU-stack,"",@progbits
There are 2 instructions that I've marked with ???? that I don't understand.
The first instruction is moving what is in %rax into %rdi to prepare for the printf call. Thats all fine except we just moved $.LC0 (which is the string "%s") into %eax. This seems unnecessary why didn't we just move $.LC0 into %rdi in the first place instead of moving it into %eax and then into %rdi?
The second instruction is clearing out %eax which I understand to be the return value of a function. But if the function is going to just clobber it anyways why do GCC care to clear it out?