Question

I was wondering what are "semantic NOPs" in assembly?

Was it helpful?

Solution

Code that isn't an actual nop but doesn't affect the behavior of the program.

In C, the following sequence could be thought of as a semantic NOP:

{
    // Since none of these have side affects, they are effectively no-ops
    int x = 5;
    int y = x * x;
    int z = y / x;
}

OTHER TIPS

They are instructions that have no effect, like a NOP, but take more bytes. Useful to get code aligned to a cache line boundary. An instruction like lea edi,[edi+0] is an example, it would take 7 NOPs to fill the same number of bytes but takes only 1 cycle instead of 7.

A semantic NOP is a collection of machine language instructions that have no effect at all or almost no effect (most instructions change condition codes) whose only purpose is obfuscation of what the program is actually doing.

Code that executes but doesn't do anything meaningful. These are also called "opaque predicates," and are used most often by obfuscators.

A true "semantic nop" is an instruction which has no effect other than taking some time and advancing the program counter. Many machines where register-to-register moves do not affect flags, for example, have numerous instructions that will move a register to itself. On the 8088, for example, any of the following would be semantic NOPs:

  mov al,al
  mov bl,bl
  mov cl,cl
  ...
  mov ax,ax
  mob bx,bx
  mov cx,cx
  ...
  xchg ax,ax
  xchg bx,bx
  xchg cx,cx
  ...

Note that all of the above except for "xchg ax,ax" are two-byte instructions. Intel has therefore declared that "xchg ax,ax" should be used when a one-byte NOP is required. Indeed, if one assembles "mov ax,ax" and disassembles it, it will disassemble as "NOP".

Note that in some cases an instruction or instruction sequence may have potential side-effects, but nonetheless be more desirable than the usual "nop". On the 6502, for example, if one needs a 7-cycle delay and the stack pointer is valid but the top-of-stack value is irrelevant, a PHP followed by a PLP will kill seven cycles using only two bytes of code. If the top-of-stack value isn't a spare byte of RAM, though, the sequence would fail.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top