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 代码。