I've written this simple C code
int main()
{
int calc = 2+2;
return 0;
}
And I want to see how that looks in assembly, so I compiled it using gcc
$ gcc -S -o asm.s test.c
And the result was ~65 lines (Mac OS X 10.8.3) and I only found these to be related:
Where do I look for my 2+2
in this code?
One part of the question hasn't been addressed.
If %rbp, %rsp, %eax
are variables, what values do they attain in this case?
Almost all of the code you got is just useless stack manipulation. With optimization on (gcc -S -O2 test.c
) you will get something like
main:
.LFB0:
.cfi_startproc
xorl %eax, %eax
ret
.cfi_endproc
.LFE0:
Ignore every line that starts with a dot or ends with a colon: there are only two assembly instructions:
xorl %eax, %eax
ret
and they encode return 0;
. (XORing a register with itself sets it to all-bits-zero. Function return values go in register %eax
per the x86 ABI.) Everything to do with your int calc = 2+2;
has been discarded as unused.
If you changed your code to
int main(void) { return 2+2; }
you would instead get
movl $4, %eax
ret
where the 4 comes from the compiler doing the addition itself rather than making the generated program do it (this is called constant folding).
Perhaps more interesting is if you change the code to
int main(int argc, char **argv) { return argc + 2; }
then you get
leal 2(%rdi), %eax
ret
which is doing some real work at runtime! In the 64-bit ELF ABI, %rdi
holds the first argument to the function, argc
in this case. leal 2(%rdi), %eax
is x86 assembly language for "%eax = %edi + 2
" and it's being done this way mainly because the more familiar add
instruction takes only two arguments, so you can't use it to add 2 to %rdi
and put the result in %eax
all in one instruction. (Ignore the difference between %rdi
and %edi
for now.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With