汇编语言
一、 选择题(5X2’=10’)
二、 填空题(6X2’=12’)
三、 简答题(4X7’=28’)
- 有哪几种寄存器名
四、 程序分析与填空题(4X7’=28’)
- 给一个程序段,填程序空缺
- 简单题类似p22页 习题2.3
- 做好课后习题
五、 程序设计题(2X7’=14’)
六、 论述题(1X8’=8’)
- 开放性
搞熟例题和习题
第一章
论述题为什么要学汇编语言
进制转换
补码
第二章
- 背寄存器有哪些2.3
- 简单题类似习题2.3
- 习题2.5不会考这么难的题
第三章
- p31 例3.1 3.2 p42 表3-1(输出字符,缓冲区)
- 熟悉汇编语言工作环境,编译过程步骤
- 程序跟踪调试
- 功能调用命令 36页 37页填空题,用了哪些命令
- DOS命令
第四章(重点)
- 几种寻址方式(填空选择)
- 框图
第五章
- 熟悉指令 : 常用的加法、减法
- 69页类型扩展 70页 例5.17/5.18
- BCD码命令
- 85页-87 例5.39 5.40搞清楚程序设计需要哪几部分
- 数据段,代码段定义。主程序,关联
- 就算主程序写不出来,也要把常规步骤写出来
- 程序设计涉及到程序转移指令
- 跳转
- 习题 5.9 5.5 5.17 5.19 5.20
- p78 例题5.29综合性例题
第六章伪指令
- 宏指令不考
- 清楚指令和伪指令的定义和应用场景
- 伪指令的定义方法和格式
- p103 ~ p107 所有例体
- (ORZ /$)包括操作符
- p107页 例题6.9根据 程序画图例
- 习题6.1 6.7
第七章分支循环
- 例题7.2 7.3
- 分支向量表概念
- 循环没时间可以不看
- 习题7.1 7.2 7.6
第八章
- 8.1 p136 过程定义与过程结构
第一章
1.计算机中数据的表示
1.1 不同进制
进制 | 代表 |
---|---|
二进制 | B |
八进制 | O |
十进制 | D |
十六进制 | H |
1.2 进制转换
十六进制转十进制
$$
5FH = 516^1+1516^0 = 95D
$$
二进制转十进制
$$
101101.1B = 12^5+12^3+12^2+12^0+1*2^{-1} = 45.5D
$$
十进制转二进制
8 4 2 1 法凑数
1.3 带符号数的补码表示
负数用补码表示
方法:
- 对正数各位取反,最低位加1
$$
求[-3]_补
$$
1 |
|
补码的加减法
- 加法
$$
[X+Y]_补 = [X]_补 + [Y]_补
$$
- 减法
$$
[X-Y]_补 = [X]_补 + [-Y]_补
$$
1.4 无符号数
数值范围
8位二进制表示无符号数
$$
0 <= N <= 255
$$
16位二进制表示无符号数
$$
0 <= N <= 65525
$$
2.习题
- 什么是机器语言:机器语言就是用二进制编码组成的机器指令的集合和一组使用机器指令的规则。
- 什么是汇编语言:汇编语言是对机器指令中的操作码用英文单词的缩写描述,对操作数用标号、变量、常量描述。
- 汇编语言的特点:
- 与机器有关:移植性差,但可直接控制硬件。
- 程序效率高。
- 局限性:受指令的限制,如考虑存储单元等。
- 调试困难。
- 汇编程序与汇编源程序的区别是什么:汇编源程序是指用汇编语言编写的程序,而汇编程序特指将汇编源程序汇编成目标文件的编译程序。
第二章
1. 存储器
1.1 16位CPU
8086是16位结构的CPU ,16位结构的CPU结构特征
(1) 数据总线为16位
(2) 运算器一次最多可以处理16位的数据
(3) 寄存器的最大宽度位16位
(4) 寄存器和运算器之间的通路为16位
1.2 存储单位
1 |
|
2. 寄存器
记住就完了
8086CPU所有寄存器都是16位,可以存放两个字节(一个字)
通用寄存器
- AX:累加器。16位可分为AH高8位和AL低8位。
- BX:基址寄存器,存放数据和内存的起始偏移地址。BH、BL
- CX:计数寄存器,存放数据和存放重复操作的次数。CH、CL
- DX:数据寄存器,存放数据和存放32位数据的高16位。DH、DL
地址寄存器
- SP:堆栈指针,存放堆栈栈顶的偏移地址。
- BP:基址指针,存放内存中数据的偏移地址。
- SI:源变址寄存器,存放内存中源数据区的偏移地址;指在某些指令作用下它可以自动地递增或递减其中的值。
- DI:目的变址寄存器,存放内存中目的数据区的偏移地址,并在某些指令作用下自动地递增或递减其中的值。
段寄存器
$$
物理地址 = 段地址 * 16 + 偏移地址
$$
- 分段方式中, 内存并没有分段 , 段的划分来自于CPU
- 段地址和偏移地址都是16位二进制数
- 段地址 * 16相当于二进制向左移动四位
1 |
|
CS:代码段寄存器,存放当前正在执行的程序段的段基址。
- 在编写汇编程序时,必须要有代码段
SS:堆栈段寄存器,存放堆栈段的段基址。
DS:数据段寄存器,存放数据段的段基址。
ES:附加段寄存器,存放另一个数据段的段基址。
指令指针寄存器
IP:指令指针寄存器,存放即将执行指令的偏移地址。
标志寄存器
- FLAGS:存放CPU的两类状态。
- 状态标志:CF(进位)、PF(奇偶)、AF(辅助进位)、ZF(零)、SF(符号)和OF(溢出)
- 控制标志:TF、IF(中断)和DF(方向)
标志名(加粗重点) | 标志为1 | 标志为0 |
---|---|---|
OF 溢出(是/否) | OV | NV |
DF 方向(减/增) | DN | UP |
IF 中断(允许/不允许) | EI | DI |
SF 符号(负/正) | NG | PL |
ZF 零 (是/否) | ZR | NZ |
AF 辅助进位(有/无) | AC | NA |
PF 奇偶(偶/奇) | PE | PO |
CF 进位(有/无) | CY | NC |
OF:溢出标志。
对有符号数有效 (只有正数与正数相加、负数与负数相加才有可能溢出)
- OF=1表示有两个有符号数的运算结果超出了可以表示的范围,结果是错误的;
- OF=0表示没有溢出,结果正确。
- 进行无符号数运算时也会产生新的OF标志(CPU不知道处理对象是否为有符号数),此时程序员可以不关心OF标志。// 因为计算机只计算二进制,所谓的有符号和无符号运算都是看程序员自己觉得的,对于有符号数程序员会利用补码定义负数
SF:符号标志。SF=1表示运算结果的最高位为“1“。
对于有符号数
- 在溢出标志OF=0时,SF=1表示运算结果为负,SF=0表示运算结果非负(SF = 最高位的值)。
- OF=1时,由于结果是错误的,所以符号位也和正确值相反。例如:两个负数相加产生溢出,此时SF=0。
对于无符号数运算,SF无意义(但是可以看出结果的大小规模)。
**ZF:零标志。
- ZF=1表示运算结果为零,减法运算后结果为零意味着两个参加运算的数大小相等;
- ZF=0,表示运算结果非零。
CF:进位/借位标志。
对无符号数有效
无符号数的加减法 = 有符号数补码的加减法
- CF=1 表示两个无符号数的加法运算有进位,或者是减法运算有借位,需要对它们的高位进行补充处理;
- 做减法时,直接观察 (被减数>减数 CF =1)
- 做加法时,可以转化为十进制,看是否超过255
- CF=0 表示没有产生进位或借位。
- 进行有符号数运算时也会产生新的CF标志,此时程序员可以不关心CF标志。
DF:方向标志。
- DF=0时,每次执行字符串指令后,源或目的地址指针用加法自动修改地址;
- DF=1时用减法来修改地址。它用来控制地址的变化方向。
IF:终端允许标志。IF=1表示允许处理器响应可屏蔽中断请求信号,称为开中断,IF=0表示不允许处理器响应可屏蔽中断请求信号,称为关中断。
AF:辅助进位标志。在进行字操作时,低字节向高字节进位时,AF=1,否则为0。一般用于两个BCD数运算后调整结果用,对其他数的运算没有意义。
PF:奇偶标志 。PF=1表示运算结果的低8位中偶数个”1“;PF=0表示有奇数个”1“。它可以用来进行奇偶校验。
3. 32位80x86CPU的工作模式
三种工作模式 : 实模式、保护模式、虚拟8086模式
1.实模式
为了兼容16位机的特点
- MS DOS 只能在实模式下运行
2.保护模式
主要工作模式
- 全部地址线参与寻址
- Windows系统及应用程序在保护模式下运行
3.虚拟8086模式
生成多个虚拟8086CPU,以便在运行实模式下的8086程序
- Windows下打开的DOS窗口运行一个DOS应用程序,程序久运行在虚拟8086模式下。
4.习题
简述计算机系统组成:
计算机由中央处理器CPU、存储器、输入系统和输出系统组成,由系统总线连接在一起。CPU包括运算器和控制器,运算器执行指令、控制器负责计算机的控制。存储器是计算机的记忆部件,以二进制形式存放程序和数据。输入输出系统包括大容量存储器,如硬盘。以及其他外设,如鼠标、键盘、显示器等。
简述16位机的各类寄存器的主要作用:参考本章2. 寄存器
写出每条汇编指令执行后的相关寄存器的值:
- Mov ax, 1345H ax = 1345H
- Mov ah, 24H ax = 2445H
- Mov al, 45H ax = 2445H
- Mov bx, 3412H bx = 3412H
- Mov al, bh ax = 2434H
- Mov ah, bl ax = 1234H
实模式下,写出段地址和偏移地址为1234:2002、1430:0042、FF00:0FFF的物理地址。(物理地址 = 段地址 * 16 + 偏移地址)
- $1234:2002 => 12340H + 2002H = 14342H$
- $1430:0042 => 14300H + 0042H = 14342H$
- $FF00:0FFF => FF000H + 0FFFH = FFFFFH$
下列各数均为十进制数,请采用8位二进制补码运算,并回答标志寄存器FLAGS中CF和OF的值,运算结果所代表的十进制数是多少?如果用16位二进制补码运算,其结果所代表的十进制数是多少?FLAGS中CF和OF的值呢?
86+69 // 题目是85+69 我直接将错就错
$86=0101\ 0110_2,69=0100\ 0101_2$
$86+69=0101\ 0110_2+0100\ 0101_2=1001\ 1011_2$补码转换$1001\ 1011_2\ => -0110\ 0101_2$此时十进制数为$-101$
因为溢出OF=1,没有进位CF=0,最高位为1故符号位SF=1,计算结果不为零ZF=0
16位下:$005BH$十进制数为$155$
没有溢出OF=0,没有进位CF=0,最高位为0故符号位SF=0,计算结果不为零ZF=086+(-69)
$86=0101\ 0110_2,-69=-0100\ 0101_2=1011\ 1011_2$
$86+(-69)=0101\ 0110_2+1011\ 1011_2=1\ 0001\ 0001_2$
补码转换$0001\ 0001_2=>0001\ 0001_2$此时十进制数为$17$
因为没溢出OF=0,有进位CF=1,最高位为0故符号位SF=0,计算结果不为零ZF=0
16位下:$0011H$十进制为$17$
因为没溢出OF=0,没进位CF=0,最高位为0故符号位SF=0,计算结果不为零ZF=086-(-69) // 加法看进位,减法看借位
$86=0101\ 0110_2,-69=-0100\ 0101_2=1011\ 1011_2$
$86-(-69)=>(无符号) 86-187=0101\ 0110_2-1011\ 1011_2=0101\ 0110_2 + 0100\ 0101_2=1001\ 1011_2$
补码转换$1001\ 1011_2\ => -0110\ 0101_2$此时十进制数为$-101$
因为溢出OF=1,有借位CF=1,最高位为1故符号位SF=1,计算结果不为零ZF=0
16位下:$005BH$十进制数为$155$
没有溢出OF=0,有借位CF=1,最高位为0故符号位SF=0,计算结果不为零ZF=086-(69)
$86=0101\ 0110_2,69=0100\ 0101_2$
$86-69=0101\ 0110_2-0100\ 0101_2=0101\ 0110_2+1011\ 1011_2=1\ 0001\ 0001_2$补码转换$0001\ 0001_2=>0001\ 0001_2$此时十进制数为$17$
因为没溢出OF=0,无借位CF=0,最高位为0故符号位SF=0,计算结果不为零ZF=0
16位下:$0011H$十进制数为$17$
没有溢出OF=0,没有借位CF=0,最高位为0故符号位SF=0,计算结果不为零ZF=0
给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围从__到__
答:偏移地址16位从0000H~FFFFH
故寻址从00010H+0000H ~ 00010H+FFFFH 即00010H到1000FH有一数据存放在内存20000H单元中,现给定段地址为SA,若想从偏移地址寻到此单元,则SA应满足的条件是:最小为__,最大为__。
答:偏移地址16位从0000H~FFFFH
寻址到20000H,最小为(20000H-FFFFH=10001H)除10H向上取整得到1001H,则最大为(20000H-0000H)除10H向下取整得到2000H。- 除10H即除16
已知8086系统某存储单元物理地址为:52506H,你认为段基址的最大值、最小是分别是多少?8086微机最多可以有多少个不同的段基址?
答:同上计算,最大:52506H/10H向下取整得到5250H(偏移地址为0),最小:(52506H-FFFFH)/10H向上取整得到4251H。
段地址16位,故最多有$2^{16}=65536$个段基址。从物理地址为00100H开始到00103H单元中顺序存放的数据为:12H、34H、56H,78H。请画出数据存放示意图,并回答以下问题:
- 写出地址00101H字节单元的内容;
答:34H - 写出地址00102H字节单元的内容
答:56H,若为字单元则7856H(小端:低字节低地址,高字节高地址)
- 写出地址00101H字节单元的内容;
第四章
1.立即寻址方式
定义
操作数直接写在指令中
用途: 用于直接指定一个常数送给寄存器
注意
- 8086中立即数是8位或者16位
- 立即寻址原来表示常数
- 立即寻址方式只能用于源操作数字段
- 立即数的类型必须与目的操作数的类型一致
举例
1 |
|
2.寄存器寻址方式
定义
操作数就是寄存器中的值
- 指令中给出寄存器名
用途: 用于指定2个寄存器作为操作数
注意
- 指令执行不需要访问内存因而执行速度快
举例
1 |
|
3.直接寻址方式
定义
操作数的有效地址EA(偏移地址)就在指令中 指令中直接给出了操作数的有效地址
由于存储器各个段的段地址已分别由各个段寄存器存放,只要知道偏移地址就能求出其物理地址
操作数的段地址为数据段,由DS指出,即操作数本身存放在数据段中
举例
1 |
|
注意
- 编写汇编源程序.asm文件时 , 对于直接寻址方式而言,必须用前缀 “ DS: “中指出该单元在数据段中
- DS:[2000H]代表一个数据段的存储单元,偏移地址为2000H
- 没写前缀DS: ,2000H代表的是立即数
- 在Debug的A命令输入命令(执行汇编指令),就不要加上前缀,系统默认为数据段
4.寄存器间接寻址方式
定义
- 操作数的有效地址EA就在寄存器中
- 不是把寄存器的内容作为操作数,而是把寄存器的内容作为操作数的地址,而操作数还在内存中。
- 用途: 适用于简单的表格处理
- 用寄存器间接指向一个内存单元,寄存器的值不同,指向的内存单元的地址就不同,常用于循环程序中
注意:
- 寄存器间接寻址只允许 BX BP SI DI 这四个寄存器作为间接地址寄存器
SI为源变址寄存器,DI为目的变址寄存器,BP为基址寄存器
- BX BP SI 默认DS作段地址寄存器
- BP 默认 SS作段地址寄存器
举例
1 |
|
1 |
|
1 |
|
5.寄存器相对寻址方式
定义
操作数的有效地址EA是一个寄存器和位移量之和(比寄存器间接寻址多一个位移量)
默认搭配是DS段寄存器和BX,SI,DI
SS段寄存器和BP
操作数物理地址 = (DS) * 10H + (BX) + 8位(16)位位移量
用途: 常用于查表操作 用于访问一维数组
举例
1 |
|
这三条指令是等效的
1 |
|
这两条指令是等效的
1 |
|
6.基址变址寻址方式
定义:
- 操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和
注意
- 允许使用的基址寄存器为 BX 和 BP
- 允许使用的变址寄存器为 SI 和 DI
1 |
|
举例
1 |
|
1 |
|
7.相对基址变址寻址方式
定义
- 有效地址是一个基址寄存器和一个变址寄存器以及一个位移量之和(比基址变址寻址多一个位移量)
- 用途: 可以用于二维数组的处理
注意
- 允许使用的基址寄存器为BX和BP
- 允许使用的变址寄存器为SI和DI
- 位移量可以为常量或者符号地址
举例
1 |
|
1 |
|
8.总结
- 不管变量的类型如何, 其有效地址总是16位
1)错误操作
双操作数指令的两个操作数,长度必须匹配
1 |
|
双操作数指令的两个操作数中,不能两个操作数同为内存单元
因为CPU与内存交换数据,通过地址线选中该内存单元,不能两个操作数同时经过数据线对内存单元进行读出或者写入
1 |
|
9.习题
- 指出以下指令的寻址方式,array是变量。
1 |
|
- 假定(DS)=1200H,(SS)=4400H,(BX)=463DH,(BP)=2006H,(SI)=6A00H,位移量D=4524H,以AX寄存器为目的操作数,试写出以下各种寻址方式下的传送指令,并确定源操作数的有效地址EA和物理地址。
1 |
|
第五章
1.数据传送指令
1)MOV 传送指令
规定
- 操作数与目的操作数的长度必须 明确且一致
- MOV AH , 258
- 目的操作数与源操作数 不能同为存储器 , 不允许在两个存储单元直接直接传送数据
- MOV [AX] , [DI]
- 目的操作数不能为 CS 或 IP , 因为CS:IP要指向的是当前要执行的指令所在的地址
- 目的操作数不可以是立即数
注意
段地址寄存器(DS SS CS ES)必须通过寄存器得到段地址,不能直接由符号地址、段寄存器、立即数得到
1 |
|
2)PUSH 进栈指令
格式
- PUSH SRC 将源操作数压入堆栈
操作
SRC为源操作数
- ( SP ) <— ( SP ) - 2
- (( SP ) + 1 , (SP)) <— ( SRC )
指令将源操作数压入堆栈 , 目的操作数的地址由 SS:SP 指出 , SP总是指向栈顶(大地址)
入栈时, 要将栈顶指针 SP 减2(2个字节,16位) , 来指向新的内存地址接受16位源操作数 , 并且同时指向新的栈顶
3)POP 出栈指令
格式
- POP DST
操作
DST表示目的操作数
- ( DST ) <— (( SP ) + 1 , ( SP ))
- ( SP ) <— ( SP ) + 2
堆栈中源操作数地址由 SS:SP 指出
源操作数弹出后 , SP + 2 ,下移一个字, 指向新的栈顶
举例
1 |
|
4)XCHG 交换指令
格式
- XCHG OPR1 , OPR2
操作
- ( OPR1 ) <— —> ( OPR2 )
- OPR1 和 OPR2都是目的操作数 ,执行后交换了位置
- 不能用立即数寻址
错误
1 |
|
2.累加器专用传送指令
注意
- 这组指令只限于 AX , AL (累加器)
- 输入/输出(IO)端口是CPU与外设传送数据的接口,单独编制,不属于内存
- 端口地址范围是0000 ~ FFFFH
1) IN(input)输入
定义
- 把端口号PORT或由DX指向的端口的数据输入到累加器,根据端口号的长度,有长格式和短格式两种形式
长格式
定义:
- 机器指令长度为2个字节 , 端口号占一个字节
格式:
- IN AL , PORT(字节)
- IN AL , PORT(字)
PORT为端口号 , 范围是00 - FFH
- 八位二进制 / 两位十六进制
短格式
定义:
- 端口号范围为 0100H - 0FFFFH
- 短格式机器指令长度为1个字节,因为端口号存在DX寄存器中
格式:
- IN AL , DX(字节)
- IN AX , **DX(**字)
2)OUT(output) 输出
定义
- 把累加器的数据输出到端口PORT或由DX指向的端口
长格式:
- OUT PORT , AL(字节)
- OUT PORT , AX(字节)
短格式:
- OUT DX , AX(字节)
- OUT DX , AL(字节)
3)XLAT(translate) 换码
定义:
- 把BX+AL的值作为以后小地址,取出其中一个字节送到AL
格式:
- XLAT
操作:
- AL <— ( BX+AL )
3.地址传送指令
- LEA 有效地址送寄存器
- LSD 指针送寄存器和DS
- LES 指针送寄存器和ES
1)LEA 有效地址送寄存器指令
格式
- LEA REG , SRC
操作
- REG <— SRC
定义:
- 把源操作数的有效地址EA(偏移地址)送到指定寄存器
1 |
|
2) LDS 指针送寄存器和DS指令
格式:
- LDS REG , SRC
操作
- REG <— ( SRC )
- DS <— ( SRC + 2 )
定义:
- 把源操作数SRC所指向的内存单元中的两个字送到指定的寄存器REG和DS
1 |
|
3) LES 指针送寄存器和ES指令
格式:
- LDS SI , [BX]
操作
- REG < — ( SRC )
- ES < — ( SRC+2 )
4.标志寄存器传送指令
- LAHF 标志送AH寄存器
- SAHF AH送标志寄存器
- PUSHF 标志入栈
- POPF 标志出栈
四条指令的格式相同,只有操作码部分,操作数为固定默认值,传送类指令(除SAHF\POPF)均不影响标志位
5.算术运算指令
重要!!!
1)类型扩展指令
- CBW 字节扩展成字
- CWD 字扩展成双字
这两条指令的格式相同,只有操作码部分,没有操作数部分。
操作数默认是累加器,无需在指令中给出
CBW :
- 当执行CBW时,默认将AL寄存器的内容扩展到AX寄存器中,扩展方法为符号扩展
- 符号扩展即如果AL的最高位为1(负数) , 则CBW指令扩展时使 AH = FFH
- 如果AL的最高位为0 , 则CBW指令扩展时使 AH = 00H。
CWD:
- 执行CWD时,默认将AX寄存器的内容扩展到(DX,AX)中
- DX存放双字中的高位
- AX存放双字中的低位
- 如果AX最高位为1,CWD指令扩展时使 DX = FFFFH
- 如果AX最高位为0,CWD指令扩展时使 DX = 0000H
举例
正数扩展
1 |
|
负数扩展
1 |
|
2)加法指令
- ADD 加法
- ADC 带进位加法
- INC 加1
加减运算必考 ADC SBB , CF , OF
ADD:
格式:
- AADD DST , SRC
操作:
- ( DST ) <— ( DST ) + ( SRC )
注意:
- 加法指令执行后会影响标志寄存器中的CF和OF标志位
举例
无符号为数的溢出标志位CF
1 |
|
有符号数的溢出标志位OF
1 |
|
ADC:
格式:
- ADD DST , SRC
操作:
- (DST) <— (SRC) + (DST) + CF
CF即为标志位的值,无符号数加法考虑
1 |
|
3)减法指令
- SUB 减法
- SBB 带借位减法
- DEC 减1
- NEG 求补
- CMP 比较
SUB减法指令
格式:
- SUB DST , SRT
操作:
- (DST) <— (DST) - (SRC)
SBB带借位减法指令
格式:
- SBB DST , SRC
操作:
- (DST) <— (DST) - (SRC) - CF
DEC减1指令
格式:
- DEC OPR
操作:
- (OPR) <— (OPR) - 1
该指令不影响CF标志位
NEG求补指令(求相反数)
格式:
- NEG OPR
操作:
- (OPR) <— -(OPR)
CMP比较指令
格式:
- CMP OPR1 , OPR2
操作:
- (OPR1) - (OPR2)
CF 标志位指明无符号的溢出
OF标志位指令有符号数溢出
举例:
1 |
|
当两个有符号数的符号相同时,结果是不会发生溢出的。只有符号数的符号相反才有可能发生溢出,需要通过OF标志位判断
1 |
|
4)乘法指令
- MUL 无符号数乘法
- IMUL 有符号数乘法
MUL:
格式:
- MUL SRC
操作:
- 当操作数为字节时, (AX) <— (AL) * (SRC)
- 当操作数为字时, (DX , AX) <— (AX) * (SRC)
注意:
IMUL格式和操作与MUL相同。
乘法指令中 , 目的操作数默认认为累加器AX
两个相乘数必须长度相同,根据SRC长度而定是AL或者AX。SRC可以是寄存器或者变量,不能是立即数(立即数长度不确定)
运算结果长度是乘数的两倍,不会出现溢出情况
举例:
1 |
|
5)除法指令
- DIV 无符号数除法
- IDIV 有符号数除法
DIV
格式:
- DIV SRC
操作:
- SRC为字节时,(AL) <— (AX)/(SRC)的商, (AH) <— (AX)/(SRC)的余数
- SRC为字时,(AX) <— (DX,AX)/(SRC)的商, (DX) <— (DX,AX)/(SRC)的余数
IDIV
- IDIV指令格式和操作与DIV相同
- IDIV中:最终商的符号应该是两个操作数符号的异或,而余数的符号和被除数符号一致
注意:
- 除法指令中,目的操作数必须是累加器AX和DX(乘法只能是AX)
- 被除数长度应为除数长度的两倍,余数放在目的操作数的高位,商放在目的操作数的低位。
- SRC不能是立即数
- 在除法中,会产生溢出现象
- 除数是字节类型时,除法指令要求商为8位。
- 如果被除数的高8位绝对值 > = 除数的绝对值。商会产生溢出
- 除数是字类型时,除法指令要求商为16位。
- 如果被除数的高16位绝对值 > = 除数的绝对值。商会产生溢出
- 除数是字节类型时,除法指令要求商为8位。
举例
作字节除法
1 |
|
作字除法
1 |
|
6)BCD码(8421)的十进制调整指令
- DAA 加法的十进制调整指令
- DAS 减法的十进制调整指令
DAA:
格式:
- DAA
操作:
- 加法指令中,以AL为目的操作数,当加法运算结束后,用DAA把AL中的和调整为正确的BCD码格式
1 |
|
举例:
AF辅助进位标志
8位运算或16位运算时如果有进位或借位CF就等于1,而4位运算时如果有进位或借位AF就等于1。
AF是为了在BCD码运算时,要用到的,因为BCD码是以4位表示的。
1 |
|
1 |
|
DAS:
格式:
- DAS
操作:
- 减法指令中,以AL为目的操作数,减法运算结束后,用DAS把差调整为BCD码
1 |
|
举例:
1 |
|
6.逻辑与位移指令
- AND
- OR
- NOT
- XOR 异或
- TEST 测试
逻辑指令按二进制位进行操作,操作数可以看成二进制位串。双操作数指令中,至少有一个操作数必须存放在寄存器中,另外一个操作数可以使用任意寻址方式
注意:
- 逻辑运算指令只会对部分标志位产生影响
- NOT指令不影响任何标志位
- 其他指令将使CF 和 OF为0,AF位无定义
AND
格式:
- AND DST , SRC
操作:
- (DST) <— (DST)^ (SRC)
OR
格式:
- OR DST , SRC
NOT
格式:
- NOT DST , SRC
XOR
格式:
- XOR DST , SRC
TEST
格式:
- TEST OPR1 , OPR2
操作:
- (OPR1) ^ (OPR2)
- test指令的两个操作数相与的结果不保存,只根据结果置标志位
7.移位指令
- SHL 循环左移
- SAL 算术左移
- SHR 循环右移
- SAR 算术右移
- ROL 循环左移
- ROR 循环右移
- RCL 带进位循环左移
- RCR 带进位循环右移
移位指令均是双操作数指令,指令格式相同
SHL: 逻辑左移
格式:
- SHL OPR , 1
- SHL OPR, CL (其中CL寄存器的值大于1)
注意:
- 其中OPR为寄存器或者内存单元 , 移位次数可以是1或CL寄存器
- 如果移位次数大于1,则可以在该移位指令前把移位次数送到CL寄存器中
左移:
算术左移和逻辑左移,操作结果相同,均是最低位补0。移出的最高位送CF标志位
ROL循环左移时,OPR整体向左移一位,最高位移出,同时送CF标志位和最低位
RCL带进位循环左移时,OPR整体左移一位,此时最高位移出送CF标志位,而CF标志位原始的数值送OPR最低位
右移:
- 逻辑右移时,最高位补0 , 移出的最低位送CF标志位。
- 算术右移时,OPR被认为是有符号数,最高位补符号位自身, 移出的最低位送CF标志位。
- ROR循环右移时,OPR整体向右移一位,最低位移出,同时送CF标志和最高位。
- RCR带进位循环右移,OPR整体右移一位,此时最低位移出送CF标志位,CF标志位原始的数值送OPR最高位
举例:
1 |
|
8.串操作指令
9.程序转移指令
- 无条件转移指令
- 条件转移指令
- 循环指令
- 子程序调用指令
- 中断调用指令
无条件转移指令
- JMP : 无条件转移到指令指定的地址去执行程序。指令中必须指定转移的目标地址
- 根据目标地址,可以将无条件转移指令分为段内转移和段间转移
段内转移:
- 转移的目标地址和本条跳转指令在同一个代码段。跳转后,CS寄存器的值没有发生转变只有IP寄存器有了改变
段间转移:
- 转移的目标地址和本条跳转指令不在同一个代码段。跳转后,CS寄存器的值发生了改变
循环指令
- LOOP 循环
- LOOPZ/LOOPE 当为0/相等时循环 ZF = 1
- LOOPNZ/LOOPNE 当不为0/不相等时循环 ZF = 0
循环指令的操作均是 首先执行CX寄存器减1,然后根据测试条件决定是否转移
1.(CX )=( CX )- 1
2.判断cx中的值
不为0转到标号处执行程序
为0则向下执行
习题5
设V是变量,指出下列错误的指令,说出错误原因并修改。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18MOV AX, [DX] ; DX不能做内存指针,寄存器间接寻址方式有:BX、SI、DI、BP可以
MOV DS, DATA ; 段不能直接送DS,需要先送AX,再由AX送DS
MOV CS, AX ; CS不能修改
MOV AX, DL ; 数据类型不一致
PUSH AL ; 必须为16位,应改成AX 不能WORD PTR AL
ADD [BX], [DI] ; 不能同问内存
LEA [BX], V ; 不能对内存直接写立即数 要改成BX
MOV [DX], OFFSET V ; DX不能做内存指针,去掉方括号
MOV [SI], 2 ; 立即数位数不确定,需要加PTR运算符
MUL BX, CX ; MUL 为单操作数 默认目的寄存器为AX、DX 或 AX
DIV 5 ; 立即数不能作为除数,需要先存入另一寄存器
MOV BYTE[SI], AX ; 类型不一致或用了保留字做标识符
MOV AX, [SI+DI] ; 只能基址变址,需要将SI、DI其中一个改为BP/BX
SHR AX, 4 ; 移位次数非1时,只能用CL计数
CMP 6, AX ; 立即数不能出现在目的地址
MOV [FFFF], AX ; FFFF会被当做标识符,需要加前缀0或后缀H
MOV AX, BX + 4 ; 如果相对基址,加方括号
JMP FAR PRO ; 需加PTR运算符在数据段定义了ARRAY数组,其中依次存储了4个字数据,根据以下要求把第4个字送AX寄存器。
直接寻址
1
MOV AX, ARRAY+6
使用BX的间接寻址
1
2MOV BX, OFFSET [ARRAY+6]
MOV AX, [BX]使用BX和ARRAY的寄存器相对寻址
1
2MOV BX, 0006H
MOV AX, ARRAY[BX]基址变址寻址
1
2
3MOV SI, 0006H
LEA BX, ARRAY
MOV AX, [BX][SI]MOV以外的其他指令
1
2SUB AX, AX
ADD AX, ARRAY+6
溢出标志位OF与进位标志位CF有何作用和区别
1 |
|
- 无符号数关心CF
- 有符号数关心OF
第六章 伪指令
1.伪指令
定义
- 在汇编程序对源程序进行汇编期间由汇编程序处理的操作。
- 指令是在程序运行期间由CPU执行的
1)段定义伪指令
1 |
|
2)数据定义域存储器单元分配伪指令
数据定义:[变量名] 操作码 N个操作数 [;注释] // N个操作数字节大小全和操作码规定一样
1 |
|
操作数为字符串。问号‘?’仅预留空间。
1 |
|
用操作符复制操作数
1 |
|
2)类型属性操作符
访问内存变量要指定地址,同时指定访问长度进行匹配,为避免出现两个长度不匹配的操作数使用类型属性操作符,进行访问。
WORD PTR ; 字类型
BYTE PTR ; 字节类型
1 |
|
3)THIS操作符和LABEL伪操作
一个变量可以定义成不同的访问类型(比如word byte)方便访问,为此引入了THIS和LABEL。
1 |
|
1 |
|
4)表达式赋值伪指令“EQU”和“=”
可以用赋值伪操作给表达式赋予一个常量或名字
格式:①表达式名 EQU 表达式②表达式名 = 表达式
```
VALUE EQU 4
DATA EQU VALUE + 5
ADDR EQU [BP+VALUE]1
2
3
4
5
6
7
8
9
- EQU和=区别,前者不能重复定义变量名,**后者可以重复定义**
- ```
VALUE = 54
VALUE = VALUE + 89
但是不能
VALUE EQU 54
VALUE EQU VALUE + 54
5)汇编地址计数器$与定位伪指令
地址计数器$
$表示当前正在汇编的指令的偏移地址。
1
2
3
4
5ORG 0H
ARRAY DW 3,$+7,7 ;$当前为2
COU = $ ;$当前为6
NEW DW COU
;内存模型为:03 00 09 00 07 00 06 00 (COU = 6,符号变量不占存储,NEW占了存储)ORG 伪操作
ORG用来设置当前地址计数器$的值(理解为定位了一个开始地址)
1
2
3
4
5
6
7ORG 0H ; 代表$ = 0 ,同时当前开始存储的地址为0H
DB 3 ;
ORG 4
BUFF DB 6
ORG $ + 6
VAL DB 9
;内存模型为:03 -- -- -- 06 -- -- -- -- -- -- 09EVEN伪操作
使下一个变量或指令开始于偶数地址。(方便16位)
ALIGN伪操作
使下一个变量的地址从4的倍数开始。(方便多字)
1
ALSI 8 ; 8字节对齐
基数控制
- 二进制:0101 0101B
- 十进制:默认数字均为十进制,23D
- 十六进制:0ABCD 9876H,同时要求第一个字符必须是0~9,若为A~F则补0。 如0FFFFH
6)过程定义伪指令
子程序又称过程,可以把一个程序写成一个过程或多个过程。
1
2
3procedure_name PROC Attribute
procedure_name ENDP1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20程序名 PROC 类型属性(NEAR或FAR); NEAR 和 FAR 好像没要求很多 随便用吧
程序名 ENDP
;;
DATA SEGMENT
STRING DB 'HELLO,WORLD$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
MAIN PROC FAR
MOV AX,DATA
MOV DS,AX
LEA DX,STRING
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
CODE ENDS
END MAIN ; 设置程序起点MAIN
2.语句格式
1 |
|
下面各项只能符号变量或常数直接计算,不能寄存器直接运算需要用对应的指令。
名字项
- 字母:A~Z
- 数字:0~9
- 专用字符:? . @ - $
算术操作符:+ - * / MOD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21ORG 0
VAL = 4
DA1 DW 6,2,9,3
DA2 DW 15,17,24
COU = $ - DA2
MOV AX , DA1*4 ; 地址乘除没有意义
MOV AX , DA1*DA2 ; 地址乘除没有意义
MOV AX , DA1+DA2 ; 地址加减没有意义
MOV AX , BX+VAL ; BX+VAL需用指令实现
----------------------------------------------
MOV AX , [BX+VAL] ; MOV AX , [BX + 4]
MOV AX , DA1+VAL ; MOV AX , [4]
MOV AX , [DA1+VAL] ; MOV AX , [4]
MOV AX , VAL*4/2 ; MOV AX , 8
MOV AX , [VAL*A/2] ; MOV AX , 8
MOV CX , (DA2-DA1)/2 ; MOV CX , 4 取到DA1区数据个数
MOV BX , COU ; MOV BX , 6 取到DA2区的字节数逻辑与逻辑位移操作符
逻辑操作符 AND , OR , XOR , NOT
位移操作符SHL , SHR
都是按位操作符
格式:
- expression 操作符 number
逻辑操作符的使用:
1
2
3
4
5
6
7
8ARY DW 8
VAL = 4
MOV AX , BX AND 0FFH ; BX AND VAL须要指令实现
MOV AX , ARY AND 0FFH ; ARY AND VAL须要指令实现
-----------------------------------------------------------
MOV AX , VAL AND 0F0H ; MOV AX , 0
AND AX , VAL OR 0FOH ; MOV AX , 0F4H移位操作符的使用
1
2
3
4
5
6
7
8
9ARY DW 8
VAL = 4
MOV AX , BX SHL 2 ; BX左移需用指令实现
MOV AX , ARY SHL 2 ;ARY左移需用指令实现
-----------------------------------
MOV AX , VAL SHL 2 ;MOV AX , 10H
MOV AX , 8 SHL 2 ;MOV AX , 20H
MOV AX , VAL SHL 15 ;MOV AX , 00H关系操作符
用于对两个操作数的大小关系作出判断。
为真则FFFFH,为假则0H
- EQ相等
- NE不等
- LT小于
- GT大于
- LE小于等于
- GE大于等于
1
2
3
4
5VAL = 4
MOV AX , BX GT 2 ; BX是否大于2须要用指令实现
-----------------------------------------------------
MOV AX, VAL GE 2 ; MOV AX , FFFFH
MOV AX, 8 LE VAL ; MOV AX , 0H数值回送操作符
TYPE:
格式:
- TYPE expression(表达式)
- 如果该表达式是变量,则汇编程序将回送该变量的以字节数表述的类型:
- DB为1,DW为2,DD为4,DF为6,DQ为8,DT为10。
- DB 定义字节,DW定义字,DD定义双字,DF定义6个字节的字,DQ定义4个字,DT定义10个字节
- 如果表达式是标号,则汇编程序将回送代表标号类型的数值:
- NEAR为-1,FAR为-2。如果表达式为常数则回送0。
- 如果该表达式是变量,则汇编程序将回送该变量的以字节数表述的类型:
- TYPE expression(表达式)
LENGTH:
格式:
- LENGTH 变量
- 变量用DUP复制的,则回送总变量数
- 不是DUP复制的为1,但嵌套的DUP不计。
- 对于使用嵌套的DUP复制的数据不能据此得到正确的总变量数。
- LENGTH 变量
SIZE:
格式:
SIZE 变量
- 变量用DUP复制的,则回送总字节数,
- 其他为单个变量的字节数,但嵌套的DUP不计。所以,对于使用嵌套的DUP复制的数据不能据此得到正确的总字节数。
OFFSET:OFFSET 变量或标号
- 回送变量或标量的偏移地址。
SEG:SEG 变量或标号
- 回送变量或标号的段地址
1 |
|
3.习题
1 |
|
定义数据段满足如下要求
(1)array为字符串变量:’inspire a generation!’
(2)data1为十六进制数:0FEDCBAH
(3)data2为二进制数:10101010B
(4)data3为100个为0的字节变量:
(5)分配500个字的空间待用
1 |
|
第七章 分支与循环程序设计
1.分支程序设计
1)分支程序结构
- IF-THEN-ELSE结构
2)单分支程序
- IF-THEN
3)复合分支程序
- 处理分段函数
4)多分支程序
- 通过JMP brach[BX]指令间接寻址方式转向对应分支
2.循环程序设计
1)循环程序结构
DO - WHILE结构
- 把循环控制条件放在循环的入口,先判断控制条件是否成立,再决定是否进入循环
DO - UNTIL结构(至少执行一次)
- 先执行循环体,然后判断控制条件是否成立,再决定是否进入循环
第八章 子程序设计
1.子程序结构
定义:
- 把一段完成相对独立功能的程序设计成子程序,供主程序调用
操作:
- 主程序通过指令CALL启动子程序执行
- 指令执行时,先把它下一条指令的地址压入堆栈保存
- 再把子程序的入口地址置入IP(CS)寄存器,以便实现转移
- 子程序执行完毕后,用放回指令(RET)回到主程序,放回指令把堆栈里保存的返回地址送回IP(CS)寄存器,实现程序的返回
- 子程序执行之后,返回到主程序接着执行
CALL指令
格式:
- CALL DST
注意:
- 与JMP指令不同,先向堆栈保存放回地址,再实现程序转移
- 对于段内调用,只向堆栈保存IP寄存器的值
- 对于段间调用,先向堆栈保存CS寄存器的值,再保存IP寄存器的值
RET指令
格式:
- RET
- RET EXP
- EXP为表达式,为一个常数。除了完成RET指令的操作外,还让SO再加上这个常数,修改SP寄存器的值
过程定义与过程结构
1 |
|
确定属性
- 如果调用程序和该过程在同一个代码段,则用NEAR属性
- 如果调用程序和该过程不在同一个代码段,则用FAR属性
保护和恢复现场寄存器
定义:
- 再进入子程序后,先保存寄存器的值,在子程序退出前恢复这些寄存器的值
1 |
|
2。子程序的参数传递
定义:
- 主程序调用子程序时,要传递参数给子程序,这个参数称为入口参数
- 子程序执行完毕后,返回参数给主程序,这个参数叫出口参数
类型
- 值传递
- 把参数的值放在约定的寄存器或内存单元
- 寄存器有限,不能传递很多参数
- 把参数的值放在约定的寄存器或内存单元
- 地址传递
- 把参数的地址传递给子程序
- 参数较多时使用
- 把参数的地址传递给子程序