GCC热补丁?

5

当我编译这段代码时

unsigned char A[] = {1, 2, 3, 4};

unsigned int
f (unsigned int x)
{
  return A[x];
}

gcc输出

mov edi, edi
movzx  eax, BYTE PTR A[rdi]
ret

在一台x86_64的机器上。
问题是:为什么有一个nop指令(mov edi,edi)?
我正在使用gcc-4.4.4。

自然而然地,混淆代码是必要的! - Thomas Eding
1个回答

3
在64位模式下,mov edi, edi不是无操作。它的作用是将rdi的高32位设置为0。
这是一个一般事实的特殊情况,即在64位模式下,所有32位操作都会清除目标寄存器的高32位。(这比保留它们更有效率,也可能更有用。)

哦,你能引用一些相关来源吗? - osgx
1
好的,我认为你对此是正确的。这只是一种清除 rdi 顶部的花哨方式。重新阅读问题后,我理解 OP 不是在问“为什么这个可热插拔函数以 mov edi, edi 开头”,而是像“为什么这个 x86-64 汇编代码看起来像一个可热插拔函数”。此外,该代码甚至没有指定 ms_hook_prologue 属性,最新版本的 gcc 不支持 x86-64 的 ms_hook_prologue,似乎在 x86-64 上会使用 leaq [%rsp + 0], %rsp prologue 而不是 mov edi, edi(http://tinyurl.com/39fye3w)。我将删除我的答案。 - Alex Jasmin
我明白了,谢谢。但是如果ABI规定寄存器中的32位参数应该已经清除了高位,那不是更有用吗? - Luís Fernando Schultz Xavier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接