海湾合作委员会不使用公司

hei*_*991 7 optimization assembly gcc x86-64 gcc4.8

GCC编译器

$ gcc --version
gcc (GCC) 4.8.2
...
Run Code Online (Sandbox Code Playgroud)

不生成inc汇编指令,它实际上可能有用,就像在这个C程序中:

int main(int argc, char **argv)
{
    int sum = 0;
    int i;
    for(i = 0; i < 1000000000L; i++)                     <---- that "i++"
        sum += i;
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

相反,它会生成一条add指令:

0000000000000000 <main>:
   0:   31 d2                   xor    %edx,%edx
   2:   31 c0                   xor    %eax,%eax
   4:   0f 1f 40 00             nopl   0x0(%rax)
   8:   01 d0                   add    %edx,%eax
   a:   83 c2 01                add    $0x1,%edx         <---- HERE
   d:   81 fa 00 ca 9a 3b       cmp    $0x3b9aca00,%edx
  13:   75 f3                   jne    8 <main+0x8>
  15:   f3 c3                   repz retq 
Run Code Online (Sandbox Code Playgroud)

为什么这样做?

编辑:我曾经gcc -O2编译过这个.gcc -Os确实产生了一条inc指令.是不是使用inc速度优化而不是空间优化?

gsg*_*gsg 12

尝试一下-march=<your machine>.结果可能会有所不同.

但是,请注意,这add $1, %reg不一定是一个糟糕的选择.虽然inc并且dec具有较小的编码,这是有吸引力的,但是它们遭受这样的事实:它们仅部分地更新标志,导致错误的依赖性问题.英特尔优化手册包含此评论(我的重点):

INC和DEC指令仅修改标志寄存器中的一部分位.这会产生对标志寄存器的所有先前写入的依赖性.当这些指令位于关键路径上时,这尤其成问题,因为它们用于更改许多其他指令所依赖的负载的地址.汇编/编译器编码规则33.(M影响,H一般性)INC和DEC指令应该用ADD或SUB指令替换,因为ADD和SUB会覆盖所有标志,而INC和DEC则不会,因此会对先前的指令产生错误依赖性设置标志.