程序集和c ++代码之间的一对一关系在哪里?

时间:2012-02-24 08:44:29

标签: c++ assembly

我试着检查这段代码在汇编中的作用:

int main(){
  if (0){
    int x = 2;
    x++;
  }
  return 0;
}

我想知道if (0)是什么意思?

我在g++ -S helloWorld.cpp

中使用了shell命令Linux

并获得此代码:

    .file   "helloWorld.cpp"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
    .section    .note.GNU-stack,"",@progbits
  1. 我预计程序集将包含一些JZ,但它在哪里?
  2. 如何在不进行优化的情况下编译代码?

6 个答案:

答案 0 :(得分:6)

C ++源代码与C ++之间没有直接保证的关系 生成的汇编程序。 C ++源代码定义了一定的 语义,编译器输出将实现的机器代码 这些语义的可观察行为。编译器如何做到这一点, 它输出的实际代码可能差别很大,甚至相同 底层硬件;我会对编译器非常失望 生成的代码将00进行了比较,然后进行了条件化 如果结果相同则跳转,无论C ++源代码是什么 是

在您的示例中,代码中唯一可观察的行为是返回 0到操作系统。编译器生成的任何东西都必须这样做(并且有 没有其他可观察的行为)。您显示的代码不是最佳的 这样:

xorl %eax, %eax
ret

真的是所有需要的。但是,当然,编译器是免费的 如果它想要的话会产生更多。 (例如,您的代码设置了一个 框架支持局部变量,即使没有。许多 编译器系统地这样做,因为大多数调试器都期望它,并且 如果没有框架就会感到困惑。)

关于优化,这取决于编译器。用g ++, -O0(这是字母O后跟数字零)关闭所有 优化。这是默认值,因此它实际上是什么 你看到了。除了有几个不同的水平 优化,g ++支持关闭或打开个别优化。 您可能想查看完整列表: http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Optimize-Options.html#Optimize-Options

答案 1 :(得分:5)

编译器将该代码作为死代码删除,例如永远不会运行的代码。你剩下的就是建立堆栈框架并设置函数的返回值。毕竟,if(0)永远不会是真的。如果您想获得JZ,那么您应该执行if(variable == 0)之类的操作。请记住,编译器绝不需要实际发出JZ指令,它可以使用任何其他方法来实现相同的功能。将高级语言编译为汇编很少是一种清晰的一对一关联。

答案 2 :(得分:1)

代码可能已经过优化。

if (0){
   int x = 2;
  x++;
}

已被淘汰。

movl $0, %eax是设置返回值的位置。似乎其他指令只是程序初始化和退出。

答案 3 :(得分:0)

编译器有可能对其进行优化,因为它永远不会成真。

答案 4 :(得分:0)

优化器删除了if条件和内部的所有代码,因此根本没有显示。

答案 5 :(得分:0)

编译器优化了if(0){}块,因为永远不会调用它。 所以你的函数只返回0(movl $ 0,%eax)