【问题标题】:How addition works for local and static variables in C and assemblyC 和程序集中的局部变量和静态变量的加法是如何工作的
【发布时间】:2016-10-12 23:42:20
【问题描述】:

此代码是使用 gcc 5.3.1 编译的。

汇编指令是通过 gdb 7.11 使用 disassemble main 生成的

操作系统是运行在 x86_64 处理器上的 GNU/Linux。


int main() {
    int i = 0;
    return ++i;
}

push   %rbp
mov    %rsp,%rbp
movl   $0x0,-0x4(%rbp)
addl   $0x1,-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    $0x1,%eax
mov    %eax,0x200b4b(%rip)
mov    0x200b45(%rip),%eax
pop    %rbp
retq

在第一个示例中,内存地址被直接操作,而在后一个示例中,值必须首先传输到eaxregister。有人可以解释发生了什么吗?

【问题讨论】:

  • 好吧,静态变量的处理方式与局部变量不同。它们必须存储在进程内存的特定部分中。编译器无法优化它们,或者至少不会尝试因此产生额外的负载。
  • 啊,好吧。出于某种原因,我认为所有涉及 ALU 的操作都必须通过寄存器来完成。 @Bakuriu
  • 静态存储类指示编译器在程序的生命周期内保持局部变量存在,而不是在每次进入和离开范围时创建和销毁它。
  • 你的第一个版本在优化后可能什么都不做,只返回 1。

标签: c variables memory assembly add


【解决方案1】:

发生了什么是你没有告诉 gcc 优化程序集。因此,它发出什么程序集并不能真正代表 CPU 可以做什么。在优化组装中,这两个序列可能如下所示:

# adding 1 an automatic variable in register eax
add $1,%eax

# alternatively
inc %eax

# adding 1 to an automatic variable on the stack
add $1,12(%rbp)

# alternatively
inc 12(%rbp)

# adding 1 to a static variable
add $1,i(%rip)

# alternatively
inc i(%rip)

rip 是指令指针。在 amd64 上,对静态变量的访问通常是相对于启用 PIC 代码的指令指针来完成的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    相关资源
    最近更新 更多