我写了这个简单的C代码
int main()
{
int calc = 2+2;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望看到它在汇编中看起来如何,所以我使用它编译它 gcc
$ gcc -S -o asm.s test.c
Run Code Online (Sandbox Code Playgroud)
结果是大约65行(Mac OS X 10.8.3),我发现这些是相关的:

我2+2在这个代码中在哪里寻找我的?
One part of the question hasn't been addressed.
If %rbp, %rsp, %eax are variables, what values do they attain in this case?
zwo*_*wol 11
你得到的几乎所有代码都是无用的堆栈操作.通过优化on(gcc -S -O2 test.c),你会得到类似的东西
main:
.LFB0:
.cfi_startproc
xorl %eax, %eax
ret
.cfi_endproc
.LFE0:
Run Code Online (Sandbox Code Playgroud)
忽略以点开头或以冒号结尾的每一行:只有两个汇编指令:
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
他们编码return 0;.(对一个寄存器进行异或操作会将其设置为全位 - 零.函数返回值%eax按照x86 ABI 进行寄存器.)与您的所有操作int calc = 2+2;都被丢弃为未使用.
如果您将代码更改为
int main(void) { return 2+2; }
Run Code Online (Sandbox Code Playgroud)
你宁愿得到
movl $4, %eax
ret
Run Code Online (Sandbox Code Playgroud)
4来自编译器进行加法本身而不是让生成的程序执行它(这称为常量折叠).
也许更有趣的是,如果您将代码更改为
int main(int argc, char **argv) { return argc + 2; }
Run Code Online (Sandbox Code Playgroud)
然后你得到
leal 2(%rdi), %eax
ret
Run Code Online (Sandbox Code Playgroud)
这是在运行时做一些真正的工作!在这种情况下%rdi,argc在64位ELF ABI中,保存函数的第一个参数. leal 2(%rdi), %eax是用于" %eax = %edi + 2"的x86汇编语言,并且这样做主要是因为更熟悉的add指令只接受两个参数,所以你不能用它来添加2 %rdi并将结果%eax放在一个指令中.(忽略现在%rdi和之间的区别%edi.)
She*_*tJS 10
编译器确定2+2 = 4并内联它.常量存储在第10行(the $4)中.要验证这一点,请将数学更改为2+3,您将看到$5
编辑:至于寄存器本身,%rsp是堆栈指针,%rbp是帧指针,%eax是一个通用寄存器