GCC生成无用的指令?

时间:2016-08-31 11:39:24

标签: gcc assembly x86 reverse-engineering

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     $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

1 个答案:

答案 0 :(得分:8)

lea 0x0(%esi),%esi是一个很长的NOP,而jmp正在跳过它。您可能有一个古代版本的binutils(包含as)与您的古老gcc版本一起使用。

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

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

如果由于某种原因你必须继续使用gcc2.95,那么请注意它是古老的,这是你为了继续使用它而做出的权衡的一部分&#39 ; s强迫你使用它。