【发布时间】:2011-06-15 11:07:03
【问题描述】:
在此编译器输出中,我试图了解 nopw 指令的机器代码编码是如何工作的:
00000000004004d0 <main>:
4004d0: eb fe jmp 4004d0 <main>
4004d2: 66 66 66 66 66 2e 0f nopw %cs:0x0(%rax,%rax,1)
4004d9: 1f 84 00 00 00 00 00
http://john.freml.in/amd64-nopl 有一些关于“nopw”的讨论。谁能解释 4004d2-4004e0 的含义?从操作码列表看,66 .. 代码似乎是多字节扩展。我觉得我可能会比我在这里得到更好的答案,除非我尝试探索操作码列表几个小时。
该 asm 输出来自 C 中的以下(疯狂的)代码,该代码优化为一个简单的无限循环:
long i = 0;
main() {
recurse();
}
recurse() {
i++;
recurse();
}
当使用gcc -O2编译时,编译器识别出无限递归并将其变成无限循环;事实上,它做得很好,它实际上在 main() 中循环而不调用 recurse() 函数。
编者注:带有 NOP 的填充函数并不特定于无限循环。这是一组具有一系列 NOP 长度的函数,on the Godbolt compiler explorer.
【问题讨论】:
-
我们只是在这里查看随机垃圾填充吗?
-
也许吧!我真的不知道!这就是这一切的美妙之处!哇。不过,真的,我从链接中得到处理器将加载一个块作为速度优化的一条指令,尽管感谢
jmp,它没有。我才明白它的意思。我知道 0x90 是什么,但我不知道66 .. ..是怎么回事,或者为什么它是 72 位长。 -
这不是这里的原因,但您可能会发现My, what strange NOPs you have! - The Old New Thing 是一个有趣的阅读。
标签: c gcc assembly x86 machine-code