24

I red the definition from http://en.wikipedia.org/wiki/NOP but I still need a simpler definition.

I stumbled across a code and I don't know exactly what it does:

switch (Something)
    {

        case this_one:
            asm ("nop");
            break;
        case other_one:
            asm ("nop");
            break;
        default:
            asm ("nop");
            break;
    }
Alexandru Cimpanu
  • 1,029
  • 2
  • 14
  • 38
  • This code does nothing meaningful. – Oliver Charlesworth Jun 23 '14 at 06:30
  • 12
    `asm` inserts inline assembly, `nop` is an instruction which does nothing. The code example does nothing useful. Which part are you having difficulty with ? – Paul R Jun 23 '14 at 06:30
  • I'm having trouble understanding what that `nothing` is. For example what would be the difference between having the line `asm ("nop");` and not having it? – Alexandru Cimpanu Jun 23 '14 at 06:32
  • 1
    Your code technically does "nothing", it's hard to tell why it exists without placing it into context with other bits of code. However, it may be being used for optimisation purposes - to preserve memory alignment for example. Some processors perform better when memory is "aligned" into power of 2 chunk sizes. – Phill Jun 23 '14 at 06:34
  • 8
    Metaphysically there's no such thing, as "nothing". NOP or No Operation means that the CPU (eventually) wastes clock cycles. It must at least decode the operation and notice that it has to fetch a new instruction. The Nothing in this context means, that "Program Counter" register is changed; _probably_ no other side effects take place. – Aki Suihkonen Jun 23 '14 at 06:40
  • 1
    @AlexandruCimpanu There are several purposes, some are mentioned in the answers below. One more that wasn't mentioned is to insert a delay > epsilon between consecutive instructions (might be needed if the code is working with HW) – SomeWittyUsername Jun 23 '14 at 06:41
  • 4
    Personally I often use asm NOP for debug code, when there is a place in the code where I would like to put a breakpoint. – Lundin Jun 23 '14 at 06:42
  • 1
    It can also be used as a placeholder for a self modifying code in the real address mode, for to write additional, or some different instructions into the code segment while the code is running. – Dirk Wolfgang Glomp Jun 23 '14 at 06:45
  • `NOP` could be a delay or padding, when i learnt assembly language i was told it can be a good idea to put a `NOP` at the start of my instructions (it was for gdb if i remember correctly). I have also seen a linux hack using a `NOP SLIDE`, My memory is a bit sketchy but pretty much somebody puts the code for a bunch of nops then an address into an environment variable and exploits a program with a buffer overflow to jump to approximately somewhere into the nop slide (it looked tricky to find the exact location of the address, so it was clever to use nop's to slide down to the address) – James Jun 24 '14 at 23:49
  • See; https://youtu.be/lF1wi41ExJ0 – user4578093 Jul 01 '15 at 06:09

7 Answers7

31

nop is an assembly instruction that does nothing--well as close to nothing as you can do and still execute a machine instruction, which means (probably) a REALLY tiny bit of time goes by (which can have limited value in certain realtime applications.

In this case, the statement asm("nop"); makes no semantic difference to the program. The only reason I can think that it might be present is to "force" the compiler to NOT collapse the code paths, making the machine structure of the switch statement visible if you look at the object code or disassemble the machine code or view it in a debugger.

Dwayne Towell
  • 8,154
  • 4
  • 36
  • 49
  • What is the difference between having `asm("nop");` in the code and leaving only `break`? – Alexandru Cimpanu Jun 23 '14 at 06:34
  • 2
    @AlexandruCimpanu: The compiler will (most likely) not optimize away an asm() instruction, because he doesn't look at its arguments. A simple break can be optimized away. – PMF Jun 23 '14 at 06:56
  • @PMF: You wouldn't need a `nop` for that, I think. An empty `volatile asm("",,,"memory")` statement should do the trick. – Kerrek SB Jun 23 '14 at 08:06
  • @DwayneTowell: nops are useful in code generation, too, to provide alignment (e.g. of jump targets and function entry points). You can also use nops to leave room for debugging -- you can insert jumps into a block of nops and hot-fix your code... – Kerrek SB Jun 23 '14 at 08:08
  • @KerrekSB: Right, but the nop thing looks a bit simpler to me. Just a matter of taste, probably. – PMF Jun 23 '14 at 08:25
  • 2
    @PMF: Well, the nop produces one instruction, the empty asm statement produces none... – Kerrek SB Jun 23 '14 at 08:26
  • @Alexandru Cimpanu as break itself will be just ignored and not generate any code or entry in the jump table – 0___________ Aug 12 '17 at 16:42
  • But in this case it possible all of the 3 cases to be aggregated in one. To prevent it `asm volatile` should be used – 0___________ Aug 12 '17 at 16:47
14

Since nobody mentioned it, nop can also be useful to "yield" during a critical section, i.e. allow other interrupts to occur so as to reduce interrupt latency caused by the critical section.

This is typically useful in embedded applications without operating systems where you often have to poll variables and/or status registers during a critical section.

On many RISC processors (ARM, AVR), the instruction immediately following interrupt unmasking will still be masked, so if you just put sei/cli close together, you won't allow any interrupt to occur.

Each nop added between sei and cli allows one more interrupt to occur before the critical section resumes.

kuroi neko
  • 8,479
  • 1
  • 19
  • 43
8

NOP is useful for debugging. Even when doing nothing because means "no operation", NOP is instruction on what you can set breakpoint in debugger. I believe programmer wanted to learn value of "Something" this way. It looks stupid but it took hours for one experienced programmer to find out why

if(Something);
{
 ...
}

was always going inside scope not depending on value of Something. I suspect someone had similar problem with switch() now. If programmer omits NOP, compiler may more easily remove whole switch() statement. I also use __asm__("#start"); for making clear borders for some code in Maximum speed from IOS/iPad/iPhone but __asm__("nop"); would do same too.

Also as already told, it can be used for realtime applications. For example http://www.rickard.gunee.com/projects/video/pic/tetris.php might use this.

Community
  • 1
  • 1
Tõnu Samuel
  • 2,877
  • 2
  • 20
  • 30
  • Well... experienced programmers keep all compiler warnings enabled. Also, experienced C programmers develop something of a sub-conscious reflex against those stray semi-colons and instantly spot them. – Lundin Jun 23 '14 at 07:02
  • 3
    This case was real but many years ago. Maybe GCC did not gave warning, I do not remember. Also people are just sometime tired etc. – Tõnu Samuel Jun 23 '14 at 07:04
  • 1
    Thank you for posting this! I found this answer to be very helpful because I never thought to use NOP that way before. – Kelsius Apr 27 '16 at 14:44
6

As already mentioned, it has uses in the embedded world. Sometimes you need to wait a cycle or two, before a pin is actually set to a certain state, especially on some sensors, etc... In the Paleolithic Era of 6581 cpu, nop was used to generate a delay, since clock was about 0.7mhz... Also what is said about the interrupts is also true.

4

NOP is an assembly instruction that means (no operation) as it said It just doesn't do anything, but it is processed by the CPU like any other instruction. So this means that it will be readed from memory, will increment the instruction pointer, but in the execute phase after the instruction decode nothing else will be done. It's frequently used by crackers in reverse ingeniery, but don't know about another uses it will have. I don't think there is any need to use a NOP instruction in C programming.

sir psycho sexy
  • 780
  • 7
  • 19
  • It could be useful if you are are running a tight polling loop and don't want the compiler to optimize out an empty loop. – BretD Aug 24 '16 at 16:04
  • @BretD Unfortunately it is true only on a very simple uC. Pipelined ones just skip nops and there is no guarantee of any delay. - For example ARM where they are useful for padding. – 0___________ Aug 12 '17 at 16:32
4

On Intel x86 atleast, nop is a mnemonic for xchg eax,eax, so it exchanges the eax register with itself. There's other forms which do the same thing but take more space (for eg. lea esi,[esi + eiz] - adds 0 to esi), but these are not the "official" nop instruction.

1

A nop is a computer instruction that does nothing. In this particular case, it's probably there to prevent the switch from being optimized away. That's implementation specific to the compiler at best, since there's nothing stopping it from parsing and optimizing asm statements.

Why one would do this? It could be for testing the machine code generation somehow. Functionally, it's not useful.

Per Johansson
  • 6,697
  • 27
  • 34
  • 3
    Actually, I don't think I've seen a compiler that dares to optimize away a NOP, since it is always there for a reason. For example, a program running on a fast MCU which is interacting with digital logic electronics could use the NOP as a mini-delay, to allow the logic levels to become stable. – Lundin Jun 23 '14 at 06:44
  • 1
    nop is costly it can be useful in realtime functions. – Micromega Jun 23 '14 at 06:45
  • 1
    Maybe. It's implementation specific regardless. It wouldn't surprise me if `nop`s aren't even put in the PIQ on e.g. x86. Still, it does take up memory, and I suppose that does have some effect. – Per Johansson Jun 23 '14 at 06:49
  • 1
    That's not true for most if not all compilers. `asm` statements are considered volatile (non-optimizable) by default, unless you add constraints to let the compiler know the purpose of the inline code (registers used, memory modifications, etc). – kuroi neko Aug 12 '17 at 11:52
  • 1
    @Lundin not on modern uP / uC is used only for padding - never for delays http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CHDJJGFB.html. If you need cycle accurate delay - only barrier instructions – 0___________ Aug 12 '17 at 16:39
  • @Lundin compiler may optimise `asm` instructions. To prevent it `asm volatile ("...")` should be used – 0___________ Aug 12 '17 at 16:45
  • @PeterJ_01: [GNU C "basic" inline asm statements](https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html) (i.e. ones without input / output constraints) are implicitly `volatile`. "Extended" asm statements without `volatile` are still treated as a black box that the compiler doesn't try to understand, but without `volatile` they're treated as a pure function of their inputs, and may be hoisted out of a loop, or optimized away entirely if nothing uses any of the outputs. e.g. `int unused; asm("nop" : "=r" (unused));` could be optimized away, but so could `asm("mov $1, %0" : "=r" (unused));` – Peter Cordes Aug 23 '17 at 21:35
  • @PerJohansson: PIQ=https://en.wikipedia.org/wiki/Prefetch_input_queue? On Intel Sandybridge-family CPUs, they have to go through the entire pipeline from decode to issue to retirement, and use up an entry in the ROB. They don't use an execution port, like xor-zeroing, but definitely consume front-end bandwidth. Maybe if it was necessary to execute NOPs quickly, Intel could have spent transistors on handling them without taking up space in the uop cache and front-end bandwidth, but it's not necessary. Just don't put NOPs inside hot loops. – Peter Cordes Aug 23 '17 at 21:40