Something interesting I have found and it certainly shows my very nerdy side and that is;
What does that refer to?
Why is there an assembly instruction for no operation. This item does not impact any registers (Except the EIP) and does not perform any memory operations. It does however take up space in the instruction stream.
From other sources I have gleaned that it will wait for 3 clock cycles. Unsure if it takes 3 clock cycles to increment the instruction pointer, since that kind of tracing is something done by the chip makers and not the software developers.
A Clock Cycle
Just a quick run down. Within a CPU we have all heard of the term 3.4GHz or other various forms of frequency when describing a CPU. Hz is a frequency, Radios use them to enable the tuner to pick up the station at the that frequency length. But the Hz we are talking about in a CPU are a little different.
A sine wave one complete turn, 360o is 1 clock cycle.
Looking at the graph above. If it takes 1 second to go from 0 to 360o then that is 1Hz.
|1Hz||1 cycle every second|
|1KHz||1000 cycles every second|
|1MHz||1,000,000 cycles every second|
|4.77MHz1||4,770,000 cycles every second|
|66MHz2||66,000,000 cycles every second|
|500MHz3||500,000,000 cycles every second|
|1.4GHz4||1,400,000,000 cycles every second (that is billion)|
|2.4GHz5||2,400,000,000 cycles every second|
|3.8GHz6||3,800,000,000 cycles every second|
So seeing these speeds of my computers over the years other than the first few values. So, waiting 3 clock cycles seems like nothing though on the slower computers it was more noticeable than today. Certainly when I was programming NOP was not used, simply because there was little need for it. I am sure it existed the purpose of assembly when I was writing it was to be as lean as possible. Having a No Operation instruction that chewed into CPU cycles for any reason was wasteful and 1 extra instruction could be executed as well.
Would you use it, as a marker for future code, that is up to the discretion of the developer. Since I started programming on older machines where system resources were very scarce I would always tend to say only put in what you need to put in.
My opinion is, don’t. If all it is going to do is be a place holder, increment the instruction point and then continue processing, this do not put it in, place a comment as your placeholder and then have your next line of code.
For those who are interested, this is the page from the Developer Guide from Intel.
220.127.116.11 No-Operation and Undefined Instructions
The NOP (no operation) instruction increments the EIP7 register to point at the next instruction, but affects nothing
There is also a FNOP – which does the same thing but operated on the FPU (the Floating Point Unit, or Maths Co-Processor).
|Opcode||Instruction||Op/En||64-Bit Mode||Compat/Leg Mode||Description|
|90||NOP||NP||Valid||Valid||One byte no-operation instruction.|
|0F 1F /0||NOP r/m16||M||Valid||Valid||Multi-byte no-operation instruction.|
|0F 1F /0||NOP r/m32||M||Valid||Valid||Multi-byte no-operation instruction.|
Instruction Operand Encoding
|Op/En||Operand 1||Operand 2||Operand 3||Operand 4|
This instruction performs no operation. It is a one-byte or multi-byte NOP that takes up space in the instruction
stream but does not impact machine context, except for the EIP register.
The multi-byte form of NOP is available on processors with model encoding:
- CPUID.01H.EAX[Bytes 11:8] = 0110B or 1111B
The multi-byte NOP instruction does not alter the content of a register and will not issue a memory operation. The
instruction’s operation is the same in non-64-bit modes and 64-bit mode.
The one-byte NOP instruction is an alias mnemonic for the XCHG (E)AX, (E)AX instruction.
The multi-byte NOP instruction performs no operation on supported processors and generates undefined opcode
exception on processors that do not support the multi-byte NOP instruction.
The memory operand form of the instruction allows software to create a byte sequence of “no operation” as one
instruction. For situations where multiple-byte NOPs are needed, the recommended operations (32-bit mode and
64-bit mode) are:
|2 bytes||66 NOP||66 90H|
|3 bytes||NOP DWORD ptr [EAX]||0F 1F 00H|
|4 bytes||NOP DWORD ptr [EAX + 00H]||0F 1F 40 00H|
|5 bytes||NOP DWORD ptr [EAX + EAX*1 + 00H]||0F 1F 44 00 00H|
|6 bytes||66 NOP DWORD ptr [EAX + EAX*1 + 00H]||66 0F 1F 44 00 00H|
|7 bytes||NOP DWORD ptr [EAX + 00000000H]||0F 1F 80 00 00 00 00H|
|8 bytes||NOP DWORD ptr [EAX + EAX*1 + 00000000H]||0F 1F 84 00 00 00 00 00H|
|9 bytes||66 NOP DWORD ptr [EAX + EAX*1 + 00000000H]||66 0F 1F 84 00 00 00 00 00H|
Exceptions (All Operating Modes)
#UD If the LOCK prefix is used.
- 4.77MHz was the clock speed of one of the original x86 processors or the 8088 version, 8bit. No history lesson today though. Though this was the speed of my first computer, it did have a turbo button to take it to 10Mhz
- This was the speed of my next computer, DX2-66 (overdrive) as it said on the chip.
- My next computer, the Intel Pentium 3 though I overclocked this to 550MHz
- My Pentium 4 HT was running nice at 1.4GHz
- A Core2 Quad come in for me at this nice speed
- Finally my new i7 sits at the 3.8GHz speed.
- EIP is just the Extended Instruction Pointer register. It is the pointer of where the current instruction is. ALL code lines increments the IP or EIP (depending on the CPU) and it is