在此编译器输出中,我试图了解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 填充函数并不特定于无限循环。这是 Godbolt 编译器资源管理器上具有一系列 NOP 长度的函数集。