Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 76 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?

like image 458
Eugene Avatar asked Jul 11 '11 17:07

Eugene


People also ask

What is RSP in x86?

On x86, the stack pointer is stored in the register called "rsp" (Register: Stack Pointer).

What does MOV EAX EAX mean?

mov eax, ebx – 2 operands, source and destination. mov eax, 5 – one operand is a literal. mov y, eax – memory to register movement. add eax, 5 – 2 operands for add. mul value – 1 operand for mul, other operand is eax.

What is mov esi?

MOV in Intel syntax assembly means “copy”. ESI is a processor register. The 8086 had a 16-bit SI register, where “SI” was short for “source index”, IIRC (used in combination with a destination index register and a counter register for automatically repeated copy operations).


2 Answers

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?

like image 162
Stephen Canon Avatar answered Oct 07 '22 19:10

Stephen Canon


#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.

like image 23
Ilya Matveychikov Avatar answered Oct 07 '22 18:10

Ilya Matveychikov