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
答案 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强迫你使用它。