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?
On x86, the stack pointer is stored in the register called "rsp" (Register: Stack Pointer).
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.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With