第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和IP

5. 段间间接转移

转移地址在数据存储器中占两个字:低字单元存放偏移地址,高字单元存放段基值。需加上类型说明 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 L8位位移量,-128~+127
段内直接转移(近)JMP NEAR PTR L16位位移量
段内寄存器间接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. 传送指令(数据传送类)
  2. 算术运算指令
  3. 逻辑运算和移位指令(运算类)
  4. 串操作指令
  5. 转移指令
  6. 处理器控制指令

五、传送指令

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。常用于查表转换。


六、串操作指令

串操作指令有三个共同特点:

  1. 以 DS:SI 指向源串,ES:DI 指向目的串
  2. 方向标志 DF 控制地址增减方向(DF=0 增量,DF=1 减量)
  3. 可加重复前缀 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           ; 重复传送
HLT

2. 串存储指令 STOS(写串)

将累加器 AL/AX 的内容传送至目的存储单元 ES:DI,自动修改 DI。

  • 加 REP 前缀可使一段内存单元填满相同值

3. 串装入指令 LODS(读串)

将源存储单元 DS:SI 的内容传送至累加器 AL/AX,自动修改 SI。

  • 一般不加重复前缀(累加器每次重写),常用在循环程序中

4. 串比较指令 CMPS / 串扫描指令 SCAS

(本章内容中提及,与串操作相关)


七、算术运算指令

1. 二进制加法和减法指令

名称格式操作影响标志
加法ADD DST, SRCDST ← DST + SRCOF, SF, ZF, AF, PF, CF
带进位加法ADC DST, SRCDST ← DST + SRC + CF同上
减法SUB DST, SRCDST ← DST - SRC同上
带借位减法SBB DST, SRCDST ← 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 LOOP1

2. 单操作数算术指令

名称格式操作标志
加1INC OPROPR ← OPR + 1OF, SF, ZF, AF, PF(不影响CF)
减1DEC OPROPR ← OPR - 1同上
求补NEG OPROPR ← -OPR(0 - OPR)全部标志
比较CMP OPR1, OPR2OPR1 - 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, BL2字节
ADD AX, BX2字节
ADD AX, [BX]2字节
ADD AX, [BX+10]3字节(8位位移量)
ADD AX, [BX+1000H]4字节(16位位移量)
ADD AX, 1000H3字节(立即数)
MOV [BX+SI+20H], 3000H6字节

十一、指令执行时间

指令执行时间用时钟周期数表示,与以下因素有关:

  1. 操作数在寄存器还是存储器
  2. 寻址方式(越复杂时间越长)
  3. 字操作的地址是偶地址还是奇地址(偶地址快,奇地址需两次访问)

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    ; 存最大值
    HLT

2. 字符串显示子程序

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计算时间 / 奇偶地址差异)

关联笔记