我正在学习有关汇编的这个教程。
根据该教程(我也尝试了本地操作,并且得到了类似的结果),以下源代码:
int natural_generator()
{
int a = 1;
static int b = -1;
b += 1; /* (1, 2) */
return a + b;
}
编译成以下汇编指令:
$ gdb static
(gdb) break natural_generator
(gdb) run
(gdb) disassemble
Dump of assembler code for function natural_generator:
push %rbp
mov %rsp,%rbp
movl $0x1,-0x4(%rbp)
mov 0x177(%rip),%eax # (1)
add $0x1,%eax
mov %eax,0x16c(%rip) # (2)
mov -0x4(%rbp),%eax
add 0x163(%rip),%eax # 0x100001018 <natural_generator.b>
pop %rbp
retq
End of assembler dump.
(我添加了行号注释(1)
、(2)
和(1,2)
。)
问题:为什么在编译后的代码中,静态变量b
的地址相对于指令指针(RIP)(参见行(1)
和(2)
),而指令指针不断变化,从而生成更复杂的汇编代码,而不是相对于可执行文件中存储这些变量的特定部分?
根据提到的教程,确实有这样一个部分:
这是因为
b
的值是硬编码在示例可执行文件的不同部分中的,并且在进程启动时由操作系统的加载程序与所有机器代码一起加载到内存中。
(强调是我的。)
objdump -drwC -Mintel
获取漂亮的输出。-r
解码符号表。objdump总是为您计算数学,并显示RIP相对指令的实际目标地址以及与RIP的偏移量。 - Peter Cordesb
在函数中没有被初始化。 - Ross Ridge