【8086汇编】关于NOP指令
初学8086汇编时,绝大多数同学对NOP 的印象只有一句话:空指令、啥也不干。
做电子琴延时、做简单时序填充时随手写几句 NOP,却从来不知道:
为什么 NOP 能延时?
为什么工程、驱动、逆向工程里大量充斥 NOP?
它机器码为什么是 0x90?
看似无用的指令,为什么 CPU 要专门设计它?
一、NOP 到底是什么
1. 全称
NOP = No Operation 空操作指令
2. 核心特性
不修改任何寄存器(AX、BX、标志位全部不变)
不读写内存
只占用 1 个字节机器码 0x90
消耗 1 个 CPU 时钟周期,然后继续往下执行
一句话总结:NOP 不改变程序数据,只改变程序时间与内存布局。
很多人误解:NOP 是空的、没用的。
真相:不做事,本身就是它最大的用处。
二、为什么 CPU 要设计一条“啥也不干”的指令?
高级语言没有“空操作”,因为高级语言只管逻辑。
但汇编、硬件、CPU 流水线、时序控制必须要有空操作:
CPU 运行是连续、匀速、逐周期的,不能暂停、不能跳空。
如果需要“等一会”“对齐地址”“留白占位”,就必须用 NOP 填充周期/空间。
三、NOP 做软件延时(电子琴实验)
1. 我们做过的电子琴代码原理
单纯 loop 循环速度极快,喇叭震动时间太短,人耳完全听不到声音。
所以需要在循环里插入 NOP,强行拖长时钟周期,拉长发声时长。
2. 延时模板
delay:
nop
nop
nop
loop delay
3. 原理拆解
每一条 NOP = 卡住 1 个时钟周期
NOP 越多 → 单次循环越慢 → 延时越长 → 音符清晰可闻
四、NOP 的四大专业用途
用途1:精准软件延时
适合短延时、硬件时序匹配、蜂鸣器、LED 闪烁、端口稳定等待。
优点:周期固定、误差极小、不破坏寄存器。
用途2:代码地址对齐
CPU 读取指令时,地址对齐的代码执行效率更高。
如果一段代码结束地址不规整,编译器会自动填充多条 NOP,让下一段程序从整地址开始执行。
用途3:代码占位、预留修改空间
开发调试时,如果后续可能需要新增指令,可以先写多条 NOP 占位。
后续直接把 NOP 替换成新指令,不用整体移动代码地址,避免程序崩地址偏移。
用途4:逆向工程破解、NOP 雪橇原理)
在软件逆向、漏洞利用中,大量填充 NOP 形成 NOP 雪橇,让程序错误执行滑入目标代码段。
同时逆向中常用 NOP 覆盖跳转指令,干掉验证逻辑、破解弹窗、去除注册判断。
五、NOP 机器码 0x90 冷知识
在 x86 架构中:
NOP 本质等价于:XCHG EAX, EAX
自己和自己交换数据,等于啥也没做,但是占用周期、占用字节。
所以机器码固定为 0x90,单字节指令,极其轻量。
写在最后
很多汇编知识点看起来平平无奇,比如 NOP、寻址、中断、进位标志。
但正是这些不起眼的底层指令,撑起了操作系统、驱动、嵌入式、逆向安全的整个技术体系。
看懂 NOP,你就已经从 只会抄代码的初学者,变成了 懂底层原理的学习者。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)