I have recently learned that nop
instruction is actually xchg eax, eax
... what it does is basically exchanges eax
with itself.
As far as CPU goes, does the exchange actually happen?
There are several instructions, which could be used depending on the compiler. xchg eax, eax
is byte code 90. It is a legit instruction, which takes up a single processing cycle. In addition, there are several other instructions, which could be used in place of xchg eax, eax
:
lea eax, [eax + 0x00] byte code 8D 40 00
mov eax, eax byte code 89 C0
Since all of those instructions are different length, compiler chooses one of the most appropriate versions depending on alignment requirements.
Regarding compilers' choices, a few pointers:
GAS (GNU Assembler, used by GCC) x86 NOP operations can be found in function i386_align_code()
similarly, for LLVM it is in X86AsmBackend::writeNopData()
nop
instruction is 0F 1F /0
which is NOP r/m16
and NOP r/m32
on supported CPUs. It may take anywhere from 3 to 9 bytes in x86-64, as per Intel doc (page 4-163). So even though you can use mov eax, eax
and others an an alternative, it has a downside vs. real nop
in that it blocks CPU pipeline and lacks other hardware optimizations that are implemented in the nop
instruction.
The short answer is "Yes." In fact, if you experiment by generating machine language op codes directly you will discover that there is a whole range of operations that are effectively NOPs, all of which take a single processor cycle to execute.
While they are not technically "Documented," you will find that very close to the 0x90,
XCHG EAX, EAX
XCHG EBX, EBX
XCHG ECX, ECX
XCHG EDX, EDX
xchg EAX, EAX
was actually executed... Most 32 bit instructions in x64 mode zero out the upper 332 bits of their operands , and this instruction did too.