What's the purpose of the nop opcode?

不打扰是莪最后的温柔 提交于 2019-12-17 17:24:34

问题


I'm going through MSIL and noticing there are a lot of nop instructions. The MSDN article says they take no action and are used to fill space if the opcode is patched. They're used a lot more in debug builds than release builds. I know that these kinds of statements are used in assembly languages to make sure an opcode fits on a word boundary, but why is it needed in MSIL?


回答1:


NOPs serve several purposes:

  • They allow the debugger to place a breakpoint on a line even if it is combined with others in the generated code.
  • It allows the loader to patch a jump with a different-sized target offset.
  • It allows a block of code to be aligned at a particular boundary, which can be good for caching.
  • It allows for incremental linking to overwrite chunks of code with a call to a new section without having to worry about the overall function changing size.



回答2:


Here's how nops are used by debugging:

Nops are used by language compilers (C#, VB, etc.) to define implicit sequence points. These tell the JIT compiler where to ensure machine instructions can be mapped back to IL instructions.

Rick Byer's blog entry on DebuggingModes.IgnoreSymbolStoreSequencePoints, explains a few of the details.

C# also places Nops after call instructions so that the return site location in source is the call out rather than the line after the call.




回答3:


It provides an opportunity for line-based markers (e.g. breakpoints) in the code where a release build would emit none.




回答4:


It may also make code run faster, when optimizing for specific processors or architectures:

Processors for a long time employ multiple pipelines that work roughly in parallel, so two independent instruction can be exceuted at the same time. On a simple processor with two pipelines, the first may support all instructions, whereas the second supports only a subset. Also, there are some stalls between the pipelines when one has to wait for the result of a previous instruction that isn't finished yet.

Under these circumstances, a dedicated nop may force the next instruction into a specific pipeline (the first, or not the first), and improve the pairing of following instructions so that the cost of the nop is more than amortized.




回答5:


Dude! No-op is awesome! It is an instruction that does nothing but consume time. In the dim dark ages you would use it to do microadjustments in timing in critical loops or more importantly as a filler in self-modifying code.




回答6:


In one processor I worked for recently (for four years) NOP was used to make sure the previous operation finished before the next operation was started. For instance:

load value to register (takes 8 cycles) nop 8 add 1 to register

This made sure register had the correct value before the add operation.

Another use was to fill in execution units, such as the interrupt vectors which had to be a certain size (32 bytes) because address for vector0 was, say 0, for vector 1 0x20 and so on, so the compiler put NOPs in there if needed.




回答7:


They could be using them to support edit-and-continue while debugging. It provides the debugger with room to work to replace the old code with new without changing offsets, etc.




回答8:


One classic use for them is so that your debugger can always associate a source-code line with an IL instruction.




回答9:


I've also seen NOPs in code that modifies itself to obfuscate what it does as a placeholder (veeery old copy protection).




回答10:


Nop is essential in the payload of buffer overflow exploits.




回答11:


As ddaa said, nops let you account for variance in the stack, so that when you overwrite the return address it jumps to the nop sled (a lot of nops in a row) and then hits the executable code correctly, rather than jumping to some byte in the instruction that isn't the beginning.




回答12:


A somewhat unorthodox use are NOP-Slides, used in buffer overflow exploits.




回答13:


50 years too late but hey.

Nop's are useful if you are typing assembly code by hand. If you had to remove code, you could nop the old opcodes.

similary, you could insert new code by overwriting some opcode and jump somewhere else. There you put the overwritten opcodes, and insert your new code. When ready you jump back.

Sometimes you had to use the tools which were available. In some cases this was just a very basic machinecode editor.

Nowadays with compilers the techniques make no sense whatsoever anymore.




回答14:


In the software cracking scene, a classic method to unlock an application would be to patch with a NOP the line that checks for the key or registration or time period or whatnot so it would do nothing and simply continue starting the application as if it is registered.




回答15:


They allow the linker to replace a longer instruction (typically long jump) with a shorter one (short jump). The NOP takes the extra space - the code could not be moved around as it would stop other jumps from working. This happens at link-time, so the compiler can't know whether a long or short jump would be appropriate.

At least, that's one of their traditional uses.




回答16:


This is not an answer to your specific question, but back in the old days you could use a NOP to fill a branch delay slot, if you couldn't manage to fill it with an otherwise-useful instruction.




回答17:


Do the .NET compilers align the MSIL output? I'd imagine it might be useful for speeding up access to the IL... Also, my understanding is that it's designed to be portable and aligned accesses are required on some other hardware platforms.




回答18:


The first assembly I learned was SPARC so I'm familiar with the branch delay slot, if you can't fill it with another instruction, usually the instruction you were going to put above the branch instruction or increment a counter in loops, you use a NOP.

I'm not familiar with cracking, but I think is common to overwrite the stack using NOP so you have not to exactly calculate where your malicious function begins.




回答19:


I used NOPs to automagically adjust the latency accumulated after entering an ISR. Very handy to nail timing dead on.



来源:https://stackoverflow.com/questions/234906/whats-the-purpose-of-the-nop-opcode

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!