指令系统与寻址方式
1. 课程说明
本课程基于《汇编语言(第 2 版)》郑晓薇 编著,机械工业出版社,可以配合该教材使用。本课程由郑晓薇授权制作,提取教材中的实例以及实验内容,可以在实验楼环境中完成所有实例及实验。实验课程制作符合教材原版实例驱动教学以及实验训练贯穿始终的特点。
本教材可在 当当网 购买(点击链接即可进入购买页面)。
本课程实验列表中的最后模块为配套教材的习题参考答案,可供读者学习参考。
2. 实验环境
DOS 环境:
实验环境中安装有 dosemu
可以模拟 DOS 环境,并提供 DEBUG
、MASM
、LINK
等汇编语言开发程序。
3. 指令的寻址方式
本实验的理论知识摘选自 《汇编语言(第 2 版)》(郑晓薇 编著,机械工业出版社)中的第 3 章——指令系统与寻址方式,感兴趣或者想要了解更多相关知识的同学可以阅读此书。
3.1 寻址方式
汇编指令由 操作码字段
和 操作数字段
构成。对于双操作指令,第一个操作数称为目的操作数,表示操作后的结果;第二个操作数称为源操作数,表示来源操作数。两者以逗号分隔。如:

所谓寻址方式,即指令中提供操作数或操作数地址的方式。通俗地说就是寻找操作数地址的方法。寻址方式的数量代表了微机系统对存储器管理能力的强弱,合理地使用寻址方式可以扩大访存空间,缩短指令长度,满足各种程序设计需要。
与数据有关的寻址方式划分为三类:立即寻址方式,寄存器寻址方式,存储器寻址方式。
3.2 七种与数据有关的寻址方式
要求掌握下列七种与数据有关的寻址方式。其中后五种属于存储器寻址方式。
- 立即寻址方式(Immediate addressing)
- 寄存器寻址方式(Register addressing)
- 直接寻址方式(Direct addressing)
- 寄存器间接寻址方式(Register indirect addressing)
- 寄存器相对寻址方式(Register relative addressing)
- 基址变址寻址方式(Based indexed addressing)
- 相对基址变址寻址方式(Relative based indexed addressing)
我们看到,常用的寻址方式有 7 种之多,到底选择哪一种为好呢?选择寻址方式有两条原则:第一实用,第二有效。最终都应达到运行速度快、指令代码短的高效率目标程序的目的。立即寻址和寄存器寻址无论从指令长度和指令执行时间都比存储器寻址要好,但是也要根据具体情况选用。
学会使用寻址方式是理解指令作用的关键,也是掌握程序设计技巧的一种途径。
3.2.1 立即寻址方式
所要找的操作数直接写在指令中,这种操作数叫立即数。在 8086、80286 中立即数是 8 位或 16 位的,在 80386 以上可以是 32 位的立即数。立即寻址方式用来表示常数。

在 DEBUG 下数据都是十六进制表示的,因此不需要用 H 标注,同时要把十进制变为十六进制才行。
在 DEBUG 下执行:
-A MOV AX,3060 MOV AL,5 MOV BL,FF MOV BX,A46D MOV CX,17
接着用 T 命令单步执行,观察各寄存器的值。
注意:
执行 T 命令之前,指令指针寄存器 IP 的值要用 R IP 修改成第一条指令的偏移地址,这样 T 命令才能从第一条指令开始执行。

3.2.2 寄存器寻址方式
在寄存器寻址方式中,操作数在寄存器中,在指令中指定寄存器名即可。

在 DEBUG 下执行:
-A MOV AX,0 MOV BX,1234 MOV AX,BX MOV CL,AH MOV AX,4650
接着用 T 命令单步执行,观察各寄存器的值。要注意指令指针 IP 的值是否指向了要执行的指令。

3.2.3 直接寻址方式
操作数存放在内存中。操作数的偏移地址(也称为有效地址 EA)直接写在指令中。
(1)存储器读操作
MOV 指令可以实现 CPU 对存储器的读写。若传送指令的目的操作数是 CPU 的寄存器,源操作数是存储单元,就完成了对存储器的读操作。
例如:MOV AX,DS:[2000H]
表示该指令表示从数据段的 2000H 单元读出一个字送入 AX。
(2)存储器写操作
如果要实现 CPU 写内存操作,只要把 MOV 指令的目的操作数变为存储单元,源操作数为 CPU 的寄存器即可。
例如:MOV DS:[4000H],AX
将 AX 的值写入数据段的 4000H 单元。
在 DEBUG 下执行:
-A MOV AX,DS:[2000] MOV DS:[4000],AX
接着用 T 命令单步执行,观察 AX 寄存器的值;用 D DS:2000
和 D DS:4000
命令观察这两个存储单元的值。
3.2.4 寄存器间接寻址方式
操作数存放在内存中。
指令形式如:
MOV AX,[BX]
操作数的 EA 在基址寄存器 BX、BP 或变址寄存器 SI、DI 中,而操作数的段地址在数据段 DS 或堆栈段 SS 中。如果有效地址由 BX、SI、DI 指出,则默认为对应于数据段,而用 BP 指出则对应于堆栈段。

思考一下,在 DEBUG 下执行时,如果按照上例给出的数据段地址和 BX 值来执行,如何实现呢?执行后怎样看到 AX=2364H?
-R DS 1500 -E DS:4580 64 23 -D DS:4580 -A MOV BX,4580 MOV AX,[BX]
接着用 T 命令单步执行,观察 AX 寄存器的值。
**注意
**:指令指针 IP 的值是否指向了要执行的指令?
3.2.5 寄存器相对寻址方式
操作数存放在内存中。
指令形式如:
MOV AX,[BX+1200H]
操作数的 EA 是一个基址或变址寄存器的内容再加上 8 位或 16 位位移量之和。也就是说在寄存器间接寻址的基础上,增加一个相对量(位移量)。这个位移量可以是立即数,也可以是符号地址。

思考一下,如果按照上例给出的参数来执行,在 DEBUG 下执行时如何修改指令呢?执行后怎样看到 AX=2428H?
提示:符号地址 TOP 直接用 25H 表示。
-R DS 1500 -E DS:7335 28 24 -D DS:7335 -A MOV SI,7310 MOV AX,25[SI]
接着用 T 命令单步执行,观察 AX 寄存器的值。
**注意
**:执行 T 命令之前,指令指针寄存器 IP 的值要用 R IP 修改成第一条指令的偏移地址。
3.2.6 基址变址寻址方式
操作数存放在内存中。
指令形式如:
MOV AX,[BX+SI]
操作数的 EA 为一个基址寄存器和一个变址寄存器的内容之和。
3.2.7 相对基址变址寻址方式
操作数存放在内存中。
指令形式如:
MOV AX,[BX+SI+1200H]
操作数的 EA 为一个基址寄存器加一个变址寄存器再加一个位移量,三者之和。可用于二维表查表和栈处理。
**自己做
**:自定各个寄存器的参数,在 DEBUG 下执行指令后得到 AX=3568H。
4. 寻找操作数
本节实验取自教材中第三章的《实例三 寻找操作数》。
4.1 实验示例
根据题目要求,写出相应的汇编指令:
- AX、BX 寄存器分别赋值为
0008H
和0006H
- AX 和 BX 的内容相加,结果在 AX 中
- 用寄存器间接寻址将相加的结果保存到 6 号单元,指令如下:
MOV AX,0008H MOV BX,0006H ADD AX,BX MOV [BX],AX HLT ;停机指令
在 DEBUG 下,用 A 命令输入上述四条指令,再用 R 命令显示寄存器的情况:

用 T 命令单步执行(注意:第一条指令的偏移地址是 0100,IP 寄存器的值也应是 0100);用 D 命令观察结果:

实验结果分析如下:
- 执行两次 T 命令后,
AX=0008H
,BX=0006H
。 - 执行加法命令后,
AX=000EH
;相应的标志位:进位标志 NC,即CF=0
;符号标志 PL,即SF=0
;零标志 NZ,即ZF=0
;溢出标志 NV,即OF=0
;表示运算结果无进位、不溢出、结果不为 0、结果是正数。 - [BX] 寄存器间接寻址方式对应的存储单元为 6 号,逻辑地址为
DS:0006
,该单元原来的值为FEEEH
。 - 执行完
MOV [BX],AX
指令后,DS:0006
单元中的内容变为000EH
了(用 D DS: 6 命令查看 DS 段的 6 号和 7 号单元)。
4.2 实验任务
实验目的
通过实验观察和分析在不同的寻址方式下存储单元逻辑地址的表示以及指令的执行结果。熟练掌握 DEBUG 的 R 命令、A 命令、T 命令和 D 命令的用法。
实验内容
参考示例一和各种寻址方式完成下列实验内容:
(1)两个操作数相减运算,结果放在数据段的 16 号单元
- AX、BX 寄存器分别赋值为
0008H
和0010H
; - AX 和 BX 的内容相减(SUB 指令),结果在 AX 中;
- 用直接寻址方式将相减的结果保存到 16 号单元。
(2)两个操作数相加运算,结果放在附加段的 0020H
号单元
- AX 的值为
0034H
; - AX 和 65 相加,结果在 AX 中;
- 用寄存器间接寻址方式(段超越)保存运算结果。(3)将 AX 寄存器中的 1234H 写入数据段的 2 号单元,读出 3 号单元的 12H 传送给 BL 寄存器(寻址方式自定)
实验要求
- 写出相关命令及操作步骤
- 实验内容用截图形式记录实验结果
- 写出实验结果分析。
**提示
**:减法的结果以补码形式表示,对应的真值为负数。标志位发生了改变。
实验拓展
- 根据自己的理解和偏好,设计并完成其他寻址方式的指令。
- 这些实验对你有何启发?