第7章 8086/8088汇编语言程序设计 7.1 引言 7.2 顺序程序设计 7.3 分支结构程序设计 7.4 循环结构程序设计 第7章 8086/8088汇编语言程序设计 7.1 引言 7.2 顺序程序设计 7.3 分支结构程序设计 7.4 循环结构程序设计 7.5 字符串操作程序设计 7.6 宏、条件汇编与重复汇编 7.7 子程序设计 7.8 8086/8088微处理器的其他指令与应用 2017/3/21
7.1 引言 1.汇编语言的基本概念与学习汇编语言的重要性 汇编语言是一种面向机器(处理器)的程序设计语言,是机器语言的符号化表示。 汇编语言的执行语句与机器指令有着一一对应的关系,即一个执行语句对应一条机器指令。 按照某种机器汇编语言的语法规则编写的源程序必须翻译成相应的机器语言才能在计算机上运行。这个翻译过程称为汇编。 从汇编语言到机器语言的翻译程序叫汇编程序. 2017/3/21
7.1 引言 1.汇编语言的基本概念与学习汇编语言的重要性 学习汇编语言有助于加深对计算机组成、寻址方式和指令集的理解。 使用汇编语言可以直接操作、控制计算机的底层硬件。 相对于高级语言源程序经过编译得到的目标程序,汇编语言源程序经汇编得到的目标程序具有代码精练、占用存储空间小、执行速度快的特点,甚至还可以降低机器的功耗。 学会一种汇编语言(8086/8088汇编语言),就可以轻松自学其他的汇编语言(如ARM)。 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 合法的字符 英文字母A~Z / a~z (汇编语言不区分字母大小写) 数字0~9 符号 + – * / < > ( ) [ ] " ′ = ; , : _ @ $ & # ? ! 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 数据分为常量和变量 在汇编期间,常量的值完全确定。 在程序运行期间,常量的值不会发生变化。 在汇编语言中,变量名代表的是 该变量在计算机中的存储地址(和类型)。 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 常量 二进制整数,例如:01010101B 八进制整数,例如:567O、567Q 十进制整数,例如:1234 十六进制整数,例如: 12H , 0ABH 字符,例如:‘O’、“GOOD” 十进制实数,例如:12.34E–5 十六进制实数,例如:1A2B345R 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 符号常量 用途:提高程序的可读性、降低发生错误的可能性 通过“EQU”或“=”语句来定义 例如:PI EQU 3.141592 ALPHT = PI* 3 一个符号用“EQU”定义后就不允许对其再次定义,而用“=”定义的符号可以对其再次定义 符号常量及其数值保存在汇编程序管理的符号表中,在汇编过程中,一旦遇到符号就用它的数值替换 。 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 变量 两种类型:寄存器变量和主存变量 寄存器变量就是寄存器名。例如:AX(AH|AL),BX(BH|BL),CX(CH|CL),DX(DH|DL),SI,DI,BP,SP,CS,DS,ES,SS,IP 主存变量简称为变量. 变量名具有段地址、偏移地址和类型三个属性 。 变量的类型有:DB、DW、DD、DQ和DT。 2017/3/21
一个实现字节型变量X+YZ的源程序 汇编语言源程序,在结构上与高级语言源程序是相似的,都是先定义变量,再编写对变量进行处理的语句。 汇编语言的语句是计算机指令的助记符,功能单一,一行只能书写一个语句/指令,且用“回车”来标志结束,不需要在语句末尾加任何标点符号。 著名诗人艾青:诗是艺术的语言——最高的语言,最纯粹的语言。 您认不认为:编汇编语言程序就想写诗一样? 2017/3/21
一个实现字节型变量X+YZ的源程序 注释 说明语句 (也称伪指令性) 处理语句 (也称指令性语句) 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 上例的伪指令有段定义伪指令、变量定义伪指令和 段值设置伪指令 段定义伪指令由语句“段名 SEGMENT”开始, 以语句“段名 ENDS”结束。 变量定义伪指令的格式是: 变量名 变量类型 变量初值序列 [;注释] 段值设置伪指令ASSUME,放在代码段的开始处 ASSUME CS: CODE, DS: DATA 2017/3/21
ASSUME伪指令仅仅告诉汇编程序:段寄存器与程序段的 对应关系。 段地址的真正设定还需要由指令性语句对段寄存器赋值来 完成。不过代码段的段寄存器CS的赋值由DOS的装入模块 自动完成,所以程序只需对数据段的段寄存器DS或附加数 据段的段寄存器ES赋值。 MOV AX, DATA ;数据段DATA的段地址送入AX MOV DS, AX ;AX中的内容送入数据段段寄存器DS 2017/3/21
可见,一个段到底是数据段还是代码段与其名字无关 ,取决于程序把哪个段对应到哪个段寄存器。 所以当源程序有多个段时,要小心编程,以免出错。 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 上例的指令性语句有MOV指令、ADD指令和INT指令 指令性语句的一般格式是: [标号:] 指令操作符 [操作数] [,操作数] [;注释] 操作数分为源操作数和目的操作数, 前者表示欲处理数据的源地址,后者表示处理结果的存储地址,两者的数据类型必须一致。 标号是后面紧跟着冒号的标识符,代表冒号后面语句的存储地址,供转移指令或循环指令作为操作数使用 标号的属性:NEAR、FAR 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 标号、段名和变量名统称为标识符 是一个由字母、符号或数字组成的字符串。 字符串的限制:(1)必须采用合法的字符;(2)第一个字符必须是字母、问号、@或下划线中的一个,不能是数字;(3)不能使用汇编语言的保留字。 标识符中字符个数没有明确的限制,但只有前面的31个字符能够被汇编程序识别。 标识符的命名应该有一些含义,以增强程序的可读性和可理解性。 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 MOV指令 格式:MOV Dst, Src ; (Dst)(Src) 例如:MOV AX, BX MOV CX, 1234H MOV可实现通用寄存器和主存单元之间的数据传送,却不能实现两个主存单元之间或 两个段寄存器之间的数据传送。 2017/3/21
7.1 引言 2.8086/8088汇编语言的基本语法 ADD指令 格式:ADD Dst, Src ; (Dst)(Src)+ (Dst) 例如:ADD AX, BX ADD CX, [1234H] ADD指令影响标志位OF,SF,ZF,AF,PF,CF 2017/3/21
7.1 引言 汇编语言程序的开发过程 编写源程序:EDIT (DOS), TextPad(Windows) 将源程序保存为 XXXX.asm 文件 使用MASM生成目标程序 XXXX.obj 使用LINK生成可执行程序 XXXX.exe 源程序 XXX.asm 目标程序 XXX.obj 可执行程序 XXX.exe 设计编辑 用MASM 汇编 用LINK 连接 执行 2017/3/21
7.2 顺序程序设计 1. 概述 顺序程序是指不含有转移指令或分支指令的程序, 语句执行的顺序就是它们排列的顺序。 2017/3/21
7.2 顺序程序设计 指令格式: XOR Dst, Src ; (Dst)(Src) (Dst) 注意对标志位的影响。 2017/3/21
7.2 顺序程序设计 2. 寻址方式的表示 大多数情况下,指令不直接给出操作数本身,而是给出存放操作数的寄存器或者是内存单元的地址。 大多数情况下,操作数地址也不是直接给出,而是给出计算操作数地址的方法,称之为寻址方式。 2017/3/21
(1) 立即寻址 操作数作为指令的一部分存放在指令中,位于操作码之后,这种操作数称为立即数。 立即数可以是8位的或者16位的。(386之后的机器也可以是32位的) 立即数用来表示常数,它经常用来给寄存器赋初值。只能用于源操作数字段,不能用于目的操作数字段,且源操作数长度应与目的操作数长度一致。 2017/3/21
立即数寻址举例 MOV AX, 3064 H 指令执行后(AX)= 3064 H 64 30 ………… OP 指令 AX 2017/3/21
立即寻址举例 MOV AL, 4E H OP 4E MOV AL,4E H AL 4E 2017/3/21
(2)寄存器寻址 操作数在寄存器中,指令中指定寄存器号。 16位的操作数,寄存器可以是 AX,BX,CX,DX,SI,DI,SP,BP。 8位的操作数,寄存器可以是 AH,AL,BH,BL,CH,CL,DH,DL。 2017/3/21
例: MOV AX , BX (BX)= 1234 H 指令执行后: (AX)= 1234 H (BX)= 1234 H 寄存器寻址不需要访问存储器来取得操作数,所以可以得到较高的运算速度。 2017/3/21
立即数寻址 寄存器寻址 直接寻址 寄存器间接寻址 寄存器相对寻址 基址变址寻址 相对基址变址寻址 不需要计算操作数的地址 寄存器寻址 直接寻址 需要计算操作数的 有效地址EA 寄存器间接寻址 寄存器相对寻址 基址变址寻址 相对基址变址寻址 2017/3/21
操作数的地址 段地址 偏移地址 我们把这个偏移地址称为有效地址(EA) 有效地址= 基址 + 变址 + 位移量 有效地址= 基址 + 变址 + 位移量 存放在变址寄存器(SI,DI)中的内容,用来 访问数组中的某个元素或字符串中的某个字符 存放在指令中的一个8位、16位的数, 但它不是立即数,而是一个地址。 存放在基址寄存器(BX,BP)中的内容,它是有效地址中的 基址部分,通常用来指向数据段中数组或字符串的首地址 2017/3/21
段 偏移地址 CS IP SS SP 或 BP DS BX、DI、SI或一个16位数 ES 8086/8088段寄存器和相应存放偏移地址的寄存器之间的默认组合 段 偏移地址 CS IP SS SP 或 BP DS BX、DI、SI或一个16位数 ES 2017/3/21
(3)直接寻址 操作数的有效地址只包含位移量一种成分,其值就存放在代码段中指令的操作码之后。位移量的值就是操作数的有效地址。 例: MOV AX , [2000H] 假设(DS)= 3000H 物理地址=3000H*16 +2000H =32000H 32000H 00 20 ………… OP 代码段 50 30 数据段 AX 则指令执行后,AX=3050H 2017/3/21
直接寻址中操作数地址是直接写在指令中,所以它只适用于处理单个变量。 可以用符号来代替数值地址 MOV AX , ADDR MOV AX , [ADDR] 如果在附加段,则应指定段前缀 MOV AX , ES:ADDR MOV AX , ES:[ADDR] 直接寻址中操作数地址是直接写在指令中,所以它只适用于处理单个变量。 因为要处理另外一个变量,就需要用另外一条指令了。 2017/3/21
(4)寄存器间接寻址 指令的操作数是一个寄存器。但是寄存器中的内容并不是真正的操作数,而是操作数的有效地址。因此真正的操作数需要按照这个有效地址访问主存储器才能获得。 16位寻址,可用的寄存器是 BX,BP,SI,DI。 使用 BX、SI、DI,其默认段是数据段 DS。 使用 BP,其默认段是堆栈段 SS。 2017/3/21
寄存器间接寻址可用于以循环结构来处理表格,执行完一条指令后,只需修改寄存器内容就可以用同一个指令来访问表格的下一项。 例:MOV AX , [BX] 设(DS)= 2000H (BX)= 1000H 物理地址 = 2000H * 16 + 1000H = 21000H 21000H ………… A0 50 数据段 AX 指令执行后 AX = 50A0H 2017/3/21
(5)寄存器相对寻址 例:MOV AX , COUNT [ SI ] 请问:寄存器间接寻址与寄存器相对寻址, 有何不同? “相对寻址”意味着指令中带有位移量。 操作数的有效地址为基址寄存器或变址寄存器的内容和指令中的位移量之和。 例:MOV AX , COUNT [ SI ] 也可以表示为 MOV AX , [ COUNT+SI ] 请问:寄存器间接寻址与寄存器相对寻址, 有何不同? 2017/3/21
当指令中使用的是基址寄存器 BX 或 BP 时, 也称为基址寻址。 当指令中使用的是变址寄存器 SI 或 DI 时, 也称为变址寻址。 例:MOV AX , COUNT [ BX ] MOV AX , COUNT [ SI ] 当指令中使用的是基址寄存器 BX 或 BP 时, 也称为基址寻址。 当指令中使用的是变址寄存器 SI 或 DI 时, 也称为变址寻址。 2017/3/21
例:MOV AX , COUNT [ BX ] 设(DS)= 3000H (BX)= 2000H COUNT = 3000H 物理地址 = 3000H * 16 + 2000H + 3000H= 35000H 30000H 35000H 00 30 ………… OP 代码段 34 12 数据段 AX 33000H COUNT BX DS 指令执行后 AX = 1234H 2017/3/21
同样可以用于以循环结构来处理表格,表格的首地址可设置为偏移量(第几列)的地址,利用修改基址或变址寄存器中的内容(第几行)来取得表格中的值。 寄存器相对寻址 (即基址寻址或变址寻址) 同样可以用于以循环结构来处理表格,表格的首地址可设置为偏移量(第几列)的地址,利用修改基址或变址寄存器中的内容(第几行)来取得表格中的值。 2017/3/21
(6)基址变址寻址 例:MOV AX , [ BX ] [ DI ] 操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和 2017/3/21
例:MOV AX , [BX] [DI] 设(DS)= 2100H (BX)= 0158H (DI) = 10A5H 物理地址 = ( 2100H * 16 + 0158H )+10A5H = 21158H+ 10A5H = 221FD H 21000H 221FDH ………… 3 4 1 2 数据段 AX 21158H BX 指令执行后 AX = 1234H 2017/3/21
基址变址寻址同样可以用于以循环结构来处理数组或表格。 表格的首地址可存放在基址寄存器中(在处理过程中保持不变),利用变址寄存器的值作为下标来访问数组或表格中的元素,每处理完一个元素,变址寄存器的值“加一”指向下一个元素。 2017/3/21
(7)相对基址变址寻址 “相对寻址”意味着指令中带有位移量。 操作数的有效地址是一个基址寄存器与一个变址寄存器的内容和指令中的位移量之和。 例: MOV AX , ARRAY [ BX ] [ SI ] 也可表示为 MOV AX , [ ARRAY+ BX+ SI ] 2017/3/21
例:MOV AX , MASK[BX][SI] 设(DS)= 3000H (BX)= 2000H (SI) = 1000H MASK = 0250H 物理地址 = 3000H * 16 + 2000H +1000H + 0250H = 33250H 假设[33250]=1234H,则指令执行后 AX = 1234H 2017/3/21
相对基址变址寻址常用于二维数组元素的寻址。 如存储器中存放着由多个记录组成的文件, 则以位移量可以指向文件之首, 基址寄存器指向某个记录, 变址寄存器则指向该记录中的一个元素 2017/3/21
7.2 顺序程序设计 例7-1 编程实现将内存中分别存放于 地址SOURCE和DEST的4个字互换。 DATA SEGMENT SOURCE DW 1234H, 5678H DEST DW 9ABCH, 0EF01H DATA ENDS 关键指令:XCHG opr1, opr2 2017/3/21
7.2 顺序程序设计 代码段的框架 CODE SEGMENT ASSUME CS: CODE, DS: DATA START:MOV AX, DATA MOV DS, AX (核心代码) MOV AH, 4CH INT 21H CODE ENDS END START 2017/3/21
7.2 顺序程序设计 代码段的核心代码 XCHG AX, DEST XCHG AX, SOURCE MOV SI, 2 MOV AX, SOURCE XCHG AX, DEST XCHG AX, SOURCE MOV SI, 2 MOV AX, SOURCE [SI] XCHG AX, DEST [SI] XCHG AX, SOURCE [SI] 2017/3/21
7.2 顺序程序设计 3. 表达式的使用 例7-2 32位数据X和Y的加减,结果分别 存于Result1和Result2。 DATA SEGMENT X DD 12345600 H Y DD 11223344 H Result1 DD ? Result2 DD ? DATA ENDS 2017/3/21
7.2 顺序程序设计 代码段的框架 CODE SEGMENT ASSUME CS: CODE, DS: DATA START:MOV AX, DATA MOV DS, AX (核心代码) MOV AH, 4CH INT 21H CODE ENDS END START 2017/3/21
7.2 顺序程序设计 代码段的核心代码(1) 表达式 带进位的加法 MOV AX, WORD PTR X MOV DX, WORD PTR [X+2] ;把1234H装入DX ADD AX, WORD PTR Y ADC DX, WORD PTR [Y+2] ; MOV WORD PTR Result1, AX ;保存结果的低16位 MOV WORD PTR [Result1+2], DX ;保存结果的高16位 表达式 带进位的加法 2017/3/21
7.2 顺序程序设计 代码段的核心代码(2) 表达式 带借位的减法 MOV AX, WORD PTR X MOV DX, WORD PTR [X+2] SUB AX, WORD PTR Y SBB DX, WORD PTR [Y+2] ; MOV WORD PTR Result2, AX MOV WORD PTR [Result2+2], DX 表达式 带借位的减法 2017/3/21
7.2 顺序程序设计 表达式的类型: 数值表达式: 常量与运算符(包括圆括号)组成的算式,它的运算结果被当作一个数值 地址表达式: 运算对象,包括寄存器名、常量、变量、标号及方括号(表示读主存)与运算符组成的算式,它的运算结果被当作一个主存地址 2017/3/21
7.2 顺序程序设计 数值表达式的运算符类型: 算术运算符 +(加)、–(减)、*(乘)、/(除)、MOD(取余数)、SHR(算术右移)和SHL(算术左移)。 其中算术右移/左移1位相当于除以/乘以2。 2017/3/21
7.2 顺序程序设计 数值表达式的运算符类型: 逻辑运算符。AND(与)、OR(或)、NOT(非)和XOR(异或)。 关系运算符。EQ(等于)、NE(不等于)、LT(小于)、GT(大于)、LE(小于等于)和GE(大于等于)。它们的运算结果是0(表示不成立或者“假”)或0FFFFH(表示成立或者“真”)。 2017/3/21
7.2 顺序程序设计 数值表达式的例子: MOV BX, ((SUM LT 10) AND 30) OR ((SUM GE 100) AND 20 符号常量SUM小于10时,将被汇编成“MOV BX, 30”; SUM大于等于100时,将被汇编成“MOV BX, 20”; SUM介于10~100时,将被汇编成“MOV BX, 0”。 2017/3/21
7.2 顺序程序设计 4.属性取代符: 类型运算符 PTR 段地址取代符“:” 短地址取代符 SHORT 任意类型运算符 THIS 2017/3/21
7.2 顺序程序设计 5.属性分离符 取段地址符 SEG 和 取偏移地址符 OFFSET 取类型符 TYPE 元素个数属性符 LENGTH 字节总数属性符 SIZE 高位字节属性符HIGH和 低位字节属性符LOW 2017/3/21
7.2 顺序程序设计 6.运算符的优先级 优先级 运算符 1(最高) LENGTH,SIZE 2 PTR,OFFSET,SEG,TYPE,THIS 3 HIGH,LOW 4 +,—(单项运算符) 5 *,/,MOD,SHR,SHL 6 +,— 7 EQ,NE,LT,LE,GT,GE 8 NOT 9 AND 10(最低) OR,XOR 2017/3/21
7.2 顺序程序设计 6.运算符的优先级 优先级高的运算先执行。 (运算符的优先级如表7-9所示) 优先级相同的多个运算符,按从左向右的顺序执行 可以用圆括号改变运算顺序,圆括号内的运算先执行。 6.运算符的优先级 2017/3/21
7.2 顺序程序设计 7.乘/除法运算的实现(1) 8086/8088的乘法指令有两个: 无符号数乘法指令MUL(unsigned MULtiple) MUL src ; (AX) (AL) *(8位src) (DX, AX) (AX) *(16位src) 带符号数乘法指令IMUL(sIgned MULtiple) IMUL src ; (AX) (AL) *(8位src) 2017/3/21
7.2 顺序程序设计 7.乘/除法运算的实现(2) 8086/8088的除法指令有两个: 无符号数除法指令DIV(unsigned DIVide) DIV src ; (AL) (AX)/(8位src)的商, (AH) (AX)/(8位src)的余数 (AX) (DX, AX)/(16位src)的商 (DX) ( DX, AX)/(16位src)的余数 带符号数除法指令IDIV(sIgned DIVide) IDIV src ; (同上) 2017/3/21
7.2 顺序程序设计 例7-3 编程计算(V–(XY+Z–540))/X。 其中X,Y,Z,V 均为16位带符号数, 计算结果的商存入F单元,余数存入F+2单元。 DATA SEGMENT X DW 25 Y DW 20 Z DW 140 V DW 50 F DW 2DUP(?) DATA ENDS XY 的结果是32位 Z要扩展成32位——符号位扩展 重复伪指令 2017/3/21
7.2 顺序程序设计 8086/8088的符号位扩展指令有两个: 1、“字节转换为字”指令CBW (Convert Byte to Word) AL的最高位(符号位)扩展到AH 2、“字转换为双字”指令CWD (Convert Word to Double Word) 将AX的最高位扩展到DX。 2017/3/21
7.2 顺序程序设计 CBW和CWD都是不带操作数的单字节指令 执行不影响标志位,但要占用AX。 16位数据与8位数据相加/减或32位数据与16位数据相加/减时,也需要对较短的数据进行符号位扩展。 2017/3/21
7.2 顺序程序设计 例如,计算56(-23)的程序段可以是: MOV AL, 56 CBW MOV CL -23 IDIV CL MOV Result, AL ;商(AL中)存入字节型变量Result 2017/3/21
7.2 顺序程序设计 例7-3 编程计算(V–(XY+Z–540))/X。 其中X,Y,Z,V 均为16位带符号数, 计算结果的商存入F单元,余数存入F+2单元。 DATA SEGMENT X DW 25 Y DW 20 Z DW 140 V DW 50 F DW 2DUP(?) DATA ENDS 2017/3/21
7.2 顺序程序设计 代码段的核心代码(1) DX:AX ← XY 的结果是32位 32位运算:BX:CX ← XY +Z MOV AX, X IMUL Y MOV CX, AX ; 将DX:AX暂存于BX:CX MOV BX, DX MOV AX, Z ; 准备计算32位的(XY +Z) CWD ; 将AX符号位扩展 DX:AX ADD CX, AX ADC BX, DX SUB CX, 540 ; BX:CX ← BX:CX 540 SBB BX, 0 ; 完成32位的减法 DX:AX ← XY 的结果是32位 32位运算:BX:CX ← XY +Z 2017/3/21
7.2 顺序程序设计 代码段的核心代码(2) MOV AX, V CWD ;将V符号位扩展DX:AX SUB AX, CX ; V (X * Y + Z 540) SBB DX, BX ;结果存于DX:AX IDIV X ;(DX:AX)/X MOV F, AX ;F←AX(商) MOV F+2, DX ;F+2←DX(余数) 2017/3/21
8.算术移位与逻辑移位(1) 7.2 顺序程序设计 8086/8088的算术移位指令有两个: 算术左移指令SAL(Shift Arithmetic Left) SAL opr, 1 SAL opr, CL 算术右移指令SAR(Shift Arithmetic Right) SAR opr, 1 SAR opr, CL 2017/3/21
8.算术移位与逻辑移位(2) 7.2 顺序程序设计 8086/8088的逻辑移位指令有两个: 逻辑左移指令SHL(SHift logical Left) SHL opr, 1 SHL opr, CL 逻辑右移指令SHR(SHift logical Right) SHR opr, 1 SHR opr, CL 2017/3/21
7.3 分支结构程序设计 程序的分支是通过转移指令来实现的。 8086/8088微处理器提供了两类转移指令: 它们的执行均不影响标志位。 无条件转移指令JMP 条件转移指令JX。 它们的执行均不影响标志位。 2017/3/21
7.3 分支结构程序设计 1.无条件转移指令JMP 段内转移:不改变CS,只改变IP; 段间转移:既改变CS,又改变IP。 指令格式:JMP OPR 指令功能:根据操作数OPR,更改IP或CS。 根据是否改变CS寄存器,无条件转移可以分为 段内转移:不改变CS,只改变IP; 段间转移:既改变CS,又改变IP。 2017/3/21
7.3 分支结构程序设计 1.无条件转移指令JMP 段内转移的三种形式: 段内直接短转移。其格式是:JMP SHORT OPR 段内直接近转移。其格式是:JMP OPR 段内间接转移。其格式是:JMP WORD PTR OPR 2017/3/21
段内直接转移 以当前 IP 指向的地址为基准地址,加上跟在操作码后面的相对位移量 D,得到目标指令的有效地址 EA。 + EA 2017/3/21
段内直接转移 8位的相对位移量(类型为:SHORT),对应的转移范围是:-128~+127 16位的相对位移量(类型为:NEAR),对应的转移范围是:-32768~+32767 例如:JMP NEAR ADDR JZ SHORT ADDR 位移量是汇编程序通过求转向的目标指令的有效地址与当前IP值之差而的。 注意:当前IP已经指向转移指令的下一条指令 2017/3/21
转向的有效地址是一个寄存器或是一个存储单元的内容。 段内间接转移 转向的有效地址是一个寄存器或是一个存储单元的内容。 这个寄存器或者存储单元中的内容可以用除立即数以外的任何一种寻址方式获得 ( I P )( E A ) 2017/3/21
寄存器寻址方式 寄存器间接寻址方式 假设: (DS)= 2000H,(BX)= 1256H, (21256H)= 3280H. JMP BX 执行该指令后,(IP)= 1256H JMP [BX] 执行该指令后,(IP)= (20000H+1256H) = (21256H) = 3280H 寄存器寻址方式 寄存器间接寻址方式 2017/3/21
(IP)= ((DS)* 16 + (BX)+ 位移量) = (20000H + 1256H + 2011H) 假设: (DS)= 2000H,(BX)= 1256H, (SI)= 528FH , 位移量VAR = 2011H (23267)= 3280H,(284F6H)= 2450H JMP VAR[BX] 执行该指令后, (IP)= ((DS)* 16 + (BX)+ 位移量) = (20000H + 1256H + 2011H) = (23267H)= 3280H JMP VAR[BX][SI] (IP)= ((DS)* 16 + (BX)+ (SI)+ VAR) = (20000H + 1256H + 528FH+ 2011H ) = (284F6H ) = 2450H 寄存器相对寻址方式 基址变址相对寻址方式 2017/3/21
段间转移应用于转移目标不在JMP指令所在段的场合,需要给出 4 字节的目标地址 CS:IP。 段间转移有两种形式: 段间直接(远)转移:JMP FAR PTR OPR 指令直接提供转向的段地址和偏移地址(类型为:FAR PTR ), 例如: JMP FAR PTR OPR (I P) OPR的低16位(段内偏移地址) (CS) OPR的高16位(段地址) 2017/3/21
段间间接寻址 JMP DWORD PTR OPR 段间直接(远)转移 段间间接寻址 JMP DWORD PTR OPR 用OPR指向的存储器单元中的相邻两个字的内容来取代 IP和 CS 寄存器中的原始内容,以达到段间转移的目的。 存储单元的有效地址EA是由指令指定除立即数方式和寄存器方式以外的任何一种数据寻址方式获得 完成的操作:(IP) (EA) (CS) (EA+2) 2017/3/21
例 JMP DWORD PTR[BX+8] (BX)= 3706H,(DS)= 1000H EA= (BX)+ 8= 3706H + 8 =370EH 物理地址 = (DS)* 16 + EA = 10000H + 370EH = 1370EH ……… B2H 67H 05H 33H 1370EH 指令执行后, (IP)= 67B2H, (CS)= 3305H 2017/3/21
7.3 分支结构程序设计 2. 条件转移指令 JX 和比较指令 CMP JX 的格式是:JX OPR, 其中 OPR 是目的地址标号(SHORT属性)。 JX 的操作是:满足条件则 ( IP ) ( IP ) + OPR,即跳转到目的地址处执行指令;否则不做任何操作(即IP不变,执行下一条指令)。 说明:X 为1~3个字母,表示转移条件。 为了得到条件转移指令所需的条件,通常需要先执行“比较”指令 CMP(CoMPare) 2017/3/21
7.3 分支结构程序设计 判断单个标志位状态的条件转移指令有10条: CF=1时转移 JC(Jump if Carry)。 CF=0时转移 JNC(Jump if Not Carry)。 ZF =1时转移 JE / JZ(Jump if Equal, or Zero)。 ZF = 0时转移 JNE / JNZ(Jump if Not Equal, or Not Zero) SF=1时转移 JS(Jump if Sign)。 SF=0时转移 JNS(Jump if Not Sign)。 OF=1时转移 JO(Jump if Overflow)。 OF=0时转移 JNO(Jump if Not Overflow)。 PF = 1时转移 JP / JPE(Jump if Parity, or Parity Even)。 PF = 0时转移 JNP / JPO(Jump if Not Parity, or Parity Odd) 2017/3/21
7.3 分支结构程序设计 比较无符号数的条件转移指令有4条: 高于/不低于且不等于(CF=0且ZF=0)转移 JA / JNBE。 高于或等于/不低于(CF=0或ZF=1)转移 JAE / JNB。 低于/不高于且不等于(CF=1且ZF=0)转移 JB / JNAE。 低于或等于/不高于(CF=1或ZF=1)转移 JBE / JNA。 其中,A 表示高于(Above),B 表示低于(Below), E 表示等于(Equal)。 2017/3/21
7.3 分支结构程序设计 比较有符号数的条件转移指令有4条: 大于/不小于且不等于(ZF=0且SFOF=0)转移 JG / JNLE。 大于或等于/不小于(ZF=1或SFOF=0)转移 JGE / JNL。 小于/不大于且不等于(ZF=0且SFOF=1)转移 JL / JNGE。 小于或等于/不大于(ZF=1或SFOF=1)转移 JLE / JNG。 其中,G 表示大于(Greater),L 表示小于(Less), E 表示等于(Egual)。 2017/3/21
例7-4 求三个16位无符号数中的最大值 DATA SEGMENT X DW 180 Y DW 670 Z DW 320 MAX DW ? 开 始 结 束 X≥Y? X≥Z? MAX←X Y X Y X Z N DATA SEGMENT X DW 180 Y DW 670 Z DW 320 MAX DW ? DATA ENDS 2017/3/21
例7-4 求三个16位无符号数中的最大值 CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX (具体操作指令序列) MOV AH, 4CH INT 21H CODE ENDS END START 2017/3/21
例7-4 求三个16位无符号数中的最大值 MOV AX, X CMP AX, Y JAE AXBIG MOV AX, Y (具体操作指令序列) MOV AX, X CMP AX, Y JAE AXBIG MOV AX, Y AXBIG: CMP AX, Z JAE AXMAX MOV AX, Z AXMAX: MOV MAX, AX 开 始 结 束 X≥Y? X≥Z? MAX←X Y X Y X Z N 2017/3/21
例7-5将三个带符号的8位二进制数x、y、z, 按升序排序后重新存回x、y、z 结 束 开 始 X<Y? Y X Y N X<Z? X Z Y<Z? Y Z DATA SEGMENT X DB -5 Y DB 23 Z DB 7 DATA ENDS 2017/3/21
例7-5 程序主体框架 CODE SEGMENT ASSUME CS:CODE, DS:DATA START: MOV AX, DATA MOV DS, AX (具体操作指令序列) EXIT: MOV AH, 4CH INT 21H CODE ENDS END START 2017/3/21
例7-5 具体操作指令序列 MOV AL, X CMP AL, Y JL XLY XCHG AL, Y XCHG AL, X 开 始 XLY: CMP AL, Z JL CMPYZ XCHG AL, Z XCHG AL, X CMPYZ: MOV AL, Y CMP AL, Z JL EXIT XCHG AL, Y 结 束 开 始 X<Y? Y X Y N X<Z? X Z Y<Z? Y Z 2017/3/21
7.4 循环结构程序设计 循环分为计数循环和条件判断循环。 计数循环的循环次数是已知的、确定的。一般是将循环次数存入计数寄存器 CX,然后每循环1次 CX 减 1,当CX不为 0 时,循环继续,否则结束循环。 这种循环结构常用LOOP指令来实现。 LOOP指令的格式是:LOOP 语句标号。 操作是:CX(CX)–1。若 CX 0 则 IP(IP)+ 语句标号;否则 IP不变(即执行LOOP指令的下一条指令) 2017/3/21
7.4 循环结构程序设计 条件判断循环通过条件转移指令或 下列条件循环指令来实现。 为零或相等循环指令LOOPZ / LOOPE (LOOP while Zero, or Equal) 非零或不相等循环指令 LOOPNZ / LOOPNE (LOOP while NonZero, or Not Equal) 2017/3/21
7.4 循环结构程序设计 LOOPZ/LOOPE指令的格式是: LOOPZ / LOOPE 语句标号。 操作是:CX(CX)–1。若CX0且ZF=1,则IP(IP)+ 语句标号;否则IP不变。 LOOPNZ/LOOPNE指令的格式是: LOOPNZ / LOOPNE 语句标号。操作是:CX(CX)–1。若CX0且ZF=0,则IP(IP)+ 语句标号;否则IP不变。 2017/3/21
7.4 循环结构程序设计 在汇编后得到的目标代码中, LOOP,LOOPZ/LOOPE 和 LOOPNZ/LOOPNE指令中的操作数“语句标号”的实质是一个单字节的补码,其值等于循环控制指令与转移目标语句的距离。这些循环控制指令的执行均不影响标志位。 2017/3/21
7.4 循环结构程序设计 例7-6 有一个首地址为ARRAY的M字数组,请编程计算该数组内容之和,并把结果存入TOTAL中。 程序的数据段 DATA SEGMENT ARRAY DW 12, 13, 26, 35, 71, 83 M EQU ( $ – ARRAY ) / 2 TOTAL DW ? DATA ENDS 2017/3/21
7.4 循环结构程序设计 例7-6 有一个首地址为ARRAY的M字数组,请编程计算该数组内容之和,并把结果存入TOTAL中。 程序代码段的核心代码 MOV AX, 0 MOV CX, M ;循环次数M送入CX MOV SI, AX ;效果等于“MOV SI, 0”,但更快 STARE_LOOP: ADD AX, ARRAY [SI] ADD SI, 2 ;地址加2指向下一个字型数据 LOOP START_LOOP MOV TOTAL, AX 2017/3/21
例7-7 将位于数据段TEXT地址中的小写字母,转换成大写字母,然后存回原地址内,TEXT内容结束标志为“$” 开 始 结 束 BX TEXT的偏移地址 AL [BX] AL=‘$’? AL<‘a’? AL>‘z’? AL – 20H AL, AL [BX] BX + 1 BX Y N ASCII码中,大于等于‘a’且小于等于‘z’的字母为小写字母,通过减 32(20H)可将其转换成大写字母。 2017/3/21
ASSUME CS:CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA BX, TEXT CODE SEGMENT ASSUME CS:CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA BX, TEXT ...... EXIT: MOV AH, 4C H INT 21 H CODE ENDS ENDS START 2017/3/21
B20: MOV AL, [BX] CMP AL, '$' ;判断是否是“结束符” JE EXIT ;是,则结束 CMP AL, 'a' JB B30 ;在‘a’之下,是大写字母 CMP AL, 'z' JA B30 ;在‘z’之上,不是字母 SUB AL, 20H ;小写字母变大写字母 MOV [BX], AL ;替换原先小写字母 B30: INC BX ;指向下一个字母, JMP B20 2017/3/21
例7-8 把 BLOCK 为首地址的数据区中 100 个连续的 8位二进制数按正、负数分开,分别送到两个缓冲区 PLUS_DATA(存正数)和 MINUS_DATA(存负数)中。假设数据中不存在 0。 判断正数的算法:使用 TEST 指令测试符号位,然后判断 ZF 标志。 TEST AL, 1000 0000B 若为正数,则“与”运算结果为 0,ZF = 1 2017/3/21
ASSUME CS:CODE, DS: DATA START: MOV AX, DATA MOV DS, AX ...... DATA SEGMENT BLOCK DB 1, -2, 3, -4,..., 100 PLUS_DATA DB 100 DUP ( ? ) MINUS_DATA DB 100 DUP ( ? ) DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS: DATA START: MOV AX, DATA MOV DS, AX ...... CODE ENDS ENDS START 2017/3/21
ASSUME CS:CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA SI, BLOCK CODE SEGMENT ASSUME CS:CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA SI, BLOCK LEA DI, PLUS_DATA LEA BX, MINUS_DATA MOV CX, 100 ...... CODE ENDS ENDS START 2017/3/21
MINUS: MOV [BX], AL ;处理负数 INC BX ;下一负数的存储地址 AGAIN: INC SI ;指向下一待处理的数据 GOON: MOV AL, [ SI ] TEST AL, 1000 0000B JNZ MINUS ;转去处理负数 MOV [DI], AL ; 处理正数 INC DI ;下一正数的存储地址 JMP AGAIN MINUS: MOV [BX], AL ;处理负数 INC BX ;下一负数的存储地址 AGAIN: INC SI ;指向下一待处理的数据 LOOP GOON ;一个完整的循环结构 2017/3/21
7.5 字符串操作程序设计 字符串操作指令和重复前缀 8086/8088微处理器提供了5条字符串操作指令:传送串指令MOVS(MOVe String)、存回串指令STOS(STOre into String)、取入串指令LODS(LOAd from String)、扫描串指令SCAS(SCAn String)和比较串指令CMPS(COMpare String)。它们都是单字节指令, 指令执行一次只处理一个字符。要想让指令连续处理一个字符串,可以在指令前面加上“重复前缀”:REP(重复)、REPE/REPZ(相等/为零重复)或REPNE/REPNZ(不相等/不为零重复)。 重复的次数由CX中的值决定。 2017/3/21
7.6 宏、条件汇编与重复汇编 宏的定义与引用 所谓“宏”是由程序员定义的一种“虚指令”,这种“虚指令”代表的是采用机器指令书写的一段汇编语言源程序,但却可以在汇编语言源程序中以普通指令助记符的形式出现。 每当遇到程序中的“宏”时,汇编程序就会用该“宏”代表的汇编语言源程序段替换到“宏”所在的位置。当某一段汇编语言源程序需要反复使用时,可以引入“宏”来简化程序设计。 2017/3/21
7.6 宏、条件汇编与重复汇编 宏的定义与引用 宏定义的格式为: 宏名 MACRO [ 形式参数列表] 7.6 宏、条件汇编与重复汇编 宏的定义与引用 宏定义的格式为: 宏名 MACRO [ 形式参数列表] … ;宏内容——汇编语言指令和伪指令组成的指令序列 ENDM [宏名]。 【例7-12】 定义一个让屏幕上光标“换行”宏指令 答:LF MACRO MOV DL,00001010B;00001010B为换行符的ASCII码 MOV AH,2 INT 21H ENDM LF 2017/3/21
7.6 宏、条件汇编与重复汇编 【例7-13】 定义一个“PRINT”宏,来实现向屏幕输出一个字符串。可使用宏LF。 7.6 宏、条件汇编与重复汇编 【例7-13】 定义一个“PRINT”宏,来实现向屏幕输出一个字符串。可使用宏LF。 答:这个宏需要带一个形式参数来表示字符串。该形式参数命名为MESSAGE。定义如下: PRINT MACRO MESSAGE MOV DX,OFFSET MESSAGE MOV AH,9 INT 21H LF ENDM 2017/3/21
7.6 宏、条件汇编与重复汇编 条件汇编 在汇编语言中,也可以通过条件汇编来缩短汇编时间。 条件汇编的格式为: 7.6 宏、条件汇编与重复汇编 条件汇编 在汇编语言中,也可以通过条件汇编来缩短汇编时间。 条件汇编的格式为: IFXX [表达式/符号/参数] ;条件伪指令 … ;语句段A ELSE … ;语句段B ENDIF。 2017/3/21
7.6 宏、条件汇编与重复汇编 条件汇编 条件伪指令有: IF 表达式 ;表达式值不等于0为真(条件成立) 7.6 宏、条件汇编与重复汇编 条件汇编 条件伪指令有: IF 表达式 ;表达式值不等于0为真(条件成立) IFE 表达式 ;表达式值等于0为真(条件成立) IF1 ;第一遍汇编为真(条件成立) IF2 ;第二遍汇编为真(条件成立) IFDEF符号 ;符号已定义为真(条件成立) IFNDEF符号 ;符号未定义为真(条件成立) IFB <参数> ;“参数为空”为真(条件成立) IFNB <参数> ;“参数非空”为真(条件成立) IFIDN <串1>,<串2> ;“串1等于串2”为真(条件成立) IFDIF <串1>,<串2> ;“串1不等于串2”为真(条件成立) 2017/3/21
7.6 宏、条件汇编与重复汇编 重复汇编 在编写程序时,如果需要连续地编写相同的一组语句或字符,就可以使用重复汇编来减少工作量。 7.6 宏、条件汇编与重复汇编 重复汇编 在编写程序时,如果需要连续地编写相同的一组语句或字符,就可以使用重复汇编来减少工作量。 支持重复汇编的伪指令有: 面向重复次数确定的REPT(Repetition)、 面向重复次数不确定的IRP(Indefinite Repeat) 面向不定长重复字符的IRPC(Indefinite Repeat)。 2017/3/21
7. 7 子程序设计 1. 引言 如果在一个程序中的多个地方、或多个程序中的多个地方用到了同一段程序,那么可以将这段程序抽取出来,存放在某一存储区域,每当需要执行这段程序时,就调用指令转到这段程序去,执行完毕,再返回原来的程序。 把抽取出来的这段程序叫做子程序或过程,调用它的程序称为 主程序或 调用程序 子程序允许嵌套和递归 2017/3/21
记录断点:为了返回到调用程序的合适地方,转子调用必须保留返回调用程序的下一条指令的地址(返回地址)--又叫断点。即当前 I P 寄存器的值。 子程序的调用过程 记录断点:为了返回到调用程序的合适地方,转子调用必须保留返回调用程序的下一条指令的地址(返回地址)--又叫断点。即当前 I P 寄存器的值。 保护现场:保存有关通用寄存器的内容,子程序返回主程序之前,恢复这些通用寄存器的内容 参数传递的方法 通过寄存器传递:适于参数较少时 通过参数表传递:适合参数较多的情况 通过堆 栈传递:适合参数较多,且子程序有嵌套、递归的情况 2017/3/21
7. 7 子程序设计 2.调用指令和返回指令 1.引言 (1)调用指令:CALL 子程序名/目的地址 (2)返回指令: RET [ n ] 2017/3/21
7. 7 子程序设计 调用指令 格式:CALL 子程序名/目的地址 功能: 段内直接近调用 CALL 子程序名(NEAR) PUSH (IP) (IP)(IP)+16位的二进制数 段内间接近调用 CALL WORD PTR [ BX ][ DI ] (IP) (EA) 2017/3/21
段间直接远调用 CALL 子程序名(FAR) PUSH (CS) PUSH (IP) (IP) 目标地址中指定的偏移地址 段间间接远调用 CALL DWORD PTR [ BX ] ( IP ) (EA) (CS) (EA + 2) 2017/3/21
7. 7 子程序设计 返回指令 RET 段内近返回 (IP) POP ( ) 段间远返回 (IP) POP( ) (CS) POP( ) 2017/3/21
7. 7 子程序设计 子程序设计 适合编成子程序的程序 子程序的特点 一段程序在整个任务中被多次使用 一段程序在多个任务中被多次使用 节省存储空间 增大了时间开销 2017/3/21
子程序的组成框架 ;程序说明 BTOD PROC FAR ( NEAR ) 保护现场 ;将寄存器压入堆栈 核心工作 恢复现场 ;将堆栈弹回寄存器 RET ;返回 BTOD ENDP 2017/3/21
7. 7 子程序设计 3. 子程序的参数传送 1.引言 2.调用指令和返回指令 通过寄存器传送 通过堆 栈传送 通过地址表传送 通过堆 栈传送 通过地址表传送 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 1.处理器控制指令 清除CF标志 CLC 进位有效位CF求反 CMC 置CF标志 STC 置DF标志 STD 清除DF标志 CLD 置IF标志 STI 清除IF标志 CLI 处理机暂停 HLT 等待状态 WAIT 将数据传送给协处理器 ESC 保证总线的控制 LOCK 无操作 NOP 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 2.对标志位的操作 1.处理器控制指令 2.对标志位的操作 8086/8088微处理器只提供对标志寄存器中DF(第10位)、IF(第9位)和CF(第0位)三个标志位进行修改的指令。 那么如何修改OF(第11位)、TF(第8位)、SF(第7位)、ZF(第6位)、AF(第4位)、PF(第2位)标志位呢? 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 利用标志进栈指令PUSHF(PUSH the Flags)和标志出栈指令POPF(POP the Flags)指令。 例如欲清除TF标志,可以用如下语句: PUSHF ;将标志寄存器的内容压入堆栈 MOV BP, SP ;栈顶指针送入BP寄存器 AND [BP], 0FEFFH ;将BP指向的主存单元的第8位置成0 POPF ;将栈顶单元的内容写入标志寄存器 欲翻转OF标志,可以用如下语句: PUSHF ;标志位入栈 POP AX ;标志位入AX XOR AX, 0800H ;在AX中将OF翻转,其余位不变 PUSH AX ;修改后的标志位入栈 POPF ;标志位出栈存回标志寄存器 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 利用“标志寄存器低字节送AH指令LAHF(Load AH with Flags)”和“AH送标志寄存器低字节指令SAHF(Store AH into Flags)”。 LAHF和SAHF指令都是单字节指令,执行时间都是4个时钟周期,LAHF指令的执行不影响标志位,SAHF指令执行后低8位标志位的值由指令的操作数决定。 例如,欲清除SF标志,可以用如下语句: LAHF AND AH, 7FH ;将标志寄存器的第7位置成0 SAHF 欲将标志寄存器低8位清0,可以用如下语句: MOV AH, 00H 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 3.中断相关指令 1.处理器控制指令 2.对标志位的操作 在执行程序的过程中,计算机会遇到一些异常情况或特殊请求。此时处理器将保存当前的状态,转去进行必要的处理,处理完毕后返回到程序间断处继续执行。这个过程叫做中断。 中断可分为由处理器外部引起的外部中断、异常情况引起的硬件中断和“中断”指令INT引起的软件中断。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 3.中断相关指令 INT指令的格式是:INT TYPE 或INT。其中TYPE为中断类型号,它是一个取值范围在0~255之间的常数或常数表达式,例如INT 21H。 所有中断都有一个编号——中断类型号。类型号乘以4就是相应的中断服务程序的入口地址。 格式中的INT TYPE为双字节指令,执行时间为52个时钟周期;格式中的INT为单字节指令,隐含的中断类型号为3,执行时间为51个时钟周期。 INT指令执行的操作依次是:SP(SP)–2,(SP)(FR),SP(SP)–2,(SP)(CS) ,SP(SP)–2,(SP)(IP),IP(TYPE*4),CS(TYPE*4+2)。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 3.中断相关指令 计算结果溢出属于一种异常,需要进行中断处理。该中断的类型号为4。为了加快溢出的处理,8086/8088微处理器专门设置了“溢出中断”指令INTO。 INTO指令执行的操作依次是:若OF=0,不做任何操作;否则,SP(SP)–2,(SP)(FR),SP(SP)–2,(SP)(CS),SP(SP)–2,(SP)(IP),IP(10H),CS(12H)。 当OF=0时,INTO指令的执行时间为4个时钟周期,否则为53个时钟周期。 INT和INTO指令执行结束后,IF和TF被置0,其余标志位不变。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 3.中断相关指令 IRET指令执行的操作依次是: 为了实现中断返回,在每个中断服务程序的末尾需要加上一条“中断返回”指令IRET(RETurn from Interrupt)。 IRET指令执行的操作依次是: IP((SP)),SP(SP)+2, CS((SP)),SP(SP)+2, FR((SP)),SP(SP)+2。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 4.面向十进制数运算的指令 1.处理器控制指令 2.对标志位的操作 3.中断相关指令 4.面向十进制数运算的指令 在8086/8088微处理器中,十进制数可以采用压缩的BCD码或非压缩的BCD码来表示。 压缩的BCD码用4位二进制数来表示1位十进制数。 非压缩的BCD码用8位二进制数来表示一位十进制数,8位中的低4位为BCD码,高4位无定义。 由于数字的ASCII码的低4位为相应数字的BCD码,而高4位为0011,所以数字的非压缩BCD码可以采用相应数字的ASCII码。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 4.面向十进制数运算的指令 在8086/8088的运算器中,表示十进制数的BCD码采用二进制的运算规则来进行运算,所以运算结束后需要对运算结果进行调整。8086/8088微处理器提供如下BCD码调整指令: (1)加法的压缩BCD码调整指令DAA (2)减法的压缩BCD码调整指令DAS (3)加法的非压缩BCD码调整指令AAA (4)减法的非压缩BCD码调整指令AAS (5)乘法的非压缩BCD码调整指令AAM (6)除法的非压缩BCD码调整指令AAD 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 5.与输入/输出相关的指令 1.处理器控制指令 2.对标志位的操作 3.中断相关指令 4.面向十进制数运算的指令 5.与输入/输出相关的指令 (1)“输入”指令IN和“输出”指令OUT 微处理器与外设之间的信息交换是通过I/O端口进行的。为此,8086/8088设置了实现累加器AX/AL与I/O端口之间数据交换的“输入”指令IN和“输出”指令OUT。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 IN指令和OUT指令有长、短两种格式。 IN指令的长格式是:IN AX/AL PORT; 短格式是:IN AX/AL DX。 OUT指令的长格式是:OUT PORT AX/AL; 短格式是:OUT DX AX/AL。 其中,PORT为端口号。 当端口的宽度为字节时选用AL,为字时选用AX。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 5.与输入/输出相关的指令 (2)“换码”指令XLAT(transLATe) 在信息处理中常常要将一种编码(源编码)转换成另一种编码(目标编码)。例如,在接受键盘输入时需要将字符的扫描码转换成ASCII码,在控制LED显示时需要将数字0~9转换成7段数码管所要求的显示码。为此,8086/8088设置了“换码”指令XLAT。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 5.与输入/输出相关的指令 (2)“换码”指令XLAT(transLATe) 指令XLAT是通过查找“源编码与其对应目标编码的表格”来进行编码转换,所以使用这条指令前,应建立一个表格(宽度为1字节),表格的内容就是每一个源编码对应的目标编码(按源编码的值由小到大排列,并以源编码的值作为查表入口)。表格的首地址要事先存入BX寄存器。 2017/3/21
7. 8 8086/8088微处理器的其他指令与应用 XLAT指令的格式是:XLAT 或XLAT OPR。 操作是:AL((BX)+(AL))。 其中指令操作数OPR(表格的首地址)是为了提高程序的可读性而书写的,在汇编时将被忽略。 在将待转换的编码存入AL后,就开始执行XLAT指令。指令执行结束后,AL中就是转换得到的目标编码。应该注意的是,由于AL只有8位,所以表格的长度不能超过256。 XLAT指令是单字节指令(11010011B),执行时间为11个时钟周期,不影响标志位。 2017/3/21