首页
社区
课程
招聘
[分享]8086汇编语言基础知识
发表于: 4天前 1024

[分享]8086汇编语言基础知识

4天前
1024

8086汇编语言基础知识

参考书目:王爽《汇编语言》(第4版)
处理器架构:Intel 8086


一、基础原理

1.1 计算机基本结构

计算机由 CPU(中央处理器)、内存(存储器)和 I/O 设备(外部设备)三大部分组成。CPU 是计算机的核心,负责执行指令;内存用于存储程序和数据;I/O 设备实现人机交互和数据输入输出。

CPU 通过总线(Bus) 与内存和 I/O 设备连接。8086 CPU 的外部总线分为三类:

总线类型 宽度 作用 说明
地址总线(Address Bus) 20 根 传送地址信息 可寻址 2^20 = 1MB 内存空间
数据总线(Data Bus) 16 根 传送数据信息 一次可传送 16 位(2 字节)数据
控制总线(Control Bus) 若干根 传送控制信号 包括读/写信号、中断请求、中断响应等

1.2 内存与地址

内存是计算机中用于存储程序和数据的部件。内存被划分为若干个存储单元,每个存储单元可存储 1 字节(8 bit)的数据。每个存储单元都有一个唯一的编号,称为地址(Address)

8086 CPU 有 20 根地址线,因此可寻址的内存空间为 2^20 = 1,048,576 字节 = 1MB,地址范围为 00000H ~ FFFFFH

关键概念:

概念 说明
字节(Byte) 8 个二进制位(bit),内存的基本存储单位
字(Word) 16 个二进制位,即 2 字节,8086 的基本字长
双字(Double Word) 32 个二进制位,即 4 字节
物理地址 CPU 实际输出到地址总线上的 20 位地址,唯一标识一个内存单元
段地址 16 位的段基址,用于在段式内存管理中定位段的起始位置
偏移地址 16 位的段内偏移量,表示数据在段内相对于段起始位置的偏移

1.3 段地址与物理地址的计算

8086 CPU 内部所有寄存器都是 16 位的,只能直接处理 16 位数据,但地址总线是 20 位的,需要 20 位地址。为了解决这个矛盾,8086 采用段地址 + 偏移地址的方式来形成 20 位物理地址。

物理地址计算公式:

物理地址 = 段地址 × 10H + 偏移地址

即段地址左移 4 位(乘以 16),再加上偏移地址,得到 20 位物理地址。

示例:

段地址 偏移地址 计算过程 物理地址
2000H 0030H 2000H × 10H + 0030H = 20000H + 0030H 20030H
FFFFH 0000H FFFFH × 10H + 0000H = FFFF0H + 0000H FFFF0H
1230H 0089H 1230H × 10H + 0089H = 12300H + 0089H 12389H
0000H FFFFH 0000H × 10H + FFFFH = 00000H + FFFFH 0FFFFH

段的特性:

  • 段的起始地址必须是 16 的倍数(即段地址 × 10H)
  • 段的最大长度为 64KB(偏移地址范围 0000H ~ FFFFH)
  • 一个物理地址可以由多个不同的"段地址:偏移地址"组合表示(例如 12389H 可以是 1230H:0089H,也可以是 1238H:0009H)

1.4 内存分段

8086 将 1MB 内存划分为若干个逻辑段,每个段用于存放特定用途的信息。常见的段类型如下:

段类型 用途 对应段寄存器 说明
代码段(Code Segment) 存放程序的指令代码 CS CPU 从 CS:IP 指向的地址读取指令执行
数据段(Data Segment) 存放程序使用的数据 DS 程序中访问数据时默认使用 DS 作为段地址
栈段(Stack Segment) 用于栈操作,存放临时数据 SS 栈顶地址由 SS:SP 指向
附加段(Extra Segment) 附加数据段,常用于串操作 ES 串操作指令中目的串的段地址

1.5 指令执行过程

CPU 执行指令的基本过程如下:

  1. CPU 从 CS:IP 指向的内存单元读取指令(取指)
  2. IP 自动增加,指向下一条指令(IP = IP + 指令长度)
  3. CPU 对取出的指令进行译码(译码)
  4. CPU 执行该指令所规定的操作(执行)
  5. 回到第 1 步,继续下一条指令的执行

关键要点:

  • CS(代码段寄存器)和 IP(指令指针寄存器)共同决定 CPU 当前要执行的指令地址
  • CPU 加电或复位时,CS = FFFFH,IP = 0000H,物理地址 = FFFF0H,这是 BIOS 程序的入口
  • 8086 的指令长度不固定,从 1 字节到 6 字节不等

1.6 栈(Stack)

栈是一种后进先出(LIFO) 的数据结构,8086 在硬件层面支持栈操作。栈段由 SS:SP 指定:SS 为栈段段地址,SP 为栈顶偏移地址。

8086 的栈是向下生长的,即每入栈一个数据,SP 减小。

操作 指令 SP 变化 说明
入栈(Push) PUSH AX SP = SP - 2 先将 SP 减 2,再将 AX 的内容存入 SS:SP 指向的内存单元
出栈(Pop) POP AX SP = SP + 2 先将 SS:SP 指向的内存单元的内容取出送入 AX,再将 SP 加 2
入栈(Push) PUSH BX SP = SP - 2 将 BX 的值压入栈中
出栈(Pop) POP DS SP = SP + 2 从栈中弹出一个字送入 DS

注意: 8086 的栈操作以**字(16 位)**为单位,每次入栈或出栈都是 2 字节。

1.7 BIOS 与 DOS

概念 说明
BIOS(基本输入输出系统) 固化在 ROM 中的程序,提供最基本的硬件控制服务,开机后首先运行
DOS(磁盘操作系统) 运行在 BIOS 之上的操作系统,提供文件管理、程序加载等服务
中断(Interrupt) CPU 暂停当前程序,转去执行中断处理程序,执行完后返回原程序继续执行
中断向量 中断处理程序的入口地址,存放在内存 0000:0000 开始的中断向量表中
中断向量表 位于内存 0000H:0000H ~ 0000H:03FFH,共 256 个中断向量,每个占 4 字节

1.8 寻址方式

8086 汇编语言支持多种寻址方式,用于确定操作数的来源:

寻址方式 说明 示例 操作数位置
立即寻址 操作数直接包含在指令中 MOV AX, 1234H 指令本身
寄存器寻址 操作数在寄存器中 MOV AX, BX 寄存器
直接寻址 操作数的偏移地址直接给出 MOV AX, [1234H] 内存,DS:1234H
寄存器间接寻址 操作数的偏移地址在寄存器中 MOV AX, [BX] 内存,DS:[BX]
寄存器相对寻址 寄存器内容加位移量 MOV AX, [BX+08H] 内存,DS:[BX+08H]
基址变址寻址 基址寄存器加变址寄存器 MOV AX, [BX+SI] 内存,DS:[BX+SI]
相对基址变址寻址 基址+变址+位移量 MOV AX, [BX+SI+08H] 内存,DS:[BX+SI+08H]

可用于间接寻址的寄存器:

寄存器 默认段寄存器 说明
BX DS 基址寄存器
BP SS 基址指针,默认使用栈段
SI DS 源变址寄存器
DI DS 目的变址寄存器

1.9 数据类型与存储顺序

8086 采用小端模式(Little-Endian):低字节存放在低地址,高字节存放在高地址。

数据 占用字节 内存存储示例(地址从低到高)
字节(Byte) 45H 1 字节 45
字(Word) 1234H 2 字节 34 12
双字(DWord) 12345678H 4 字节 78 56 34 12

二、寄存器

2.1 通用寄存器

8086 CPU 有 4 个 16 位通用寄存器,每个都可以拆分为两个独立的 8 位寄存器使用。

16位寄存器 高8位 低8位 主要用途 特殊用途
AX(累加器) AH AL 算术运算、逻辑运算的默认操作数 乘除法中隐含使用;I/O 指令中用于传送数据
BX(基址寄存器) BH BL 存放内存操作数的基址偏移量 可用于寄存器间接寻址 [BX]
CX(计数寄存器) CH CL 通用数据存储 LOOP 指令和串操作 REP 前缀中用作循环计数器;移位指令中指定移位次数
DX(数据寄存器) DH DL 通用数据存储 乘法中存放高 16 位结果;除法中存放被除数的高 16 位;间接 I/O 中存放端口地址

通用寄存器的拆分:

AX = AH : AL    (AH 为高 8 位,AL 为低 8 位)
BX = BH : BL
CX = CH : CL
DX = DH : DL

各寄存器在乘除法中的隐含使用:

运算 指令 隐含使用的寄存器 说明
字节乘法 MUL BL AX = AL × BL 被乘数在 AL,结果在 AX
字乘法 MUL BX DX:AX = AX × BX 被乘数在 AX,结果高位在 DX,低位在 AX
字节除法 DIV BL AL = AX / BL,AH = AX % BL 被除数在 AX,商在 AL,余数在 AH
字除法 DIV BX AX = DX:AX / BX,DX = DX:AX % BX 被除数在 DX:AX,商在 AX,余数在 DX

2.2 段寄存器

寄存器 全称 作用 默认使用场景
CS 代码段寄存器(Code Segment) 存放当前执行代码所在段的段地址 CPU 取指令时使用 CS:IP
DS 数据段寄存器(Data Segment) 存放程序数据所在段的段地址 访问数据时默认使用 DS 作为段地址
SS 栈段寄存器(Stack Segment) 存放栈所在段的段地址 PUSH/POP 操作使用 SS:SP
ES 附加段寄存器(Extra Segment) 存放附加数据段的段地址 串操作中目的串使用 ES:DI

注意: 段寄存器不能直接参与算术运算,必须通过通用寄存器中转。例如:

MOV AX, 1000H    ; 先将段地址送入 AX
MOV DS, AX       ; 再通过 AX 转送到 DS

2.3 控制寄存器

寄存器 全称 位数 作用
IP 指令指针寄存器(Instruction Pointer) 16 位 存放下一条要执行指令的偏移地址,与 CS 配合形成指令的物理地址
FLAGS 标志寄存器 16 位(使用 9 位) 存放运算结果的状态标志和控制标志

IP 的特殊性: IP 不能被直接读写(没有 MOV IP, AX 这样的指令),只能通过跳转指令(JMP、CALL、RET、LOOP 等)来改变其值。

2.4 标志寄存器(FLAGS)详细定义

FLAGS 寄存器中各标志位的位置(位编号从 0 开始):

位编号:  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
标志位:   -  -  -  -  OF DF IF TF SF ZF  - AF  - PF  - CF

2.4.1 状态标志位

标志位 名称 位置 为 1 时含义 为 0 时含义 设置条件
CF 进位标志(Carry Flag) 第 0 位 无符号运算产生进位/借位 无符号运算无进位/借位 最高位有进位或借位时置 1
PF 奇偶标志(Parity Flag) 第 2 位 结果低 8 位中 1 的个数为偶数 结果低 8 位中 1 的个数为奇数 根据结果低 8 位中 1 的个数设置
AF 辅助进位标志(Auxiliary Carry Flag) 第 4 位 低 4 位向高 4 位有进位/借位 低 4 位向高 4 位无进位/借位 第 3 位向第 4 位有进位或借位时置 1
ZF 零标志(Zero Flag) 第 6 位 运算结果为零 运算结果不为零 运算结果为全 0 时置 1
SF 符号标志(Sign Flag) 第 7 位 运算结果为负(最高位为 1) 运算结果为非负(最高位为 0) 等于结果的最高位
OF 溢出标志(Overflow Flag) 第 11 位 有符号运算产生溢出 有符号运算无溢出 有符号运算结果超出表示范围时置 1

2.4.2 控制标志位

标志位 名称 位置 为 1 时含义 为 0 时含义 用途
TF 陷阱标志(Trap Flag) 第 8 位 单步执行模式 正常执行模式 用于调试,每执行一条指令产生单步中断
IF 中断允许标志(Interrupt Flag) 第 9 位 允许可屏蔽中断 禁止可屏蔽中断 控制 CPU 是否响应外部可屏蔽中断请求
DF 方向标志(Direction Flag) 第 10 位 串操作地址递减(从高到低) 串操作地址递增(从低到高) 控制串操作指令中 SI/DI 的增减方向

2.4.3 OF 与 CF 的区别

对比项 CF(进位标志) OF(溢出标志)
适用对象 无符号数运算 有符号数运算
含义 最高位是否产生进位/借位 有符号数运算结果是否超出表示范围
字节运算溢出范围 无符号 0 ~ 255 有符号 -128 ~ +127
字运算溢出范围 无符号 0 ~ 65535 有符号 -32768 ~ +32767
典型使用场景 无符号数比较(JA/JB) 有符号数比较(JG/JL)

2.5 变址寄存器

寄存器 全称 默认段 用途
SI 源变址寄存器(Source Index) DS 串操作中作为源操作数的偏移地址;通用寻址中的变址寄存器
DI 目的变址寄存器(Destination Index) ES 串操作中作为目的操作数的偏移地址;通用寻址中的变址寄存器
BP 基址指针寄存器(Base Pointer) SS 通常用于访问栈段中的数据;访问函数参数和局部变量
SP 栈指针寄存器(Stack Pointer) SS 始终指向栈顶,与 SS 配合确定栈顶物理地址

2.6 寄存器总览

类别 寄存器 位数 可否直接赋值
通用寄存器 AX, BX, CX, DX 16 位 可以(MOV AX, 1234H)
通用寄存器(8位) AH, AL, BH, BL, CH, CL, DH, DL 8 位 可以(MOV AL, 45H)
变址/指针寄存器 SI, DI, BP, SP 16 位 可以(MOV SI, 1000H)
段寄存器 CS, DS, SS, ES 16 位 可以,但须通过通用寄存器中转
控制寄存器 IP 16 位 不可以,只能通过跳转指令修改
标志寄存器 FLAGS 16 位 不可以,由运算结果自动设置或通过专用指令修改

三、汇编指令

3.1 数据传送指令

指令 含义 作用 格式/用法示例 对标志位影响
MOV 传送(Move) 将源操作数的值复制到目的操作数 MOV AX, BX(寄存器间传送)
MOV AX, 1234H(立即数送寄存器)
MOV [BX], AX(寄存器送内存)
MOV AX, [BX](内存送寄存器)
不影响任何标志位
PUSH 入栈(Push) 将操作数压入栈中 PUSH AX(将 AX 压栈)
PUSH [BX](将内存字数据压栈)
不影响标志位
POP 出栈(Pop) 从栈中弹出数据到操作数 POP AX(弹出栈顶数据到 AX)
POP DS(弹出栈顶数据到 DS)
不影响标志位
XCHG 交换(Exchange) 交换两个操作数的值 XCHG AX, BX(交换 AX 和 BX)
XCHG AL, [BX](交换 AL 和内存字节)
不影响标志位
LEA 取有效地址(Load Effective Address) 将操作数的偏移地址送入寄存器 LEA AX, [BX+SI+08H](将有效地址送入 AX) 不影响标志位
LDS 加载 DS 和寄存器 从内存中取双字,低字送指定寄存器,高字送 DS LDS SI, [BX]([BX]低字→SI,[BX+2]高字→DS) 不影响标志位
LES 加载 ES 和寄存器 从内存中取双字,低字送指定寄存器,高字送 ES LES DI, [BX]([BX]低字→DI,[BX+2]高字→ES) 不影响标志位

MOV 指令的限制规则:

  • 不能在两个内存单元之间直接传送(MOV [SI], [DI] 是非法的)
  • 不能将立即数直接送入段寄存器(MOV DS, 1000H 是非法的)
  • 不能在两个段寄存器之间直接传送(MOV ES, DS 是非法的)
  • 源操作数和目的操作数的类型(字节/字)必须一致

3.2 算术运算指令

3.2.1 加法与减法

指令 含义 作用 格式/用法示例 对标志位影响
ADD 加法(Add) 将两个操作数相加,结果送目的操作数 ADD AX, BX(AX = AX + BX)
ADD AX, 1234H
影响 CF、ZF、SF、OF、PF、AF
ADC 带进位加法(Add with Carry) 两个操作数相加再加上 CF ADC AX, BX(AX = AX + BX + CF) 影响 CF、ZF、SF、OF、PF、AF
SUB 减法(Subtract) 目的操作数减去源操作数 SUB AX, BX(AX = AX - BX) 影响 CF、ZF、SF、OF、PF、AF
SBB 带借位减法(Subtract with Borrow) 目的操作数减去源操作数再减去 CF SBB AX, BX(AX = AX - BX - CF) 影响 CF、ZF、SF、OF、PF、AF
INC 加 1(Increment) 操作数加 1 INC AX(AX = AX + 1)
INC CX
影响 ZF、SF、OF、PF、AF,不影响 CF
DEC 减 1(Decrement) 操作数减 1 DEC AX(AX = AX - 1)
DEC BX
影响 ZF、SF、OF、PF、AF,不影响 CF
NEG 取补(Negate) 对操作数取补码(即取相反数) NEG AX(AX = -AX,等价于 0 - AX) 影响所有状态标志位
CMP 比较(Compare) 目的操作数减源操作数,但不保存结果,仅设置标志位 CMP AX, BX(计算 AX - BX,只设置标志位) 影响 CF、ZF、SF、OF、PF、AF

3.2.2 乘法

指令 含义 作用 格式/用法 隐含操作数 结果存放
MUL 无符号乘法 无符号数相乘 MUL BL 被乘数:AL AX = AL × BL
MUL 无符号乘法 无符号数相乘 MUL BX 被乘数:AX DX:AX = AX × BX
IMUL 有符号乘法 有符号数相乘 IMUL BL 被乘数:AL AX = AL × BL(有符号)
IMUL 有符号乘法 有符号数相乘 IMUL BX 被乘数:AX DX:AX = AX × BX(有符号)

乘法说明:

  • 字节乘:AL × 源操作数 → AX(结果 16 位)
  • 字乘:AX × 源操作数 → DX:AX(结果 32 位,DX 存高 16 位,AX 存低 16 位)
  • MUL 用于无符号数,IMUL 用于有符号数
  • 如果结果的高半部分(AH 或 DX)不为 0,则 CF = OF = 1

3.2.3 除法

指令 含义 作用 格式/用法 被除数 余数
DIV 无符号除法 无符号数相除 DIV BL AX(16 位被除数) AL(8 位商) AH(8 位余数)
DIV 无符号除法 无符号数相除 DIV BX DX:AX(32 位被除数) AX(16 位商) DX(16 位余数)
IDIV 有符号除法 有符号数相除 IDIV BL AX(有符号) AL AH
IDIV 有符号除法 有符号数相除 IDIV BX DX:AX(有符号) AX DX

除法说明:

  • 字节除:AX / 源操作数 → 商在 AL,余数在 AH
  • 字除:DX:AX / 源操作数 → 商在 AX,余数在 DX
  • 如果商超出寄存器能表示的范围,将触发除法溢出中断(中断 0)
  • DIV 用于无符号数,IDIV 用于有符号数

3.2.4 符号扩展指令

指令 含义 作用 说明
CBW 字节扩展为字(Convert Byte to Word) 将 AL 的符号位扩展到 AH AL 为正数时 AH = 00H;AL 为负数时 AH = FFH
CWD 字扩展为双字(Convert Word to Double Word) 将 AX 的符号位扩展到 DX AX 为正数时 DX = 0000H;AX 为负数时 DX = FFFFH

3.3 逻辑运算指令

指令 含义 作用 格式/用法示例 对标志位影响
AND 逻辑与 按位进行与运算 AND AX, 0FF0H(屏蔽 AX 低 4 位)
AND AL, 0DFH(将第 5 位清 0)
CF=0,OF=0,影响 ZF、SF、PF
OR 逻辑或 按位进行或运算 OR AX, 000FH(将 AX 低 4 位置 1)
OR AL, 20H(将第 5 位置 1)
CF=0,OF=0,影响 ZF、SF、PF
NOT 逻辑非 按位取反 NOT AX(AX 各位取反) 不影响任何标志位
XOR 逻辑异或 按位进行异或运算 XOR AX, AX(将 AX 清零)
XOR AL, 20H(翻转第 5 位)
CF=0,OF=0,影响 ZF、SF、PF
TEST 测试 按位进行与运算,但不保存结果,仅设置标志位 TEST AL, 01H(测试最低位是否为 1) CF=0,OF=0,影响 ZF、SF、PF

常用技巧:

操作 指令 说明
寄存器清零 XOR AX, AX 比 MOV AX, 0 更高效(指令更短)
屏蔽特定位 AND AL, 0F0H 保留高 4 位,低 4 位清零
设置特定位 OR AL, 01H 将最低位置 1
翻转特定位 XOR AL, 0FFH 将 AL 所有位翻转
测试特定位 TEST AL, 80H 测试最高位是否为 1(不改变 AL 的值)

3.4 移位与循环移位指令

3.4.1 移位指令

指令 含义 作用 格式/用法 对标志位影响
SHL 逻辑左移(Shift Left) 各位左移,低位补 0 SHL AX, 1(左移 1 位)
SHL AX, CL(左移 CL 位)
CF = 最后移出的位,影响 ZF、SF、PF、OF
SHR 逻辑右移(Shift Right) 各位右移,高位补 0 SHR AX, 1(右移 1 位) CF = 最后移出的位,影响 ZF、SF、PF、OF
SAL 算术左移(Shift Arithmetic Left) 与 SHL 相同,各位左移,低位补 0 SAL AX, 1 同 SHL
SAR 算术右移(Shift Arithmetic Right) 各位右移,高位补符号位(保持符号不变) SAR AX, 1(右移 1 位,符号位不变) CF = 最后移出的位,影响 ZF、SF、PF、OF

移位指令说明:

  • 移位 1 位时直接写 1(如 SHL AX, 1)
  • 移位多位时必须将移位次数放入 CL 寄存器(如 MOV CL, 4 然后 SHL AX, CL)
  • SHL 左移 1 位相当于无符号数乘以 2
  • SHR 右移 1 位相当于无符号数除以 2
  • SAR 右移 1 位相当于有符号数除以 2(保持符号)

3.4.2 循环移位指令

指令 含义 作用 格式/用法 对标志位影响
ROL 循环左移(Rotate Left) 各位左移,最高位移入最低位,同时移入 CF ROL AX, 1 CF = 最后移出的位(最高位),OF 在移 1 位时受影响
ROR 循环右移(Rotate Right) 各位右移,最低位移入最高位,同时移入 CF ROR AX, 1 CF = 最后移出的位(最低位),OF 在移 1 位时受影响
RCL 带进位循环左移(Rotate through Carry Left) 各位左移,CF 移入最低位,最高位移入 CF RCL AX, 1 CF = 最后移出的位(最高位)
RCR 带进位循环右移(Rotate through Carry Right) 各位右移,CF 移入最高位,最低位移入 CF RCR AX, 1 CF = 最后移出的位(最低位)

3.5 控制转移指令

3.5.1 无条件转移

指令 含义 作用 格式/用法 说明
JMP 无条件跳转(Jump) 无条件转移到目标地址执行 JMP label(段内直接跳转)
JMP AX(段内间接跳转)
JMP FAR PTR label(段间直接跳转)
修改 IP(段内)或 CS:IP(段间)

JMP 的跳转类型:

类型 格式 修改的寄存器 说明
段内直接跳转 JMP label IP 目标地址在编译时确定
段内间接跳转 JMP AX / JMP WORD PTR [BX] IP 目标地址在寄存器或内存中
段间直接跳转 JMP FAR PTR label CS 和 IP 跳转到另一个代码段
段间间接跳转 JMP DWORD PTR [BX] CS 和 IP 从内存取 32 位地址送入 CS:IP

3.5.2 条件转移指令

条件转移指令根据标志位的状态决定是否跳转,只能进行段内短转移(偏移范围 -128 ~ +127)。

基于单个标志位的条件转移:

指令 含义 转移条件 等价指令
JZ / JE 为零/相等则跳转(Jump if Zero/Equal) ZF = 1 JZ 和 JE 等价
JNZ / JNE 不为零/不相等则跳转(Jump if Not Zero/Not Equal) ZF = 0 JNZ 和 JNE 等价
JS 为负则跳转(Jump if Sign) SF = 1
JNS 为正则跳转(Jump if Not Sign) SF = 0
JO 溢出则跳转(Jump if Overflow) OF = 1
JNO 不溢出则跳转(Jump if Not Overflow) OF = 0
JP / JPE 偶校验则跳转(Jump if Parity/Parity Even) PF = 1 JP 和 JPE 等价
JNP / JPO 奇校验则跳转(Jump if Not Parity/Parity Odd) PF = 0 JNP 和 JPO 等价
JC 有进位则跳转(Jump if Carry) CF = 1 JB、JNAE
JNC 无进位则跳转(Jump if Not Carry) CF = 0 JNB、JAE

无符号数比较的条件转移(CMP 后使用):

指令 含义 转移条件 等价指令
JA 高于则跳转(Jump if Above) CF = 0 且 ZF = 0 JNBE
JAE 高于或等于则跳转(Jump if Above or Equal) CF = 0 JNB、JNC
JB 低于则跳转(Jump if Below) CF = 1 JNAE、JC
JBE 低于或等于则跳转(Jump if Below or Equal) CF = 1 或 ZF = 1 JNA

有符号数比较的条件转移(CMP 后使用):

指令 含义 转移条件 等价指令
JG 大于则跳转(Jump if Greater) ZF = 0 且 SF = OF JNLE
JGE 大于或等于则跳转(Jump if Greater or Equal) SF = OF JNL
JL 小于则跳转(Jump if Less) SF ≠ OF JNGE
JLE 小于或等于则跳转(Jump if Less or Equal) ZF = 1 或 SF ≠ OF JNG

CX 为零条件转移:

指令 含义 转移条件
JCXZ CX 为零则跳转(Jump if CX is Zero) CX = 0

3.5.3 循环指令

指令 含义 作用 格式/用法 说明
LOOP 循环(Loop) CX 减 1,若 CX ≠ 0 则跳转到目标标号 LOOP label 隐含使用 CX 作为计数器
LOOPE / LOOPZ 相等/为零时循环 CX 减 1,若 CX ≠ 0 且 ZF = 1 则跳转 LOOPE label 用于在循环中查找不匹配项
LOOPNE / LOOPNZ 不相等/不为零时循环 CX 减 1,若 CX ≠ 0 且 ZF = 0 则跳转 LOOPNE label 用于在循环中查找匹配项

LOOP 指令的执行过程:

  1. CX = CX - 1
  2. 若 CX ≠ 0,则 IP = IP + 位移量(跳转到标号处)
  3. 若 CX = 0,则顺序执行下一条指令

3.6 调用与返回指令

指令 含义 作用 格式/用法 说明
CALL 调用子程序(Call) 将返回地址(IP 或 CS:IP)压栈,然后跳转到子程序 CALL label(段内调用)
CALL FAR PTR label(段间调用)
段内调用压入 IP,段间调用压入 CS 和 IP
RET 返回(Return) 从栈中弹出返回地址,回到调用点 RET(段内返回)
RET n(段内返回并丢弃 n 字节参数)
段内返回弹出 IP,段间返回弹出 IP 和 CS
RETF 远返回(Return Far) 段间返回 RETF 从栈中弹出 IP 和 CS

CALL 与 RET 的配对使用:

调用方式 调用动作 返回指令 返回动作
段内调用 CALL label 压入 IP,跳转到目标地址 RET 弹出 IP,返回到调用点
段间调用 CALL FAR PTR label 压入 CS 和 IP,跳转到目标地址 RETF 弹出 IP 和 CS,返回到调用点

3.7 串操作指令

串操作指令用于对内存中的一批数据进行操作。SI 指向源串(默认 DS 段),DI 指向目的串(默认 ES 段)。DF 标志决定地址变化方向:DF=0 时地址递增,DF=1 时地址递减。

指令 含义 作用 格式 隐含操作数 对标志位影响
MOVSB 传送字节串(Move String Byte) 将 DS:[SI] 的字节传送到 ES:[DI],SI 和 DI 加/减 1 MOVSB DS:SI → ES:DI 不影响
MOVSW 传送字串(Move String Word) 将 DS:[SI] 的字传送到 ES:[DI],SI 和 DI 加/减 2 MOVSW DS:SI → ES:DI 不影响
STOSB 存字节串(Store String Byte) 将 AL 的内容存入 ES:[DI],DI 加/减 1 STOSB AL → ES:DI 不影响
STOSW 存字串(Store String Word) 将 AX 的内容存入 ES:[DI],DI 加/减 2 STOSW AX → ES:DI 不影响
LODSB 取字节串(Load String Byte) 将 DS:[SI] 的字节送入 AL,SI 加/减 1 LODSB DS:SI → AL 不影响
LODSW 取字串(Load String Word) 将 DS:[SI] 的字送入 AX,SI 加/减 2 LODSW DS:SI → AX 不影响
CMPSB 比较字节串(Compare String Byte) 比较 DS:[SI] 和 ES:[DI] 的字节,SI 和 DI 加/减 1 CMPSB DS:[SI] - ES:[DI] 影响 CF、ZF、SF、OF、PF、AF
CMPSW 比较字串(Compare String Word) 比较 DS:[SI] 和 ES:[DI] 的字,SI 和 DI 加/减 2 CMPSW DS:[SI] - ES:[DI] 影响 CF、ZF、SF、OF、PF、AF
SCASB 扫描字节串(Scan String Byte) 比较 AL 和 ES:[DI] 的字节,DI 加/减 1 SCASB AL - ES:[DI] 影响 CF、ZF、SF、OF、PF、AF
SCASW 扫描字串(Scan String Word) 比较 AX 和 ES:[DI] 的字,DI 加/减 2 SCASW AX - ES:[DI] 影响 CF、ZF、SF、OF、PF、AF

REP 前缀:

前缀 含义 作用 搭配指令 说明
REP 重复(Repeat) CX ≠ 0 时重复执行串操作,每次 CX 减 1 MOVSB/MOVSW、STOSB/STOSW 用于批量传送或填充
REPE / REPZ 相等时重复 CX ≠ 0 且 ZF = 1 时重复执行 CMPSB/CMPSW、SCASB/SCASW 查找第一个不匹配/不等的元素
REPNE / REPNZ 不相等时重复 CX ≠ 0 且 ZF = 0 时重复执行 CMPSB/CMPSW、SCASB/SCASW 查找第一个匹配/相等的元素

方向控制指令:

指令 含义 作用 说明
CLD 清方向标志(Clear Direction) DF = 0,串操作地址递增 SI/DI 每次加 1 或加 2
STD 置方向标志(Set Direction) DF = 1,串操作地址递减 SI/DI 每次减 1 或减 2

3.8 中断指令

指令 含义 作用 格式/用法 说明
INT 软中断(Interrupt) 引发指定类型的中断,调用中断处理程序 INT 10H(调用 BIOS 视频服务)
INT 21H(调用 DOS 系统服务)
压入 FLAGS、CS、IP,然后跳转到中断处理程序
IRET 中断返回(Interrupt Return) 从中断处理程序返回 IRET 弹出 IP、CS、FLAGS,返回到被中断的程序
INTO 溢出中断(Interrupt on Overflow) 若 OF = 1 则触发中断 4 INTO 常用于除法溢出检测

常用 BIOS 中断(INT 10H):

AH 值 功能 主要参数
02H 设置光标位置 BH = 页号,DH = 行号,DL = 列号
06H 屏幕窗口上滚 AL = 滚动行数,BH = 属性,CH/CL = 窗口左上角,DH/DL = 窗口右下角
09H 在光标处显示字符 AL = 字符,BH = 页号,BL = 属性,CX = 重复次数
0EH 以电传方式显示字符 AL = 字符,BL = 前景色

常用 DOS 中断(INT 21H):

AH 值 功能 主要参数 返回值
01H 从键盘输入一个字符并回显 AL = 输入字符的 ASCII 码
02H 输出一个字符到屏幕 DL = 要输出的字符
09H 输出字符串 DS:DX = 字符串首地址(以 $ 结尾)
4CH 程序终止返回 DOS AL = 返回码 无(程序结束)

3.9 输入/输出指令

指令 含义 作用 格式/用法 说明
IN 输入(Input) 从端口读取数据到 AL/AX IN AL, 60H(从端口 60H 读入一个字节到 AL)
IN AX, DX(从 DX 指定的端口读入一个字到 AX)
端口号 0255 可直接指定,25665535 须通过 DX
OUT 输出(Output) 将 AL/AX 的数据写入端口 OUT 60H, AL(将 AL 的内容写入端口 60H)
OUT DX, AX(将 AX 的内容写入 DX 指定的端口)
端口号 0255 可直接指定,25665535 须通过 DX

3.10 标志位操作指令

指令 含义 作用 说明
CLC 清进位标志(Clear Carry) CF = 0 在进行多精度运算前清除 CF
STC 置进位标志(Set Carry) CF = 1
CMC 进位标志取反(Complement Carry) CF = NOT CF
CLD 清方向标志(Clear Direction) DF = 0 串操作前通常执行,确保地址递增
STD 置方向标志(Set Direction) DF = 1 使串操作地址递减
CLI 清中断标志(Clear Interrupt) IF = 0 禁止可屏蔽中断
STI 置中断标志(Set Interrupt) IF = 1 允许可屏蔽中断
LAHF 标志送 AH(Load AH from Flags) AH = FLAGS 的低 8 位 将 SF、ZF、AF、PF、CF 送入 AH
SAHF AH 送标志(Store AH into Flags) FLAGS 的低 8 位 = AH 将 AH 的内容送入标志寄存器低 8 位
PUSHF 标志入栈(Push Flags) 将 FLAGS 压入栈中
POPF 标志出栈(Pop Flags) 从栈中弹出 FLAGS

3.11 其他常用指令

指令 含义 作用 格式/用法 说明
NOP 空操作(No Operation) 不执行任何操作,占用一个时钟周期 NOP 用于延时或指令对齐
HLT 停机(Halt) CPU 停止执行指令,等待中断 HLT 使 CPU 进入暂停状态
XLAT 查表转换(Translate) 用 AL 中的值作为偏移量,从表中取出对应字节送入 AL XLAT AL = DS:[BX + AL],常用于字符转换
AAA ASCII 加法调整 调整 AL 中的 ASCII 加法结果 AAA 用于 BCD/ASCII 加法运算后的调整
AAS ASCII 减法调整 调整 AL 中的 ASCII 减法结果 AAS 用于 BCD/ASCII 减法运算后的调整
DAA 压缩 BCD 加法调整 调整 AL 中的压缩 BCD 加法结果 DAA
DAS 压缩 BCD 减法调整 调整 AL 中的压缩 BCD 减法结果 DAS

3.12 伪指令

伪指令不是 CPU 指令,而是在汇编时指导汇编器如何处理源代码的指令。

伪指令 含义 作用 用法示例
DB 定义字节(Define Byte) 在内存中分配并初始化字节数据 DB 1, 2, 3, 'ABC'
DW 定义字(Define Word) 在内存中分配并初始化字数据 DW 1234H, 5678H
DD 定义双字(Define Double Word) 在内存中分配并初始化双字数据 DD 12345678H
DUP 重复(Duplicate) 与 DB/DW/DD 配合,批量定义数据 DB 100 DUP(0)(定义 100 个字节全为 0)
SEGMENT / ENDS 段定义 定义一个逻辑段的开始和结束 DATA SEGMENT ... DATA ENDS
ASSUME 段假定 告诉汇编器段寄存器与段的对应关系 ASSUME CS:CODE, DS:DATA
EQU 等值定义 定义一个常量符号 COUNT EQU 100
OFFSET 取偏移地址 获取变量或标号的偏移地址 MOV BX, OFFSET BUFFER
SEG 取段地址 获取变量或标号所在段的段地址 MOV AX, SEG BUFFER
PTR 类型指定(Pointer) 指定操作数的类型 MOV BYTE PTR [BX], 0FFH
PROC / ENDP 过程定义 定义一个子过程 SUB1 PROC ... SUB1 ENDP
END 源程序结束 标记源程序的结束,可指定程序入口 END START

附录:8086 指令编码参考

操作数大小指定

后缀 含义 对应大小 使用场景
BYTE PTR 字节操作 8 位(1 字节) MOV BYTE PTR [BX], 0FFH
WORD PTR 字操作 16 位(2 字节) MOV WORD PTR [BX], 1234H
DWORD PTR 双字操作 32 位(4 字节) MOV DWORD PTR [BX], 12345678H
FAR PTR 远转移/调用 段间转移 JMP FAR PTR label
NEAR PTR 近转移/调用 段内转移 JMP NEAR PTR label
SHORT 短转移 段内短转移(-128~+127) JMP SHORT label

[招生]科锐逆向工程师培训(2026年7月3日实地,远程教学同时开班, 第56期)!

收藏
免费 0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回