Posted 2010-02-23 00:00:00 GMT
I was looking at a disassembly. It contained this
What is the point of passing an operand to NOP? NOP is the instruction
that does nothing. Yet not quite true: Intel's US
Method of modifying an instruction set
architecture of a computer processor to maintain backward
compatibility suggests that they could opt to use more complex
NOP instructions to provide hints like memory prefetch requests. On
processors without the prefetch logic the operations would do nothing,
but processors with prefetch would initiate memory requests to bring
the data into cache. The extended NOPs taking operands that lie in the
amd64 and x86 instruction sets are called hinting nops for this
reason, but as far as I know they don't yet hint anything (see the
PREFETCH instructions near the same opcode code points).
It turns out that these interesting nopls, nopw, etc. are generated by GAS (that is, when using GCC). As the instruction set is encoded in quite a uniform way to simplify the decode stage, there are many instructions that achieve nothing: for example, xchg %ax,%ax (the standard two-byte nop) or leal 0(%esi),%esi, a three-byte nop. Dedicating opcodes for longer NOPs is a sensible way to simplify the CPU's own optimizations.
Aligning jump targets in code to a 16-byte boundary to make sure that the target can be fetched in a single cacheline request is important. However the padding used to flow through to this aligned boundary should be as efficiently encoded as possible, and using only a single instruction to take up eight bytes — nopw 0L(%[re]ax,%[re]ax,1), is more efficient than repeatedly exercising the decode logic on eight one-byte nops. The code to do this is in binutils/gas/config/tc-i386.c:i386_align_code.
Goes to show how mature the AMD64 instruction set has become — and how far from the days of the Binary Coded Decimal nonsense.
Post a comment