在%x86-64上,mov%esi,%esi是否为no-op?

Eug*_*ene 8 assembly x86-64 linux-kernel

我对Linux内核的一个头文件(arch/x86/include/asm/nops.h)中的注释感到有些困惑.它说明了这一点

<...>以下指令在64位模式下不是nops,对于64位模式,使用K8或P6 nops而不是
movl%esi,%esi
leal 0x00(%esi),%esi
<...>

我想作者暗示机器指令(分别是'89 F6'和'8D 76 00')而不是汇编指令.根据LEA英特尔软件开发人员手册第2A卷中的描述,后一条指令(lea 0x00(%rsi), %esi)与前者相同,mov %esi,%esi.

所以这简化了问题,是否mov %esi,%esi实际上是x86-64上的无操作.

mov不会改变旗帜.这种mov也不会改变记忆.似乎,如果它改变了一些东西%rip,那应该是通用寄存器.但我不知道它如何改变内容%rsi或其他内容.如果你操纵通用寄存器的下半部分,上半部分不应该改变,对吧?

Ste*_*non 18

mov %esi, %esi
Run Code Online (Sandbox Code Playgroud)

将%rsi的高32位归零,因此不是x86_64上的无操作.

  • @Steve:我编写汇编的第一个平台是68k,所以我想我还有一段时间才能把它挂掉...... (4认同)
  • 看到你是一个集会的人,这是你的第486个答案,这是否意味着你现在不再回答问题了?(对不起,蹩脚的486笑话......我记得我的486DX2 ......现在我完全脱离主题了) (3认同)
  • 只是为了补充答案,英特尔开发手册的相关部分是3.4.1.1(第1卷). (2认同)

Ily*_*kov 6

#include <stdio.h>

int main(int argc, char * argv[])
{
    void * reg_rsi = 0;

    asm (
        "movq $0x1234567812345678, %%rsi;\n"
        "movl %%esi, %%esi;\n"
        "movq %%rsi, %0;\n"
        : "=r" (reg_rsi)
        : /* no inputs */
        : /* no clobbered */
    );

    printf("reg_rsi = %p\n", reg_rsi);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这为我的x86_64机器提供了"reg_rsi = 0x12345678".