【问题标题】:GCC generates useless instructions?GCC生成无用的指令?
【发布时间】:2017-01-07 23:42:03
【问题描述】:
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

【问题讨论】:

  • 您编写的哪些代码最终被翻译成上面生成的程序集?您应该包含此信息以增加获得帮助的机会。
  • 你编译优化了吗?什么平台/操作系统?
  • 添加信息希望对您有所帮助
  • 查看在-O0 编译的代码完全是浪费时间。编译器不仅不关心生成最优代码,它有时会生成病态次优代码以使调试更容易(例如,允许你设置断点)。您应该查看的唯一反汇编是优化代码。

标签: gcc assembly x86 reverse-engineering


【解决方案1】:

lea 0x0(%esi),%esi 是一个长 NOP,jmp 正在跳过它。您可能有一个 ancient 版本的 binutils(包含 as)来配合您的古老 gcc 版本。

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

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

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

【讨论】:

  • 加上-O2看起来好多了^^
猜你喜欢
  • 2018-07-08
  • 2020-04-13
  • 2014-03-17
  • 2017-05-15
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
相关资源
最近更新 更多