GCC生成无用的指令?

5
BOOL32 doStuff() {
    return TRUE;
}

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

          doStuff:
0e9de190:   push    %ebp
0e9de191:   mov     %esp,%ebp
 308          return TRUE;
0e9de193:   mov     $0x1,%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     $0x1,%eax
0e9de1XX:   mov     %ebp,%esp
0e9de1XX:   pop     %ebp
0e9de1XX:   ret
0e9de1XX:   fill with lea 0x0, %esi

你写了哪些代码最终被翻译成上面生成的汇编代码?你应该包含这些信息以增加获得帮助的机会。 - code_dredd
你是否使用优化编译?使用的是哪个平台/操作系统? - rubenvb
添加了一些信息,希望这能有所帮助。 - maxbit89
4
查看使用“-O0”编译的代码完全是浪费时间。编译器不仅不在意生成最优代码,有时还会生成病态的次优代码以便于调试(例如允许您设置断点)。您应该查看优化后的代码的反汇编结果。 - Cody Gray
1个回答

8

lea 0x0(%esi),%esi 是一个长的NOP指令,而jmp则跳过了它。你可能使用的是旧版binutils(包含as)以及旧版gcc。

因此,当gcc在函数中间放置.p2align以对齐标签时,这个标签本身并不是分支目标(出于某种奇怪的原因,但由于是-O0,所以并不是好代码),汇编器会生成一个长的NOP指令,并跳过它。

通常只有在有许多NOP指令的情况下,尤其是所有单字节NOP指令的情况下,才会跳过一组NOP指令。这段代码非常愚蠢,因此请停止使用如此老旧的工具。您可以尝试升级汇编器(但仍然使用gcc2.95,如果需要的话)。或者检查它是否发生在-O2-O3, 如果是这样,那就无关紧要了。

如果您必须继续使用gcc2.95,那么请注意它是古老的,这是您为保持使用它所做的权衡之一。


1
使用 -O2 优化选项后,效果看起来好多了 ^^ - maxbit89

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接