C 和汇编语言中局部变量和静态变量的加法是如何工作的
How addition works for local and static variables in C and assembly
这段代码是用 gcc 5.3.1 编译的。
汇编指令是通过 gdb 7.11 使用 disassemble main
生成的
操作系统 GNU/Linux 运行 在 x86_64 处理器上。
int main() {
int i = 0;
return ++i;
}
push %rbp
mov %rsp,%rbp
movl [=10=]x0,-0x4(%rbp)
addl [=10=]x1,-0x4(%rbp)
mov -0x4(%rbp),%eax
pop %rbp
retq
int main() {
static int i;
return ++i;
}
push %rbp
mov %rsp,%rbp
mov 0x200b54(%rip),%eax
add [=11=]x1,%eax
mov %eax,0x200b4b(%rip)
mov 0x200b45(%rip),%eax
pop %rbp
retq
在第一个例子中,内存地址被直接操作,而在后一个例子中,值必须首先传输到eax
寄存器。谁能解释一下这是怎么回事?
这是怎么回事,你没有告诉 gcc 优化程序集。因此,它发出的程序集并不能真正代表 CPU 可以做什么。在优化汇编中,这两个序列可能如下所示:
# adding 1 an automatic variable in register eax
add ,%eax
# alternatively
inc %eax
# adding 1 to an automatic variable on the stack
add ,12(%rbp)
# alternatively
inc 12(%rbp)
# adding 1 to a static variable
add ,i(%rip)
# alternatively
inc i(%rip)
rip
是指令指针。在 amd64 上,对静态变量的访问通常是相对于指令指针完成的,以启用 PIC 代码。
这段代码是用 gcc 5.3.1 编译的。
汇编指令是通过 gdb 7.11 使用 disassemble main
操作系统 GNU/Linux 运行 在 x86_64 处理器上。
int main() {
int i = 0;
return ++i;
}
push %rbp
mov %rsp,%rbp
movl [=10=]x0,-0x4(%rbp)
addl [=10=]x1,-0x4(%rbp)
mov -0x4(%rbp),%eax
pop %rbp
retq
int main() {
static int i;
return ++i;
}
push %rbp
mov %rsp,%rbp
mov 0x200b54(%rip),%eax
add [=11=]x1,%eax
mov %eax,0x200b4b(%rip)
mov 0x200b45(%rip),%eax
pop %rbp
retq
在第一个例子中,内存地址被直接操作,而在后一个例子中,值必须首先传输到eax
寄存器。谁能解释一下这是怎么回事?
这是怎么回事,你没有告诉 gcc 优化程序集。因此,它发出的程序集并不能真正代表 CPU 可以做什么。在优化汇编中,这两个序列可能如下所示:
# adding 1 an automatic variable in register eax
add ,%eax
# alternatively
inc %eax
# adding 1 to an automatic variable on the stack
add ,12(%rbp)
# alternatively
inc 12(%rbp)
# adding 1 to a static variable
add ,i(%rip)
# alternatively
inc i(%rip)
rip
是指令指针。在 amd64 上,对静态变量的访问通常是相对于指令指针完成的,以启用 PIC 代码。