GCC 生成无用的指令?

GCC generates useless instructions?

BOOL32 doStuff() {
    return TRUE;
}

gcc 2.95 for vxworks 5.x,使用 -O0 为 32 位 x86 编译以上代码生成以下代码:

          doStuff:
0e9de190:   push    %ebp
0e9de191:   mov     %esp,%ebp
 308          return TRUE;
0e9de193:   mov     [=11=]x1,%eax
0e9de198:   jmp     0xe9de1a0 <doStuff+16>
 312      {
0e9de19a:   lea     0x0(%esi),%esi
// The JMP jumps here
0e9de1a0:   mov     %ebp,%esp
0e9de1a2:   pop     %ebp
0e9de1a3:   ret

在 JMP 和 LEA 指令之前,一切看起来都很正常。它们有什么用?


我猜这是某种对齐方式,但我不确定。

我会做这样的事情:

          doStuff:
0e9de190:   push    %ebp
0e9de191:   mov     %esp,%ebp
 308          return TRUE;
0e9de193:   mov     [=12=]x1,%eax
0e9de1XX:   mov     %ebp,%esp
0e9de1XX:   pop     %ebp
0e9de1XX:   ret
0e9de1XX:   fill with lea 0x0, %esi

lea 0x0(%esi),%esi是一个long NOP,jmp就是跳过了。您可能有一个 ancient 版本的 binutils(包含 as)来配合您的旧 gcc 版本。

因此,当 gcc 放置一个 .p2align 以在函数中间对齐一个标签时,该标签不是分支目标(出于某些奇怪的原因,但它是 -O0,所以它甚至不应该是好的代码),汇编程序做了一个很长的 NOP 并跳过了它。

通常情况下,如果有很多 NOP,您只会跳过一块 NOP,尤其是当它们都是单字节 NOP 时。这真是愚蠢的代码,所以停止使用这种硬壳工具。您可以尝试升级您的汇编程序(但如果需要,仍然使用 gcc2.95)。或者检查它是否不会发生在 -O2-O3,在这种情况下无关紧要。

如果您出于某种原因必须继续使用 gcc2.95,请注意它是古老的,这是您为继续使用迫使您使用它的任何东西而做出的权衡的一部分。