开发者

Is mov %esi, %esi a no-op or not on x86-64?

I am a bit confused by the comment in one of the header files for the Linux kernel, arch/x86/include/asm/nops.h. It states that

<...> the following instructions are NOT nops in 64-bit mode, for 64-bit mode use K8 or P6 nops instead

movl %esi,%esi

leal 0x00(%esi),%esi

<...>

I guess the author implied the machine instructions ('89 F6' and '8D 7开发者_运维问答6 00', respectively) there rather than assembly instructions. It follows from the description of LEA in Intel Software Developer's Manual Vol 2A that the latter instruction (lea 0x00(%rsi), %esi) does the same as the the former, mov %esi,%esi.

So this reduces to the question, whether mov %esi,%esi is actually a no-op on x86-64.

mov does not change flags. This kind of mov does not change memory either. It seems, if it changes something besides %rip, that should be general purpose registers. But I have no clue how it can change the contents of %rsi or whatever. If you manipulate the lower half of a general purpose register, the upper half should not change, right?


mov %esi, %esi

zeros out the high 32 bits of %rsi, and is therefore not a no-op on x86_64.

See Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?


#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;
}

This gives "reg_rsi = 0x12345678" for my x86_64 machine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜