第8章 寻址方式与指令系统
课程:1A003 计算机组织与系统结构(第二部分) 来源:田浩然上传的资料/1A003 计算机组织与系统结构/第二部分/第8章 寻址方式与指令系统.ppt 文件大小:699 KB 格式:PowerPoint 97-2003 二进制格式(图片型PPT) 提取方式:二进制UTF-16LE流文本扫描,提取104段有效文本,覆盖完整章节结构 处理日期:2026-08-31 状态:partial_extraction
一、寻址方式概述
1. 定义
寻址方式:指令中如何提供操作数或操作数地址的方式,即规定如何对地址字段作出解释以找到操作数。
程序转移时需提供转移地址,这跟提供操作数地址在方法上没有本质区别,因此也归入寻址方式的范畴。
2. 寻址方式设计的关键地位
一个指令系统能够提供哪些寻址方式,能否为编制程序提供方便,这是指令系统设计的关键。
不同计算机系统中,寻址方式的名称和分类并不统一,但基本可以归结为以下几种方式或它们的变型或组合:
- 立即寻址(立即数寻址)
- 寄存器寻址
- 直接寻址
- 间接寻址
- 变址寻址
Z80系统的寻址方式举例:
- 立即寻址 / 立即扩展寻址
- 直接寻址 / 零页寻址
- 隐含寻址 / 相对寻址
- 寄存器寻址 / 寄存器间接寻址
- 位寻址 / 变址寻址
3. 两类寻址方式
- 数据的寻址方式(重点讨论)
- 转移地址的寻址方式
二、数据的寻址方式
1. 立即寻址(Immediate Addressing)
指令中直接给出操作数,操作数紧跟在操作码之后,作为指令的一部分存放在代码段里。取出指令的同时也就取出了操作数,立即有操作数可用。
MOV AX, 3064H ; 立即数 3064H 送入 AX
ADD AL, 20H ; 立即数 20H 加到 AL
ADD AX, 1090H ; 立即数 1090H 加到 AX要点:
- 立即数可以为8位,也可以为16位
- 16位数遵循”高位字节存放在高地址中,低位字节存放在低地址中”的小端规则
- 常用于给寄存器赋值
- 只能用于源操作数,不能用于目的操作数
错误示例:
MOV AL, 256 ; 256=100H,超过AL(8位)范围
MOV AX, -32769 ; 超过AX带符号数(补码)范围
MOV 100H, AL ; 立即数不能作为目的操作数
DEC 20 ; 单操作数指令不能使用立即数
MOV DS, 1234H ; 源操作数是立即数,则目的操作数就不能是段寄存器2. 寄存器寻址(Register Addressing)
操作数在寄存器中,指令中指明寄存器号。
- 8位操作数寄存器:AH, AL, BH, BL, CH, CL, DH, DL
- 16位操作数寄存器:AX, BX, CX, DX, SI, DI, SP, BP, CS, DS, ES, SS
- 注意:CS 不能作目的寄存器
特点:操作数在CPU内部,不需要访问存储器,执行速度快。
3. 直接寻址(Direct Addressing)
操作数的偏移地址(有效地址EA)直接包含在指令中,默认段寄存器为DS。
MOV AX, [2000H] ; 将 DS:2000H 单元的字送入 AX物理地址计算:物理地址 = DS × 16 + 偏移地址
段跨越前缀:可以通过段跨越前缀取得其他段中的数据。
MOV AX, ES:[2000H] ; 从附加段 ES 取数4. 寄存器间接寻址(Register Indirect Addressing)
操作数的有效地址在寄存器中(BX、BP、SI、DI 之一)。
MOV AX, [BX] ; 设 DS=2000H, BX=1000H
; 物理地址 = 20000H + 1000H = 21000H默认段寄存器规则:
- BX, SI, DI → 默认段寄存器 DS
- BP → 默认段寄存器 SS
也可使用段跨越前缀指定其他段。
5. 寄存器相对寻址(Register Relative Addressing)
操作数的有效地址是一个基址或变址寄存器的内容与指令中指定的8位或16位位移量(Displacement)之和。
EA = [BX/BP/SI/DI] + 8位/16位位移量
默认段寄存器:
- BX, SI, DI → DS
- BP → SS
6. 基址变址寻址(Based Indexed Addressing)
有效地址 = 基址寄存器(BX/BP之一)的内容 + 变址寄存器(SI/DI之一)的内容
EA = [BX/BP] + [SI/DI]
默认段寄存器:
- 含 BX → DS
- 含 BP → SS
7. 基址变址相对寻址(Relative Based Indexed Addressing)
有效地址 = 基址寄存器内容 + 变址寄存器内容 + 8位/16位位移量
EA = [BX/BP] + [SI/DI] + 8位/16位位移量
这是最灵活的寻址方式,适用于二维数组访问、结构体成员访问等场景。
三、转移地址的寻址方式
1. 基本概念
段内转移(近转移):转移地址与转移类指令在同一个代码段,只修改IP,CS不变。
段间转移(远转移):转移地址与转移类指令位于不同的代码段,同时修改CS和IP。
直接转移:转移地址直接放在指令中(绝对转移 / 相对转移)。
间接转移:转移地址间接放在寄存器或存储器中(寄存器寻址 / 存储器寻址)。
2. 段内直接转移
转移地址(近标号)直接包含在汇编形式的转移指令中。机器代码中存放的是标号与当前IP值的差(位移量),位移量与转移指令一起存于代码段。
IP + (标号 - IP) = 标号 = 转移地址
执行转移指令时,将位移量加到IP上即可,不必再访问寄存器或存储器。
段内直接短转移:
JMP SHORT OPR ; IP ← IP + 8位位移量 (-127~+128)段内直接近转移:
JMP NEAR PTR OPR ; IP ← IP + 16位位移量3. 段内间接转移
转移地址的偏移量在寄存器或内存单元中。
JMP AX ; 寄存器寻址,BX的内容为转移地址
JMP [BX] ; 寄存器间接寻址
JMP [BX+20] ; 寄存器相对寻址
JMP [BX+SI] ; 基址变址寻址
JMP [BX+SI+20] ; 基址变址相对寻址4. 段间直接转移
转移地址(远标号)直接包含在指令中,高字存段基值,低字存偏移地址。
JMP FAR PTR L ; 段间直接转移,同时修改CS和IP5. 段间间接转移
转移地址在数据存储器中占两个字:低字单元存放偏移地址,高字单元存放段基值。需加上类型说明 DWORD PTR。
JMP DWORD PTR DS:[20] ; 直接寻址
JMP DWORD PTR [BX] ; 寄存器间接寻址
JMP DWORD PTR [BX+20] ; 寄存器相对寻址
JMP DWORD PTR [BX+SI] ; 基址变址寻址
JMP DWORD PTR [BX+SI+20] ; 基址变址相对寻址6. JMP 指令寻址方式速查表
| 分类 | 寻址方式 | 示例 | 说明 |
|---|---|---|---|
| 段内 | 直接转移(短) | JMP SHORT L | 8位位移量,-128~+127 |
| 段内 | 直接转移(近) | JMP NEAR PTR L | 16位位移量 |
| 段内 | 寄存器间接 | JMP BX | 转移地址在寄存器 |
| 段内 | 存储器间接 | JMP WORD PTR [BX+SI+20] | 可使用除立即数外的各种存储器寻址 |
| 段间 | 直接转移 | JMP FAR PTR L | 直接给出CS:IP |
| 段间 | 存储器间接 | JMP DWORD PTR [DI] | 连续4字节单元存CS和IP |
四、8086/8088 指令系统分类
8086/8088 指令系统可分为六类(或四类):
- 传送指令(数据传送类)
- 算术运算指令
- 逻辑运算和移位指令(运算类)
- 串操作指令
- 转移指令
- 处理器控制指令
五、传送指令
1. 通用传送指令
MOV 指令
最基本的传送指令,将源操作数送到目的操作数。
PUSH / POP 指令(堆栈操作)
压入 PUSH SRC:
- 先修改指针:SP ← SP - 2
- 后压入:(SP+1, SP) ← SRC
弹出 POP DST:
- 先弹出:DST ← (SP+1, SP)
- 后修改指针:SP ← SP + 2
特点:堆栈向低地址方向生长;SP始终指向栈顶;SS为堆栈段寄存器。
示例:设 SS=1000H,SP=2000H,BX=1234H,则依次执行 PUSH AX、PUSH BX、POP CX 后:
- SS 不变(仍为 1000H)
- SP = 2000H - 4 + 2 = 1FFEH
- 栈顶物理地址 = 1000H×16 + 1FFEH = 11FFEH
- BX 不变(1234H)
- CX = 原 BX 的值(1234H)
XCHG 指令(交换指令)
XCHG OPR1, OPR2 ; OPR1 ←→ OPR2不影响任何标志位。
XCHG AL, BL ; 寄存器之间
XCHG BX, CX ; 寄存器之间
XCHG DS:[2530H], CX ; 寄存器与存储器2. 专用传送指令
LEA(Load Effective Address)
取有效地址,将存储器操作数的偏移地址送到指定寄存器。
LDS(Load pointer into register and DS)
装入远指针到寄存器和DS。
LES(Load pointer into register and ES)
装入远指针到寄存器和ES。
3. 输入输出指令
IN 指令(输入)
从数据端口输入数据或从状态端口输入状态字。
IN AL, 28H ; 直接端口寻址(8位端口地址)
IN AL, DX ; 间接端口寻址(DX存16位端口地址)查询式输入示例:
LOP: IN AL, 27H ; 读状态端口
TEST AL, 01H ; 测试就绪位
JNZ LOP ; 未就绪则等待
IN AL, 28H ; 就绪则读数据端口OUT 指令(输出)
输出数据或命令给指定的I/O端口。
OUT 80H, AL ; 直接端口寻址
OUT DX, AL ; 间接端口寻址4. 换码指令 XLAT
XLAT 或 XLATB将 BX 为首址、AL 为索引的表格元素送入 AL。常用于查表转换。
六、串操作指令
串操作指令有三个共同特点:
- 以 DS:SI 指向源串,ES:DI 指向目的串
- 方向标志 DF 控制地址增减方向(DF=0 增量,DF=1 减量)
- 可加重复前缀 REP / REPZ / REPNZ
1. 串传送指令 MOVS
MOVSB(字节传送):
- 将 DS:SI 的一个字节传送到 ES:DI
- DF=0: SI←SI+1, DI←DI+1
- DF=1: SI←SI-1, DI←DI-1
MOVSW(字传送):
- 将 DS:SI 的一个字传送到 ES:DI
- DF=0: SI←SI+2, DI←DI+2
- DF=1: SI←SI-2, DI←DI-2
程序示例:将内存1000H开始的100个字节数据向高地址方向移动一个字节
MOV AX, DS
MOV ES, AX ; 使ES=DS
MOV SI, 1063H ; 源地址(从最后一个字节开始)
MOV DI, 1064H ; 目的地址(高一个字节)
MOV CX, 64H ; 100个字节
STD ; 方向标志置1(地址减量)
REP MOVSB ; 重复传送
HLT2. 串存储指令 STOS(写串)
将累加器 AL/AX 的内容传送至目的存储单元 ES:DI,自动修改 DI。
- 加 REP 前缀可使一段内存单元填满相同值
3. 串装入指令 LODS(读串)
将源存储单元 DS:SI 的内容传送至累加器 AL/AX,自动修改 SI。
- 一般不加重复前缀(累加器每次重写),常用在循环程序中
4. 串比较指令 CMPS / 串扫描指令 SCAS
(本章内容中提及,与串操作相关)
七、算术运算指令
1. 二进制加法和减法指令
| 名称 | 格式 | 操作 | 影响标志 |
|---|---|---|---|
| 加法 | ADD DST, SRC | DST ← DST + SRC | OF, SF, ZF, AF, PF, CF |
| 带进位加法 | ADC DST, SRC | DST ← DST + SRC + CF | 同上 |
| 减法 | SUB DST, SRC | DST ← DST - SRC | 同上 |
| 带借位减法 | SBB DST, SRC | DST ← DST - SRC - CF | 同上 |
标志寄存器(9个标志位):
- O(溢出)、D(方向)、I(中断允许)、T(陷阱)
- S(符号)、Z(零)、A(辅助进位)、P(奇偶)、C(进位)
多倍精度运算
双字(32位)加法示例:
MOV SI, 2000H ; 第一个数首地址
MOV AX, [SI] ; 低16位送AX
MOV DI, 3000H ; 第二个数首地址
ADD AX, [DI] ; 低16位相加(影响CF)
MOV [SI], AX ; 存低16位结果
MOV AX, [SI+2] ; 高16位
ADC AX, [DI+2] ; 高16位相加 + CF
MOV [SI+2], AX ; 存高16位结果多字加法通用程序(循环):
MOV CL, DS:[2500H] ; 字长度
MOV SI, 2000H
MOV DI, 3000H
CLC ; 清进位
LOOP1:
MOV AX, [SI]
ADC AX, [DI]
MOV [SI], AX
INC SI
INC SI
INC DI
INC DI
DEC CL
JNZ LOOP12. 单操作数算术指令
| 名称 | 格式 | 操作 | 标志 |
|---|---|---|---|
| 加1 | INC OPR | OPR ← OPR + 1 | OF, SF, ZF, AF, PF(不影响CF) |
| 减1 | DEC OPR | OPR ← OPR - 1 | 同上 |
| 求补 | NEG OPR | OPR ← -OPR(0 - OPR) | 全部标志 |
| 比较 | CMP OPR1, OPR2 | OPR1 - OPR2(不回送结果,只置标志) | 全部标志 |
NEG 求补指令:把操作数当成带符号数,正数变负数(补码),负数变正数。方法是”各位包括符号位求反,末位加1”。
若 AL = 00010001B = +17,执行 NEG AL 后:
AL = 11101111B = [-17]补
若 AL = 11010001B = [-47]补,执行 NEG AL 后:
AL = 00101111B = +47
CMP 比较指令:做减法但不回送结果,只根据结果置标志。通常安排在条件转移指令之前。
3. 乘法指令
无符号乘法 MUL SRC:
- 字节操作:AX ← AL × SRC
- 字操作:DX:AX ← AX × SRC
带符号乘法 IMUL SRC:
- 操作同MUL,但操作数和乘积均为带符号数(补码表示),符合代数符号规则
4. 除法指令
无符号除法 DIV SRC:
- 字节除数:AL ← (AX) / (SRC) 之商;AH ← 余数
- 字除数:AX ← (DX:AX) / (SRC) 之商;DX ← 余数
带符号除法 IDIV SRC:
- 操作同DIV,但商和余数是带符号的
- 商的符号符合一般代数符号规则
- 余数的符号与被除数相同
综合例题:计算 (V - (X*Y + Z - 540)) / X,商送AX,余数送DX(X、Y、Z、V均为字变量)。
5. BCD 数运算调整指令
DAA(Decimal Adjust for Addition)— 加法的十进制调整
BCD加法后,如果低4位大于9或AF=1,则AL加06H;如果高4位大于9或CF=1,则AL加60H。
原理:二进制加法是”满16进1”,但十进制是”满10进1”,所以差了6,需要加6调整。
例:19 + 8 = 27
0001 1001 (19)
+ 0000 1000 ( 8)
-----------
0010 0001 (21) ← 结果不对,低4位进位后变成了1而不是10
低位向高位产生了进位,但"满16进一"实际应该"满10进1",少了6
+ 0000 0110 (加6调整)
-----------
0010 0111 (27) ← 正确结果
DAS(Decimal Adjust for Subtraction)— 减法的十进制调整
减法的十进制调整,类似原理。
AAA / AAS / AAM / AAD(非组合BCD调整)
- AAA:加法的ASCII调整
- AAS:减法的ASCII调整
- AAM:乘法的ASCII调整
- AAD:除法的ASCII调整
BCD转换编程示例:将从UNPACKED开始的16位分离BCD数转换成组合BCD数,结果存PACKED开始的单元。
MOV DX, 8 ; 循环次数
MOV CL, 4 ; 移位次数
MOV SI, 0
MOV DI, SI
CONVERT:
MOV AX, [SI+UNPACKED]
SHL AL, CL ; 左移4位,低字节变高4位
SHR AX, CL ; 整个AX右移4位,AH低4位移入AL高4位
MOV [DI+PACKED], AL
INC SI
INC SI
INC DI
DEC DX
JNZ CONVERT八、逻辑运算和移位指令
1. 逻辑运算指令
- NOT(非)、AND(与)、OR(或)、XOR(异或)、TEST(测试)
- 主要影响 SF, ZF, PF 标志
2. 移位指令
- 算术移位:SAL(算术左移)、SAR(算术右移)
- 逻辑移位:SHL(逻辑左移)、SHR(逻辑右移)
- 循环移位:ROL、ROR、RCL、RCR
移位次数可以是1或CL寄存器的值。
九、转移指令
1. 无条件转移指令 JMP
详见前述”转移地址的寻址方式”。
2. 条件转移指令
根据标志位状态决定是否转移。全部为段内短转移(8位位移量)。
按标志分类:
- JC / JNC:CF=1 / CF=0 转移
- JZ/JE / JNZ/JNE:ZF=1 / ZF=0 转移
- JS / JNS:SF=1 / SF=0 转移
- JO / JNO:OF=1 / OF=0 转移
- JP/JPE / JNP/JPO:PF=1 / PF=0 转移
按带符号数比较:
- JG / JNLE:大于则转移(大于 = 不小于等于)
- JGE / JNL:大于等于则转移
- JL / JNGE:小于则转移
- JLE / JNG:小于等于则转移
按无符号数比较:
- JA / JNBE:高于则转移
- JAE / JNB:高于等于则转移
- JB / JNAE:低于则转移
- JBE / JNA:低于等于则转移
条件转移程序示例:
; 如果 X > 50,转向 TOO-HIGH
; 如果 X-Y 溢出,转向 OVERFLOW
; 否则计算 X-Y,结果存 RESULT
MOV AX, X
CMP AX, 50
JG TOO_HIGH ; X > 50 转
SUB AX, Y
JO OVERFLOW ; 溢出转
MOV RESULT, AX
JMP DONE
TOO_HIGH:
...
OVERFLOW:
...
DONE:
...3. 循环控制指令
- LOOP:CX-1,不为0则循环
- LOOPZ/LOOPE:CX-1,不为0且ZF=1则循环
- LOOPNZ/LOOPNE:CX-1,不为0且ZF=0则循环
- JCXZ:CX=0则转移
4. 过程调用和返回
- CALL:调用子程序(段内/段间,直接/间接)
- RET:从子程序返回(段内/段间,可选弹出参数)
5. 中断及中断返回指令
- INT n:软中断
- INTO:溢出中断
- IRET:中断返回
十、指令编码格式
8086 指令为变字长指令,长度1~6字节。
基本格式
| 操作码字节 | 寻址方式字节(可选) | 位移量(可选) | 立即数(可选) |
| 1字节 | 1字节 | 0/1/2字节 | 0/1/2字节 |
寻址方式字节(ModR/M)
-
mod 域(2位):寻址方式
- 00:无位移量([BX+SI] 等)
- 01:8位位移量
- 10:16位位移量
- 11:寄存器寻址
-
reg 域(3位):寄存器编码
- 000=AX/AL, 001=CX/CL, 010=DX/DL, 011=BX/BL
- 100=SP/AH, 101=BP/CH, 110=SI/DH, 111=DI/BH
- 由操作码字节的W位决定是8位还是16位
-
r/m 域(3位):寄存器/存储器编码
- 000=[BX+SI], 001=[BX+DI], 010=[BP+SI], 011=[BP+DI]
- 100=[SI], 101=[DI], 110=[BP](mod=00时为直接寻址), 111=[BX]
指令长度示例
| 指令 | 长度 |
|---|---|
ADD AL, BL | 2字节 |
ADD AX, BX | 2字节 |
ADD AX, [BX] | 2字节 |
ADD AX, [BX+10] | 3字节(8位位移量) |
ADD AX, [BX+1000H] | 4字节(16位位移量) |
ADD AX, 1000H | 3字节(立即数) |
MOV [BX+SI+20H], 3000H | 6字节 |
十一、指令执行时间
指令执行时间用时钟周期数表示,与以下因素有关:
- 操作数在寄存器还是存储器
- 寻址方式(越复杂时间越长)
- 字操作的地址是偶地址还是奇地址(偶地址快,奇地址需两次访问)
ADD 指令执行时间举例(5MHz 8086):
| 操作数位置 | 时钟周期 |
|---|---|
| 寄存器到寄存器 | 3 |
| 内存偶地址字到寄存器([BP+SI]) | 7+EA |
| 内存奇地址字到寄存器 | 8+EA |
EA = 有效地址计算时间(时钟周期):
- 直接寻址:6
- [BX/SI/DI]、[BP]:5
- 位移量 + 基址/变址:9
- 基址变址:7~8
- 基址变址相对:11~12
十二、典型程序设计举例
1. 找最大数
在内存2000H开始处存放100个字节无符号数据,找出最大的一个,存放到3000H字节单元中。
MOV BX, 2000H ; 数据首址
MOV CX, 99 ; 比较次数(100个数比较99次)
MOV AL, [BX] ; 取第一个数为初始最大值
P1: INC BX
CMP AL, [BX] ; 与下一个数比较
JNC P2 ; AL >= [BX],不换
MOV AL, [BX] ; 否则换最大值
P2: DEC CX
JNZ P1 ; 未完继续
MOV [3000H], AL ; 存最大值
HLT2. 字符串显示子程序
DISPLAY PROC
PUSH BP
MOV BP, SP
PUSH ES
PUSH DI
LES DI, [BP+04] ; 字符串首址送ES:DI
AAA:
ES:MOV AL, [DI] ; 取字符
CMP AL, 00 ; 判结束符
JZ EEE
PUSH AX ; 字符入栈
CALL PUTCHAR ; 调显示字符
POP AX
INC DI
JMP AAA
EEE:
POP DI
POP ES
POP BP
RET 2
DISPLAY ENDP十三、章节关系图
8.1 8086/8088寻址方式与指令系统
├── 8.1.1 寻址方式
│ ├── 概述(定义/分类/重要性)
│ ├── 数据寻址方式(7种:立即/寄存器/直接/寄存器间接/寄存器相对/基址变址/基址变址相对)
│ └── 转移地址寻址方式(段内/段间 × 直接/间接)
│
├── 8.1.2 指令系统
│ ├── 传送指令(MOV/PUSH/POP/XCHG/LEA/LDS/LES/IN/OUT/XLAT)
│ ├── 算术运算指令(ADD/ADC/SUB/SBB/INC/DEC/NEG/CMP/MUL/IMUL/DIV/IDIV/DAA/DAS/AAA/AAS/AAM/AAD)
│ ├── 逻辑运算和移位指令(NOT/AND/OR/XOR/TEST + SAL/SAR/SHL/SHR/ROL/ROR/RCL/RCR)
│ ├── 串操作指令(MOVS/STOS/LODS/CMPS/SCAS + REP/REPZ/REPNZ)
│ ├── 转移指令(JMP/条件转移/LOOP/CALL/RET/INT/IRET)
│ └── 处理器控制指令(CLC/STC/CMC/CLD/STD/CLI/STI/NOP/HLT/WAIT/ESC/LOCK)
│
├── 指令编码格式(操作码 + ModR/M + 位移量 + 立即数)
└── 指令执行时间(时钟周期 / EA计算时间 / 奇偶地址差异)
关联笔记
- 计算机组成-第5章-计算机微型计算机的组成及工作过程(第5章,计算机组成基础,冯·诺依曼架构/三总线/指令执行过程)
- 汇编语言的基本语法-第7章-计算机组织与系统结构(第7章,汇编语言基础,与本章指令系统紧密衔接)
- 结构化计算机组成-第6版-Tanenbaum(books/,更深入的计算机组成教材,第4章指令集体系结构)
- 边干边学-LINUX内核指导-李善平-陈文智(books/,Linux 2.4内核,实际系统中的寻址方式与指令应用)
- Linux内核完全注释-赵炯-Linux-0.11内核源码详解(books/,Linux 0.11内核完全注释,80x86保护模式寻址)