第一章 计算机基础知识
第一节 计算机中的运算基础
一、数制及其转换
1)任意进制数的共同特点(n进制)n=2、8、10、16 ①、n进制数最多是由n个数码组成
十进制数的组成数码为:0~9 二进制数的组成数码为:0、1 八进制数的组成数码为:0~7
十六进制数的组成数码为:0~9、A~F
十六进制数和十进制数的对应关系是:
0~9相同,A-10,B-11,C-12,D-13,C-14,F-15
②、n进制数的基数或底数为n,作算术运算时,有如下特点:
低位向相邻高位的进位是逢n进1(加法); 低位向相邻高位的借位是以1当本位n(减法)。
③、各位数码在n进制数中所处位置的不同,所对应的权也不同。
以小数点为分界点: 向左(整数部分):各位数码所对应的权依次是n0、n1、n2,… 向右(小数部分):各位数码所对应的权依次是n-1、n-2、n-3,… 权:数制每一位所具有的值。 2)数制的转换
①、非十进制数→十进制数
转换方法:按位权展开求和
例:101.11B = 1*22+1*20+1*2-1+1*2-2
= 4+1+0.5+0.25 = 5.75
F94H = 15*162+9*161+4*160
= 3988
注意点:只有十进制数的下标可以省略,其他进制数不可以省略。 ②、十进制数→非十进制数(K进制数)
转换方法:分成小数和整数分别转换。
整数部分:除K取余,直至商为0,先得的余数为低位; 小数部分:乘K取整,先得的整数为高位。 例:把3988转换成16进制数
例:0001,1010,1110,1101,1011.0100B
1 A E D B 4 H
若十六进制数转换为二进制数,则将每一位拆成4位。
3)模的概念
模:恒量一个存储单元的最大容量也是一个机器所能处理的最大数据。
若a和b除以M,余数相等,则称a和b对于M 是同余的,则可以写成:a = b(mod M)
容器的最大容量称为模。
可写成:KM + X = X (mod M) 4)有符号数在计算机中的表示方法
在计算机中,一个有符号数可以用原码、补码和反码表示。 A) 共同规律:
①、用0表示正号,用1表示负号,且摆放在数据的最高位,有符号数和无符
号数表示的根本区别在于无符号数的最高位是数值位,有符号数的最高位是符号位;
②、同一正数的原、补、反码都相同。
③、定义区间均对模2n而言,其中n表示有符号数的二进制代码 位数。 B)其它规律:
①、任一负数的原码和对应的正数(绝对值相等)的原码仅是符号位不同; ②、任一负数的反码是表示其符号位为1,数值位取反; ③、任一负数的补码是其反码的最低位加1; ④、从定义区间上看
原码和反码的定义区间相同,是 –2n-1<X<2n-1; 补码的定义区间是 –2n-1≤X<2n-1;
⑤、0的原码、反码有+ 0和- 0之分;
0的补码只有一种表达方式。
例1:设X = +97 求[X]原、[X]反、[X]补 (mod 28)
解:97=110 0001B
[X]原=0110 0001B;
[X]反=[X]补=0110 0001B。
例2:设X = -97, 求[X]原、[X]反、[X]补 (mod 28)
解:97=110 0001B
[X]原=1110 0001B; [X]反=1001 1110B; [X]补=1001 1111B。
例3:设X = -137 求[X]原、[X]反、[X]补 (mod 29)
解:137=1000 1001B
[X]原=11000 1001B; [X]反=10111 0110B; [X]补=10111 0111B。
5)带符号数运算时的溢出问题 A)、溢出和进位的区别:
进位是指最高位向更高位的进位
溢出是指运算结果超出数所能表示的围。 带符号数所能表示的范围:(若用n位二进制数码表示) 原码:-(2n-1-1)≤X≤2n-1-1 补码:-2n-1≤X≤2n-1-1
反码:-(2n-1-1)≤X≤2n-1-1
B)、溢出的判断方法:
设CD_A是符号位向更高位的进位,CD_B是数值位向符号位的进位,则溢出可用V=CD_A⊕CD_B判断,V=1表示有溢出,V=0表示无溢出。对于加减法,也可以这样判断,只有下述4中情况有可能产生溢出: 正数+正数,结果应为正,若为正,则无溢出;若为负,则有溢出。 负数+负数,结果应为负,若为负,则无溢出;若为正,则有溢出。 正数-负数,结果应为正,若为正,则无溢出;若为负,则有溢出。 负数-正数,结果应为负,若为负,则无溢出;若为正,则有溢出。
对于乘(除)法,乘积(商)超过了能存放的范围有溢出,否则无溢出。 其它情况肯定无溢出。 C)、注意点:
无符号数和带符号数表示方法的区别:
无符号数:无符号位,所有位都是数值位,即最高位也是数值位; 带符号数:有符号数,且在最高位,其余各位才是数值位。 二进制数的减法运算
例如:Y=11(10)-8(10)=? (mod 25)
Y=11(10)-8(10) =11(10)+(-8(10)) =11(10)补+(-8(10))补 11(10)原=01011B -8(10)原=11000B -8(10)反=10111B -8(10)补=11000B 01011B
11000B 00011B
6)、基本名词
位 :BIT,缩写为b;
字节 :BYTE,由8位二进制数代码表示,缩写为B;
字 : WORD,取决于计算机CPU的字长,内部寄存器的位数,其中8086CPU
为16位,386、486CPU为32位;
千字节:1KB = 1024B = 210B ,
兆字节:1MB = 220B,
吉字节:1GB = 230B=1024MB 太字节:1TB = 240B=1024GB
第二节:计算机中数据的编码
一、十进制数在计算机中的表示方法
BCD(Binary Coded Decimal)是用4位二进制代码表示一位十进制数,由于4位二进制代码表示16种状态,而十进制数只取其中10种状态。选择不同的对应规律,可以得到不同形式的BCD码。最常用的是8421BCD码。由于在机内采用BCD码进行运算绕过了二进制、十进制间的复杂转化环节,从而节省了机器时间。 例:59 = (0101,1001)BCD
465 = (0100,0110,0101)BCD
(011010000010)BCD = (0110,1000,0010)BCD = 682
注意点:BCD码与二进制数之间不能直接转换,需将BCD码先转换成十进制数,再由十进制数转换为二进制数。与十六进制数的区别在于:组内逢2进1,组间逢十进1。
二、字符在计算机中的表示方法
由于大、小写英文字母、0~9数字字符、标点符号、计算机特殊控制符一共不超过128个,所以只要用七位二进制数码来表示,称为ASCII码。国际标准为ISO-646,我国国家标准为GB1988。在计算机中,一个字符通常用一个字节(八位)表示,最高位通常为0或用于奇偶校验位。 例: ’A’= 41H = 01000001B
’0’= 30H = 00110000B ’a’= 61H = 01100001B ’;’ = 3BH = 00111011B
ISO2022标准在兼容ISO646的基础上扩展成8位码,可表示256个字符,扩充了希腊字母、数学符号、非拉丁字符、商用图符,游戏符号等。 三、机器数和真值
机器数:是摆在计算机寄存器或存储器或I/O端口中的数; 真 值:描述机器数对应于某一确定的码制就有唯一确定的值。
例:机器数34H,用原码表示为+52;用反码表示为+52;用补码表示为+52;用
BCD码表示为34;用ASCII码表示为4。 即[+52]原=[+52]反=[+52]补=34H [34]BCD = 34H [4]ASCII = 34H
机器数97H,用原码表示为-23;用反码表示为-104;用补码表示为-105;用BCD码表示为97;用ASCII码表示为ETB。
第三节:数的定点和浮点表示
一、数的定点和浮点表示
定点表示:又称整数表示,小数点在数中的位置是固定不变的; 浮点表示:又称实数表示,小数点在数中的位置是浮动的。
一个任意实数,在计算机内部可以用指数(为整数)和尾数(为纯小数)来表示,用指数和尾数表示实数的方法称为浮点表示法。 对于任意一个二进制数N,可用N=S*2P表示, 其中S为尾数(二进制数),表示N的全部有效数字
P为阶码(二进制数)指明小数点的位置 2为阶码的底,
当阶码P为固定值时,数的这种表示法称为定点表示,这样的数称为定点数;
当阶码为可变时,数的这种表示法称为浮点表示,这样的数称为浮点数。 一个实数可表示成一个纯小数与一个乘幂之积。如 1011.101=0.1011101×2100 -0.0010011=-0.10011×2-10 -110001101=-0.110001101×21001
表示浮点数时指数选用什么编码?尾数的格式和小数点位置如何确定?起初不同的计算机有不同的规定,产生了相互间数据格式的不兼容。为此,IEEE制定了有关标准,并被普遍采用。
浮点数的长度可以是32位、64位甚至更长,分阶码和尾数两部分。阶码位数越多,可表示的数的范围越大;尾数越多,所表示的数的精度越高。
第二章 8086/8088微处理器及其系统结构
第一节
8086/8088CPU
一、总线接口部件BIU与执行部件EU
1、总线接口部件BIU:由4个16位段寄存器,一个16位指针寄存器。20位物理地址加法器,6字节指令队列(8088为4字节)及总线控制电路组成。负责与存储器及I/o端口 的数据传送,既BIU。根据执行部件EU计算出的16位偏移地址及16位段积存器提供的16位段地址,通过地址加法器产生20位物理地址。根据EU单元的请求,用20位物理地址对存储器进行读/写操作,也可对I/O口进行读/写操作。
无论8086还是8088都会在执行指令的同时,从内存中取下面一条或几条指令放在指令队列中。
2、执行部件EU:执行部件由ALU、寄存器阵列、标志寄存器FR、控制器等几个部分组成。其任务就是从指令队列中流取出指令,然后分析和执行指令,还负责计算操作数的16位偏移地址。 3、BIU和EU的管理
BIU和EU非同步工作,其管理原则为:
(1)指令队列有2个字节节空(8086)时, BIU会自动把下一条指令取到指令队
列中。
(2)EU在执行指令过程中,如果必须访问存储器或I/O设备,则EU会自动请求
BIU进入总线周期去完成访问存储器或I/O操作,此时若BIU空闲,就会立即完成EU请求。否则BIU将首先完成自己,将指令取至指令队列中的任务,再响应EU的请求。
(3)当指令队列已满,而EU又无请求时,BIU进入空闲状态。
(4)当EU执行转移类,调用及返回指令时,EU将不再用指令队列中顺序装入的
指令。此时指令队列中原有的内容被自动清除,而BIU会接着将另一程序段的指令装入指令队列
EU和BIU这种并行的工作方式极大地提高了CPU的工作效率。 二、系统总线
总线是部件之间进行数据(电信号)交换的通道。 80x86计算机的系统总线分为3类:
数据总线 地址总线 控制总线
1、数据总线
数据总线是用来传递数据的,定义了CPU在每个内存周期所能存取数据的位数。
80x86系列CPU的数据总线为8位、16位、32位或64位。这就是“为什么通常的数据存取是以8位、16位、32位或64位进行的”。
数据总线越宽,处理能力越强。
具有N位数据总线并不意味着CPU只能处理N位数据。 2. 地址总线
地址总线用来指出数据的地址(内存或I/O)。
地址总线的位数决定了最大可编址的内存与I/O空间。
对于N位地址总线,CPU可以提供2N个不同地址:0~2N -1。 地址总线由内存与I/O子系统共享使用(I/O只用低16位)。 3. 控制总线
控制总线用来控制CPU与内存和I/O设备之间的数据传送方(如传送方向)。 三、80x86 CPU的寄存器组
1. 通用寄存器
8位通用寄存器8个:AL、AH、BL、BH、CL、CH、DL、DH。 16位通用寄存器8个:AX、BX、CX、DX、SI、DI、BP、SP。
32位通用寄存器8个:EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP。 AL与AH、BL与BH、CL与CH、DL与DH分别对应于AX、BX、CX和DX的低8位与高8位。AX、BX、CX、DX、SI、DI、BP和SP分别对应于EAX、EBX、ECX、EDX、ESI、EDI、EBP和ESP的低16位。
AX:累加器,用累加器进行的操作可能需要更少时间,累加器可用于乘、除、
输入/出操作,它的使用频率很高。
BX:基地址寄存器,可作为存储器指针来使用。 CX:计数寄存器,在循环和字符串操作时,要用它来控制循环次数,在位操作中,当移多位时,要用CL来指明移位的位数。
DX:数据寄存器,在进行乘、除时,可作默认的操作数参与运算,也可用于存
放I/O的端口地址。
①寄存器:由触发器组成成一个触发器就是一个一位寄存器,由多个触发器可以组
成一个多们寄存器。
缓冲寄存器----用以暂存数据。
移位寄存器----能够提供所有存注数据一位一位地向左或 向右移。 计数器----一个计数脉冲到达时,会按二进制数的规律累 计脉冲数。 累加器----用以暂存每次ACU中计算的中间结果。
②存储器:是计算机的主要组成部分,它即可用来存储数据,也可用以存放计算机
的运算程序。存储器由寄存器组成,可以看作是一个程序寄存器堆。每个存储单元数据实际上相当于一个缓冲寄存器,可分为只读存储器(ROM),随机存储器(RAM)。
③数据寄存器:主要用来存储保存操作数和运算结果等信息,从而节省读取操作数
所须占用总线和访问存储器的时间。
SI、DI称为变址寄存器,它们主要用于存放存储单元在内的偏移量,用它们可实现多种存储器操作数的寻址方式。为以不同的地址形式访问存储单元提供方便。
变址寄存器不可分割成8位寄存器,作为通用寄存器,也可存放逻辑运算的操作数和运算结果。
BP、SP称为指针寄存器,主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式。乃以不同的地址形式访问存储单元提供方便。同上,不可分,也可存数据。
它们主要用于访问堆栈内的存储单元,并且规定: BP为基指针寄存器,用它可直接存取堆栈中的数据。 SP为堆栈指针寄存器,用它只可访问栈顶。
SI和DI分别用来存放字符串处理时,源操作数段内偏移地址和目的操作数段内偏移地址,故分别称作源变址寄存器和目的变址寄存器。
2. 专用寄存器
指令指针:EIP(32位)、IP(16位)。IP是EIP的低16位。 标志寄存器:EFLAGS(32位)、FLAGS(16位)。FLAGS是EFLAGS的低16位。
表2-1 寄存器的隐含用法 标志寄存器
标志寄存器(Flag Register)共有16位,其中7位未用。标志寄存器内容如图所示:
(1)状态(条件)标志 (2)控制标志 OF DF IF TF SF ZF AF PF CF 3. 段寄存器
6个16位的段寄存器:CS、DS、ES、SS、FS和GS。
FS、GS以及所有32位寄存器是从80386 CPU开始引入的。
第二节 堆栈的概念
一、堆栈的概念
堆栈是在存储器中划出的一块连续存储区,这个连续存储区的底端是固定的。另一端是活动的,可以上下进行浮动。所有出入这个存储区的信息都要从活动的一端出入,即堆栈中的数据遵循先进后出,后进先出的原则。在任何时刻,栈顶总是指向最后一个存入堆栈的数据的存储单元。
由图可知当TOP小于等于BOTTOM时堆栈为空,不存放任何数据;
当堆栈存有数据时候,TOP大于BOTTOM。 二、8086/8088堆栈的组织
在8086/8088系统中堆栈是由堆栈寄存器SS指定一段内存储区。堆栈的底P是堆栈段的最大地址单元。堆栈顶P(栈顶)由堆栈指针SP指向,SP中始终包含有段地址(起始地址)与栈顶之间的距离(字节数)。当堆栈初始化,SP的值为堆栈的长度(这时它指向栈底+1的单元)。如上图所示,由于SP是16位寄存器,因此堆栈的深度(长度,即能存放的字节数)最大是64KB.(8×8)。
8086/8088堆栈是按字进行组织,每次在堆栈中存取的数据都是两个字节。
第三节 8086的系统组
一、8086存储器的分段结构
8086 CPU中有四个段寄存器:CS,DS,SS和ES,这四个段寄存器存放了CPU当前可以寻址的四个段的基值,也即可以从这四个段寄存器规定的逻辑段中存取指令代码和数据。一旦这四个段寄存器的内容被设定,就规定了CPU当前可寻址的段,如图2-7所示。
图2-7 当前可寻址的存储器段(堆栈段和附加段重叠) 二.8086存储器的逻辑地址与物理
物理地址:内存单元的实际地址,也就是出现在地址总线上的地址。
逻辑地址:或称分段地址,记作 段地址: 段内偏移地址
段地址表示段在内存中的起始位置,通常被保存在某个段寄存器中。段内偏移地址表示内存单元相对于段起始位置的位移,简称偏移地址,也叫有效地址EA。
段地址与偏移地址都是16位。
系统采用下列方法将逻辑地址自动转换为20位的物理地址:
物理地址 = 段地址 × 16 + 偏移地址
每个内存单元具有唯一的物理地址,但可由不同的逻辑地址描述。 8086存储器的逻辑地址与物理地址
8086 CPU中的每个存储元在存储体中的位置都可以使用实际地址和逻辑地址来表示。
逻辑地址可表示为 段首地址:偏移地址
CPU访问存储器时,要形成20位的物理地址,即先找到某段,再找到该段内的偏移量。换句话说,CPU是以物理地址访问存储器的, 三.8086存储器20位物理地址的形成
在8086/8088存储空间中,把16字节的存储空间称作一节(Paragraph)。为了简化操作,要求各个逻辑段从节的整数边界开始,也就是说段首地址低4位应该是“0”,因此就把段首地址的高16位称为“段基址”,存放在段寄存器DS
或CS或SS或ES中,段内的偏移地址存放在IP或SP中。
例如,代码段寄存器CS=2000H,指令指针寄存器存放的是偏移地址IP=2200H,
存储器的物理地址为20000H+2200H=22200H
第三章 8086的寻址方式
第一节 概述
一、 概念
1、指 令:让计算机完成某种操作的命令。指令的集合称作指令系统。指令的
符号用规定的英文字母组成称为助记符。
2、语 言:计算机中真正可以处理的只是由 “0” “1”组成的二进制代码。这种指
令代码易出错且不易修改,由于依赖于机器,使 用极不方便,使人们发明了“指令的助记符”,用几个字母(往往就是其含义的英文单词或缩写)代替某条指令。如加法用ADD表示,这种符号系统的扩大就是汇编语言,使用汇编语言编程。优点是运行效率高,可直接对硬件内部进行控制。缺点是对硬件有更深入的了解,而且编程效率不高,并且与机器的体系结构仍有一定的依赖关系。
3、汇编程序:由于机器并不能直接识别和运行用汇编程序编制出的程序,必须
先转换成对应的机器代码指令,这项工作不用手工完成,仅须交给称为“汇编程序”的软件处理一下,即可得到可以直接运行的程序。人们将用汇编程序编出的程序称为“源程序”称用汇编程序处理后的程序为“目的程序”。
二、指令的组成
指令的组成
指令由操作码和操作数两部分组成 操作码说明计算机要执行哪种操作,如传送、运算、移位、跳转等操作,它是指令中不可缺少的组成部分用一个唯一的助记符表示(指令功能的英文缩写),对应着机器指令的一个二进制编码
操作数是指令执行的参与者,即各种操作的对象,可以是一个具体的数值,可以是存放数据的寄存器,或指明数据在主存位置的存储器地址 例:START:MOV AL,80H;将16进制数80H送入AL 标号是给指令所在地址取的名字
注释本身只用来对指令功能加以说明,给阅读程序带来方便,汇编程序对它不做任何处理。
有些指令不需要操作数,通常的指令都有一个或两个操作数,也有个别指令有3个甚至4个操作数 三、寻址方式
指令系统设计了多种操作数的来源 寻找操作数的过程就是操作数的寻址
操作数采取哪一种寻址方式,会影响机器运行的速度和效率 如何寻址一个操作数对程序设计很重要
第二节 8086的机器代码格式
一、8086的机器代码格式 1/2字节
mov ax,[BP+0] ;机器代码是 8B 46 00
前一个字节8B是操作码(含w=1表示字操作) 中间一个字节46(01 000 110)是 “mod reg r/m”字节
reg=000表示目的操作数为AX
mod=01和r/m=110表示源操作数为[BP+D8] 最后一个字节就是8位位移量〔D8=〕00 二、 其他机器代码形式
mov al,05 ;机器代码是B0 05
前一个字节B0是操作码(含一个操作数AL),后一个字节05是立即数 mov ax,0102H ;机器代码是B8 02 01 前一个字节B8是操作码(含一个操作数AX),后两个字节02 01是16位立即数(低字节02在低地址) 三、指令的助记符格式
操作码 操作数1,操作数2 ;注释
操作数2,称为源操作数 src,它表示参与指令操作的一个对象
操作数1,称为目的操作数 dest,它不仅可以作为指令操作的一个对象,还可以用来存放指令操作的结果 分号后的内容是对指令的解释 传送指令MOV的格式
MOV dest,src ;dest←src
MOV指令的功能是将源操作数src传送至目的操作数dest,例如:
MOV AL,05H ;AL←05H MOV BX,AX ;BX←AX MOV AX,[SI] ;AX←DS:[SI]
MOV AX,[BP+06H] ;AX←SS:[BP+06H]
MOV AX,[BX+SI] ;AX←DS:[BX+SI] 传送指令MOV的功能
0/1字节 0/1/2字节 0/1/2字节 第三节 立即数寻址方式
一、 定义
指令中的操作数直接存放在机器代码中,紧跟在操作码之后(操作数作为指令的一部分存放在操作码之后的主存单元中)
这种操作数被称为立即数imm,它可以是8位数值i8(00H~FFH) 也可以是16位数值i16(0000H~FFFFH),立即数寻址方式常用来给寄存器赋值
二、 立即数寻址指令
MOV AL,05H ;AL←05H MOV AX,0102H ;AX←0102H
第四节 寄存器寻址方式
一、 定义
操作数存放在CPU的内部寄存器reg中,可以是:
8位寄存器r8:
AH、AL、BH、BL、CH、CL、DH、DL 16位寄存器r16:
AX、BX、CX、DX、SI、DI、BP、SP 4个段寄存器seg: CS、DS、SS、ES
二、 寄存器寻址指令
MOV AX,1234H ;AX←1234H MOV BX,AX ;BX←AX
第五节 存储器寻址方式
一、 定义及分类
指令中给出操作数的主存地址信息(偏移地址,称之为有效地址EA),而段地址在默认的或用段超越前缀指定的段寄存器中 8086设计了多种存储器寻址方式 1、直接寻址方式
2、寄存器间接寻址方式 3、寄存器相对寻址方式 4、基址变址寻址方式 5、相对基址变址寻址方式
二、直接寻址方式
有效地址在指令中直接给出
默认的段地址在DS段寄存器,可使用段超越前缀改变 MOV AX,[2000H]
;AX←DS:[2000H] ;指令代码:A10020
MOV AX,ES:[2000H]
;AX←ES:[2000H] ;指令代码:26A10020
三、寄存器间接寻址方式
有效地址存放在基址寄存器BX或变址寄存器SI、DI中 默认的段地址在DS段寄存器,可使用段超越前缀改变
MOV AX,[SI] ;AX←DS:[SI]
四、寄存器相对寻址方式
有效地址是寄存器内容与有符号8位或16位位移量之和,寄存器可以是BX、BP或SI、DI
有效地址=BX/BP/SI/DI+8/16位位移量
段地址对应BX/SI/DI寄存器默认是DS,对应BP寄存器默认是SS;可用段超越前缀改变
寄存器相对寻址指令
MOV AX,[DI+06H] ;AX←DS:[DI+06H] MOV AX,[BP+06H] ;AX←SS:[BP+06 五、基址变址寻址方式
有效地址由基址寄存器(BX或BP)的内容加上变址寄存器(SI或DI)的内容构成:
有效地址=BX/BP+SI/DI
段地址对应BX基址寄存器默认是DS,对应BP基址寄存器默认是SS;可用段超越前缀改变 基址变址寻址指令
MOV AX,[BX+SI] ;AX←DS:[BX+SI] MOV AX,[BP+DI] ;AX←SS:[BP+DI]
MOV AX,DS:[BP+DI] ;AX←DS:[BP+DI] 六、相对基址变址寻址方式
有效地址是基址寄存器(BX/BP)、变址寄存器(SI/DI)与一个8位或16位位移量之和:
有效地址=BX/BP+SI/DI+8/16位位移量
段地址对应BX基址寄存器默认是DS,对应BP基址寄存器默认是SS;可用段超越前缀改变
相对基址变址寻址指令 MOV AX,[BX+SI+06H] ;AX←DS:[BX+SI+06H] 位移量可用符号表示
同一寻址方式有多种表达形式 七、几点注意事项 1、用符号表示位移量
在寄存器相对寻址或相对基址变址寻址方式中,位移量可用符号表示:
MOV AX,[SI+COUNT]
;COUNT是事先定义的变量或常量(就是数值)
MOV AX,[BX+SI+WNUM] ;WNUM也是变量或常量
2、多种表达形式
同一寻址方式可以写成不同的形式:
MOV AX,[BX][SI]
;等同于 MOV AX,[BX+SI] MOV AX,COUNT[SI]
;等同于 MOV AX,[SI+COUNT] MOV AX,WNUM[BX][SI]
;等同于 MOV AX,WNUM[BX+SI] ;等同于 MOV AX,[BX+SI+WNUM]
3、汇编语言指令格式
由4部分组成:
标号:指令助记符 目的操作数,源操作数 ;注释 标号表示该指令在主存中的逻辑 每个指令助记符就代表一种指令 目的和源操作数表示参与操作的对象 注释是对该指令或程序段功能的说明 4、为了描述方便,采用下列符号约定:
dest — 目的操作数
src — 源操作数
oprdn — 第n个操作数,如oprd1, oprd2, oprd3 = — 赋值 / — 或者
reg8 — 8位通用寄存器AH/AL/BH/BL/CH/CL/DH/DL reg16 — 16位通用寄存器AX/BX/CX/DX/SI/DI/BP/SP
reg32 — 32位通用寄存器EAX/EBX/ECX/EDX/ESI/EDI/EBP/ESP reg — reg8/reg16/reg32
seg — 段寄存器CS/DS/SS/ES/FS/GS mem8 — 8位内存操作数
mem16 — 16位内存操作数 mem32 — 32位内存操作数 mem — mem8/mem16/mem32 mem64 — 64位内存操作数 imm8 — 8位立即数 imm16 — 16位立即数 imm32 — 32位立即数 imm — imm8/imm16/imm32
第四章 8086的指令系统
第一节 数据传送类指令
一、 定义
数据传送是计算机中最基本、最重要的一种操作,传送指令也是最常使用的一类指令,传送指令把数据从一个位置传送到另一个位置,除标志寄存器传送指令外,均不影响标志位 重点掌握
MOV XCHG XLAT PUSH POP LEA
二、通用数据传送指令
提供方便灵活的通用传送操作,有3条指令MOV、XCHG、XLAT 1、传送指令MOV(move)
A)把一个字节或字的操作数从源地址传送至目的地址 MOV reg/mem,imm ;立即数送寄存器或主存 例4.1立即数传送
mov al,4 ;al←4,字节传送
mov cx,0ffh ;cx←00ffh,字传送 mov si,200h ;si←0200h,字传送
mov byte ptr [si],0ah ;byte ptr 说明是字节操作 mov word ptr [si+2],0bh ;word ptr 说明是字操作 MOV reg/mem,imm ;立即数送寄存器或主存 mov ax,bx ;ax←bx,字传送 mov ah,al ;ah←al, 字节传送 mov ds,ax ;ds←ax,字传送 mov [si],al ;[si]←al,字节传送
MOV reg/seg,mem ;主存送(段)寄存器 mov al,[bx]
mov dx,[bp] ;dx←ss:[bp] mov es,[si] ;es←ds:[si]
不存在存储器向存储器的传送指令
MOV reg/seg,mem ;主存送(段)寄存器 mov [si],ds
mov ax,es ;ax←es mov ds,ax ;ds←ax←es 对段寄存器的操作有一些限制 B)MOV指令传送功能 C)非法传送种类
(1)两个操作数的类型要一致
绝大多数双操作数指令,除非特别说明,目的操作数与源操作数必须类型一致,否则为非法指令例如源操作数是字节,而目的操作数是字;或相反 MOV AL,050AH ;非法指令:050Ah为字,而AL为字节
寄存器有明确的字节或字类型,有寄存器参与的指令其操作数类型就是寄存器的类型
对于存储器单元与立即数同时作为操作数的情况,必须显式指明;byte ptr指示字节类型,word ptr指示字类型 (2)两个操作数不能都是存储器
传送指令很灵活,但主存之间的直接传送却不允许
8086指令系统不允许两个操作数都是存储单元(除串操作指令),要实现这种传送,可通过寄存器间接实现
mov ax,buffer1 ;ax←buffer1(将buffer1内容送ax) mov buffer2,ax ;buffer2←ax
;这里buffer1和buffer2是两个字变量,实际表示直接寻址方式 (3)要小心段寄存器的操作
不允许立即数传送给段寄存器
MOV DS,100H ;非法指令:立即数不能传送段寄存器 不允许直接改变CS值
MOV CS,[SI] ;不允许使用的指令 不允许段寄存器之间的直接数据传送
MOV DS,ES ;非法指令:不允许段寄存器间传送
2、交换指令XCHG(exchange) 把两个地方的数据进行互换
XCHG reg,reg/mem ;reg reg/mem (1) 存器与寄存器之间对换数据 例4.6:寄存器间交换 mov ax,1234h ;ax=1234h mov bx,5678h ;bx=5678h xchg ax,bx
;ax=5678h,bx=1234h
xchg ah,al ;ax=7856h
(2)器与存储器之间对换数据 例4.7:寄存器与存储器交换 xchg ax,[2000h] ;字交换 ;等同于 xchg [2000h],ax xchg al,[2000h] ;字节交换 ;等同于 xchg [2000h],al
(3) 在存储器与存储器之间对换数据
3、换码指令XLAT(translate)
将BX指定的缓冲区中、AL指定的位移处的一个字节数据取出赋给AL XLAT ;al←ds:[bx+al]
换码指令执行前:在主存建立一个字节量表格,内含要转换成的目的代码,表格首地址存放于BX,AL存放相对表格首地址的位移量 换码指令执行后:将AL寄存器的内容转换为目标代码 例4.8:代码转换 mov bx,100h mov al,03h xlat 换码指令没有显式的操作数,但使用了BX和AL;因为换码指令使用了隐含寻址方式——采用默认操作数
三、堆栈操作指令
1、概念
(1) 堆栈是一个“后进先出LIFO”(或说“先进后出FILO”)的主存区域,位于堆
栈段中;SS段寄存器记录其段地址
堆栈只有一个出口,即当前栈顶;用堆栈指针寄存器SP指定 栈顶是地址较小的一端(低端),栈底不变
(2)堆栈和队列
堆栈:按照后进先出(LIFO)的原则组织的存储器空间(栈) 队列:按照先进先出(FIFO)的原则组织的存储器空间
(3)堆栈只有两种基本操作:进栈和出栈,对应两条指令PUSH和POP PUSH
;进栈指令先使堆栈指针SP减2,然后把一个字操作数存入堆栈顶部 POP
;出栈指令把栈顶的一个字传送至指定的目的操作数,然后堆栈指针SP加2 进栈指令PUSH
PUSH r16/m16/seg ;SP←SP-2 ;SS:[SP]←r16/m16/seg push ax
push [2000h]
出栈指令POP
POP r16/m16/seg ;r16/m16/seg←SS:[SP] ;SP←SP+2 pop ax
pop [2000h] 2、堆栈的特点
堆栈操作的单位是字,进栈和出栈只对字量
字量数据从栈顶压入和弹出时,都是低地址字节送低字节,高地址字节送高字节
堆栈操作遵循先进后出原则,但可用存储器寻址方式随机存取堆栈中的数据 堆栈常用来临时存放数据、传递参数、保存和恢复寄存器 例4.11:现场保护恢复
push ax ;进入子程序后 push bx push ds ...
pop ds ;返回主程序前 pop bx pop ax 四、标志寄存器传送指令
标志寄存器传送指令用来传送标志寄存器FLAGS的内容,方便进行对各个标志位的直接操作 有2对4条指令:
低8位传送:LAHF和SAHF 16位传送:PUSHF和POPF
1、标志低字节进出AH指令
LAHF ;AH←FLAGS的低字节
LAHF指令将标志寄存器的低字节送寄存器AH
SF/ZF/AF/PF/CF状态标志位分别送入AH的第7/6/4/2/0位,而AH的第5/3/1位任意
SAHF ;FLAGS的低字节←AH
SAHF将AH寄存器内容送FLAGS的低字节
用AH的第7/6/4/2/0位相应设置SF/ZF/AF/ PF/CF标志 2、标志寄存器进出堆栈指令
PUSHF ;SP←SP-2 ;SS:[SP]←FLAGS
PUSHF指令将标志寄存器的内容压入堆栈,同时栈顶指针SP减2 POPF ;FLAGS←SS:[SP] ;SP←SP+2
POPF指令将栈顶字单元内容送标志寄存器,同时栈顶指针SP加2 例4.12:置位单步标志 pushf ;保存全部标志到堆栈 pop ax ;从堆栈中取出全部标志
or ax,0100h ;设置D8=TF=1, ;ax其他位不变 push ax ;将ax压入堆栈
popf ;FLAGS←AX ;将堆栈内容取到标志寄存器 五、地址传送指令
地址传送指令将存储器单元的逻辑地址送至指定的寄存器
有效地址传送指令 LEA
指针传送指令 LDS和LES 注意不是获取存储器单元的内容 1、有效地址传送指令LEA(load EA)
将存储器操作数的有效地址传送至指定的16位寄存器中 LEA r16,mem ;r16←mem的有效地址EA 例4.13:获取有效地址 mov bx,0400h mov si,3ch
lea bx,[bx+si+0f62h]
;BX=0400h+003ch+0f62h=139EH
获得主存单元的有效地址;不是物理地址,也不是该单元的内容。可以实现计算功能
2、指针传送指令
LDS r16,mem ;r16←mem, ;DS←mem+2
LDS指令将主存中mem指定的字送至r16,并将mem的下一字送DS寄存器
LES r16,mem ;r16←mem, ;ES←mem+2 LES指令将主存中mem指定的字送至r16,并将mem的下一字送ES寄存器 例4.14:地址指针传送
mov word ptr [3060h],0100h mov word ptr [3062h],1450h
les di,[3060h] ;es=1450h,di=0100h lds si,[3060h] ;ds=1450h,si=0100h
mem指定主存的连续4个字节作为逻辑地址(32位的地址指针),送入DS:r16或ES:r16
六、输入输出指令
8086通过输入输出指令与外设进行数据交换;呈现给程序员的外设是端口(Port)即I/O地址
8086用于寻址外设端口的地址线为16条,端口最多为216=65536(64K)个,端口号为0000H~FFFFH 每个端口用于传送一个字节的外设数据 1、 输入输出寻址方式
8086的端口有64K个,无需分段,设计有两种寻址方式
(1)直接寻址:只用于寻址00H~FFH前256个端口,操作数i8表示端口号 (2)间接寻址:可用于寻址全部64K个端口,DX寄存器的值就是端口号 对大于FFH的端口只能采用间接寻址方式 2、输入指令IN
将外设数据传送给CPU内的AL/AX
IN AL,i8 ;字节输入:AL←I/O端口(i8直接寻址) IN AL,DX ;字节输入:AL←I/O端口(DX间接寻址) IN AX,i8 ;字输入:AX←I/O端口(i8直接寻址) IN AX,DX ;字输入:AX←I/O端口(DX间接寻址) 例4.15:输入字量
;直接寻址,字节量输入 in al,21h mov ah,al in al,20h
;直接寻址,字量输入
in ax,20h
;间接寻址,字量输入 mov dx,20h in ax,dx
两段功能相同,字量数据传送实际上实现了连续的两个端口地址的字节量传送
3、输出指令OUT
将CPU内的AL/AX数据传送给外设
OUT i8,AL ;字节输出:I/O端口←AL(i8直接寻址) OUT DX,AL ;字节输出:I/O端口←AL(DX间接寻址) OUT i8,AX ;字输出:I/O端口←AX(i8直接寻址) OUT DX,AX ;字输出:I/O端口←AX(DX间接寻址) 例4.16:输出字节量
;间接寻址,字节量输出 mov dx,3fch mov al,80h out dx,al
第二节 算术运算类指令
算术运算类指令
四则运算是计算机经常进行的一种操作。算术运算指令实现二进制(和十进制)数据的四则运算
请注意算术运算类指令对标志的影响
掌握:ADD/ADC/INC、SUB/SBB/DEC/ NEG/CMP 熟悉:MUL/IMUL、DIV/IDIV
理解:CBW/CWD、DAA/DAS、 AAA/ AAS/AAM/AAD
一、加法指令
1、加法指令ADD指令将源与目的操作数相加,结果送到目的操作数,ADD指令按状态标志的定义相应设置
ADD reg,imm/reg/mem ;reg←reg+imm/reg/mem ADD mem,imm/reg ;mem←mem+imm/reg 例4.17a:加法运算
mov al,0fbh ;al=0fbh add al,07h ;al=02h
mov word ptr [200h],4652h ;[200h]=4652h mov bx,1feh ;bx=1feh add al,bl ;al=00h
add word ptr [bx+2],0f0f0h ;[200h]=3742h 2、带进位加法指令ADC
ADC指令将源与目的操作数相加,再加上进位CF标志,结果送到目的操作数 ADC指令按状态标志的定义相应设置
ADC指令主要与ADD配合,实现多精度加法运算 ADC reg,imm/reg/mem ;reg←reg+imm/reg/mem+CF ADC mem,imm/reg ;mem←mem+imm/reg+CF 例4.18a:双字加法 mov ax,4652h ;ax=4652h
add ax,0f0f0h ;ax=3742h,CF=1 mov dx,0234h ;dx=0234h adc dx,0f0f0h ;dx=f325h,CF=0
;DX.AX=0234 4652H +F0F0 F0F0H =F325 3742H
3、增量指令INC(increment)
INC指令对操作数加1(增量)
INC指令不影响进位CF标志,按定义设置其他状态标志 INC reg/mem ;reg/mem←reg/mem+1 inc bx
inc byte ptr [bx] 二、 减法指令
1、减法指令SUB(subtract)
SUB指令将目的操作数减去源操作数,结果送到目的操作数 SUB指令按照定义相应设置状态标志
SUB reg,imm/reg/mem ;reg←reg-imm/reg/mem SUB mem,imm/reg ;mem←mem-imm/reg 例4.17b:减法运算
mov al,0fbh ;al=0fbh
sub al,07h ;al=0f4h,CF=0
mov word ptr [200h],4652h ;[200h]=4652h mov bx,1feh ;bx=1feh sub al,bl ;al=0f6h
sub word ptr [bx+2],0f0f0h ;[200h]=5562h,CF=1 2、带借位减法指令SBB
SBB指令将目的操作数减去源操作数,再减去借位CF(进位),结果送到目的操作数。
SBB指令按照定义相应设置状态标志
SBB指令主要与SUB配合,实现多精度减法运算
SBB reg,imm/reg/mem ;reg←reg-imm/reg/mem-CF SBB mem,imm/reg ;mem←mem-imm/reg-CF 例4.18b:双字减法 mov ax,4652h ;ax=4652h
sub ax,0f0f0h ;ax=5562h,CF=1 mov dx,0234h ;dx=0234h
sbb dx,0f0f0h ;dx=1143h,CF=1 ;DX.AX=0234 4652H -F0F0 F0F0H=1143 5562H 3、减量指令DEC(decrement)
DEC指令对操作数减1(减量)
DEC指令不影响进位CF标志,按定义设置其他状态标志
DEC reg/mem ;reg/mem←reg/mem-1
INC指令和DEC指令都是单操作数指令,主要用于对计数器和地址指针的调整 三、求补指令NEG(negative)
NEG指令对操作数执行求补运算:用零减去操作数,然后结果返回操作数 求补运算也可以表达成:将操作数按位取反后加1
NEG指令对标志的影响与用零作减法的SUB指令一样 NEG reg/mem ;reg/mem←0-reg/mem 例4.19:求补运算 mov ax,0ff64h
neg al ;ax=ff9ch,OF=0、SF=1、ZF=0、PF=1、CF=1 sub al,9dh ;ax=ffffh,OF=0、SF=1、ZF=0、PF=1、CF=1 neg ax ;ax=0001h,OF=0、SF=0、ZF=0、PF=0、CF=1 dec al ;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=1 neg ax ;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=0 四、比较指令CMP(compare)
CMP指令将目的操作数减去源操作数,按照定义相应设置状态标志 CMP指令执行的功能与SUB指令,但结果不回送目的操作数 CMP reg,imm/reg/mem ;reg-imm/reg/mem
CMP mem,imm/reg ;mem-imm/reg 例4.20:比较AL与100 cmp al,100 ;al-100 jb below ;al<100,跳转到below执行 sub al,100 ;al≥100, al←al-100 inc ah ;ah←ah+1
below: ...
执行比较指令之后,可以根据标志判断两个数是否相等、大小关系等 五、乘法指令
1、MUL r8/m8 ;无符号字节乘法 ;AX←AL×r8/m8
MUL r16/m16 ;无符号字乘法 ;DX.AX←AX×r16/m16 IMUL r8/m8 ;有符号字节乘法 ;AX←AL×r8/m8
IMUL r16/m16 ;有符号字乘法 ;DX.AX←AX×r16/m16 例4.21:乘法运算
mov al,0b4h ;al=b4h=180 mov bl,11h ;bl=11h=17
mul bl ;ax=Obf4h=3060 ;OF=CF=1,AX高8位不为0 mov al,0b4h ;al=b4h=-76 mov bl,11h ;bl=11h=17
imul bl ;ax=faf4h=-1292 ;OF=CF=1,AX高8位含有效数字
2、乘法指令的功能
乘法指令分无符号和有符号乘法指令
乘法指令的源操作数显式给出,隐含使用另一个操作数AX和DX 字节量相乘:AL与r8/m8相乘,得到16位的结果,存入AX
字量相乘:AX与r16/m16相乘,得到32位的结果,其高字存入DX,低字存入
AX
乘法指令利用OF和CF判断乘积的高一半是否具有有效数值 3、乘法指令对标志的影响
乘法指令如下影响OF和CF标志:
MUL指令——若乘积的高一半(AH或DX)为0,则OF=CF=0;否则OF=CF=1 IMUL指令——若乘积的高一半是低一半的符号扩展,则OF=CF=0;否则均为1 乘法指令对其他状态标志没有定义
对标志没有定义:指令执行后这些标志是任意的、不可预测(就是谁也不知道是0还是1)
对标志没有影响:指令执行不改变标志状态 六、除法指令
DIV r8/m8 ;无符号字节除法:
;AL←AX÷r8/m8的商,Ah←AX÷r8/m8的余数
DIV r16/m16 ;无符号字除法:
;AX←DX.AX÷r16/m16的商,DX←DX.AX÷r16/m16的余数 IDIV r8/m8 ;有符号字节除法:
;AL←AX÷r8/m8的商,Ah←AX÷r8/m8的余数 IDIV r16/m16 ;有符号字除法:
;AX←DX.AX÷r16/m16的商,DX←DX.AX÷r16/m16的余数 1、除法指令的功能
除法指令分无符号和有符号除法指令
除法指令的除数显式给出,隐含使用另一个操作数AX和DX作为被除数 字节量除法:AX除以r8/m8,8位商存入AL,8位余数存入AH 字量除法:DX.AX除以r16/m16,16位商存入AX,16位余数存入DX 除法指令对标志没有定义 除法指令会产生结果溢出 2、除法错中断
当被除数远大于除数时,所得的商就有可能超出它所能表达的范围。如果存放商的寄存器AL/AX不能表达,便产生溢出,8086CPU中就产生编号为0的内部中断——除法错中断
对DIV指令,除数为0,或者在字节除时商超过8位,或者在字除时商超过16位,则发生除法溢出
对IDIV指令,除数为0,或者在字节除时商不在-128~127范围内,或者在字除时商不在-32768~32767范围内,则发生除法溢出 例4.22:除法运算 mov ax,0400h ;ax=400h=1024 mov bl,0b4h ;bl=b4h=180
div bl ;商al=05h=5 ;余数ah=7ch=124 mov ax,0400h ;ax=400h=1024 mov bl,0b4h ;bl=b4h=-76
idiv bl ;商al=f3h=-13 ;余数ah=24h=36 七、符号扩展指令
CBW ;AL的符号扩展至AH
;如AL的最高有效位是0,则AH=00
;AL的最高有效位为1,则AH=FFH。AL不变
CWD ;AX的符号扩展至DX
;如AX的最高有效位是0,则DX=00
;AX的最高有效位为1,则DX=FFFFH。AX不变 符号扩展指令常用于获得倍长的数据 1、符号扩展的概念
符号扩展是指用一个操作数的符号位(即最高位)形成另一个操作数,后一个
操作数的各位是全0(正数)或全1(负数)。符号扩展不改变数据大小
对于数据64H(表示数据100),其最高位D7为0,符号扩展后高8位都是0,成为0064H(仍表示数据100) 对于数据ff00H(表示有符号数-256),其最高位D15为1,符号扩展后高16位都是1,成为ffffff00H(仍表示有符号数-256)
例4.23:符号扩展 mov al,80h ;al=80h cbw ;ax=ff80h add al,255 ;al=7fh cbw ;ax=007fh
例4.24:AX÷BX cwd ;DX.AX←AX
idiv bx ;AX←DX.AX÷BX
利用符号扩展指令得到除法指令所需要的倍长于除数的被除数
对无符号数除法应该采用直接使高8位或高16位清0的方法,获得倍长的被除数
八、十进制调整指令
1、十进制数调整指令对二进制运算的结果进行十进制调整,以得到十进制的运算结果
分成压缩BCD码和非压缩BCD码调整 压缩BCD码就是通常的8421码;它用4个二进制位表示一个十进制位,一个字节可以表示两个十进制位,即00~99
非压缩BCD码用8个二进制位表示一个十进制位,只用低4个二进制位表示一个十进制位0~9,高4位任意,通常默认为0 BCD码(Binary Coded Decimal)
二进制编码的十进制数:一位十进制数用4位二进制编码来表示 8086支持压缩BCD码和非压缩BCD码的调整运算 真值 8 64 二进制编码 08H 40H 压缩BCD码 08H 64H 非压缩BCD码 08H 0604H 2、压缩BCD码加、减调整指令 (ADD AL,i8/r8/m8) (ADC AL,i8/r8/m8)
DAA ;AL←将AL的加和调整为压缩BCD码 (SUB AL,i8/r8/m8) (SBB AL,i8/r8/m8)
DAS ;AL←将AL的减差调整为压缩BCD码
使用DAA或DAS指令前,应先执行以AL为目的操作数的加法或减法指令 DAA和DAS指令对OF标志无定义,按结果影响其他标志,例如CF反映压缩BCD码相加或减的进位或借位状态 例4.25a:压缩BCD加法
mov al,68h ;al=68h,压缩BCD码表示真值68 mov bl,28h ;bl=28h,压缩BCD码表示真值28 add al,bl ;二进制加法:al=68h+28h=90h
daa ;十进制调整:al=96h;实现压缩BCD码加法:68+28=96 例4.25b:压缩BCD减法
mov al,68h ;al=68h,压缩BCD码表示真值68
mov bl,28h ;bl=28h,压缩BCD码表示真值28 sub al,bl ;二进制减法:al=68h-28h=40h
das ;十进制调整:al=40h ;实现压缩BCD码加法:68-28=40 例4.26:压缩BCD减法 mov ax,1234h mov bx,4612h sub al,bl
das ;34-12=22,CF=0 xchg al,ah sbb al,bh
das ;12-46=66,CF=1
xchg al,ah ;1 1234-4612=6622 3、非压缩BCD码加、减调整指令 (ADD AL,i8/r8/m8) (ADC AL,i8/r8/m8)
AAA ;AL←将AL的加和调整为非压缩BCD码
;AH←AH+调整的进位
(SUB AL,i8/r8/m8) (SBB AL,i8/r8/m8)
AAS ;AL←将AL的减差调整为非压缩BCD码
;AH←AH-调整的借位
使用AAA或AAS指令前,应先执行以AL为目的操作数的加法或减法指令 AAA和AAS指令在调整中产生了进位或借位,则AH要加上进位或减去借位,同时CF=AF=1,否则CF=AF=0;它们对其他标志无定义 例4.27a:非压缩BCD加
mov ax,0608h ;ax=0608h,非压缩BCD码表示真值68 mov bl,09h ;bl=09h,非压缩BCD码表示真值9 add al,bl ;二进制加法:al=08h+09h=11h
aaa ;十进制调整:ax=0707h
;实现非压缩BCD码加法:68+9=77 例4.27b:非压缩BCD减
mov ax,0608h ;ax=0608h,非压缩BCD码表示真值68 mov bl,09h ;bl=09h,非压缩BCD码表示真值9 sub al,bl ;二进制减法:al=08h-09h=ffh
aas;十进制调整:ax=0509h;实现非压缩BCD码减法:68-9=59 4、非压缩BCD码乘、除调整指令 (MUL r8/m8)
AAM ;AX←将AX的乘积调整为非压缩BCD码
AAD ;AX←将AX中非压缩BCD码扩展成二进制数 (DIV r8/m8)
AAM指令跟在字节乘MUL之后,将乘积调整为非压缩BCD码
AAD指令跟在字节除DIV之前,先将非压缩BCD码的被除数调整为二进制数 AAM和AAD指令根据结果设置SF、ZF和PF,但对OF、CF和AF无定义 例4.27c:非压缩BCD乘
mov ax,0608h ;ax=0608h,非压缩BCD码表示真值68 mov bl,09h ;bl=09h,非压缩BCD码表示真值9 mul bl ;二进制乘法:al=08h×09h=0048h aam;十进制调整:ax=0702h ;实现非压缩BCD码乘法:8×9=72 例4.27d:非压缩BCD除
mov ax,0608h ;ax=0608h,非压缩BCD码表示真值68 mov bl,09h ;bl=09h,非压缩BCD码表示真值9 aam ;二进制扩展:ax=68=0044h
div bl ;除法运算:商al=07h,余数ah=05h
;实现非压缩BCD码初法:68÷9=7(余5)
第三节 位操作类指令
位操作类指令以二进制位为基本单位进行数据的操作;这是一类常用的指令,都应该特别掌握。注意这些指令对标志位的影响 逻辑运算指令
AND OR XOR NOT TEST 移位指令
SHL SHR SAR 循环移位指令
ROL ROR RCL RCR 一、 逻辑运算指令 1、逻辑与指令AND
对两个操作数执行逻辑与运算,结果送到目的操作数 AND reg,imm/reg/mem ;reg←reg∧imm/reg/mem AND mem,imm/reg ;mem←mem∧imm/reg
只有相“与”的两位都是1,结果才是1;否则,“与”的结果为0
AND指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义
2、逻辑或指令OR
对两个操作数执行逻辑或运算,结果送到目的操作数 OR reg,imm/reg/mem ;reg←reg∨imm/reg/mem OR mem,imm/reg ;mem←mem∨imm/reg 只要相“或”的两位有一位是1,结果就是1;否则,结果为0
OR指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义 3、逻辑异或指令XOR
对两个操作数执行逻辑异或运算,结果送到目的操作数 XOR reg,imm/reg/mem ;reg←reg⊕imm/reg/mem XOR mem,imm/reg ;mem←mem⊕imm/reg
只有相“异或”的两位不相同,结果才是1;否则,结果为0
XOR指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义
4、逻辑非指令NOT
对一个操作数执行逻辑非运算
NOT reg/mem ;reg/mem←~reg/mem
按位取反,原来是“0”的位变为“1”;原来是“1”的位变为“0” NOT指令是一个单操作数指令 NOT指令不影响标志位 例4.28:逻辑运算
mov al,45h ;逻辑与 al=01h
and al,31h ;CF=OF=0,SF=0、ZF=0、PF=0 mov al,45h ;逻辑或 al=75h
or al,31h ;CF=OF=0,SF=0、ZF=0、PF=0
mov al,45h ;逻辑异或 al=74h
xor al,31h ;CF=OF=0,SF=0、ZF=0、PF=1 mov al,45h ;逻辑非 al=0bah not al ;标志不变
例4.29:逻辑指令应用
;AND指令可用于复位某些位(同0相与),不影响其他位:将BL中D3和D0位清0,其他位不变 and bl,11110110B
;OR指令可用于置位某些位(同1相或),不影响其他位:将BL中D3和D0位置1,其他位不变 or bl, 00001001B
;XOR指令可用于求反某些位(同1相异或),不影响其他位:将BL中D3和D0位求反,其他不变 xor bl, 00001001B 5、测试指令TEST
对两个操作数执行逻辑与运算,结果不回送到目的操作数 TEST reg,imm/reg/mem ;reg∧imm/reg/mem TEST mem,imm/reg ;mem∧imm/reg 只有相“与”的两位都是1,结果才是1;否则,“与”的结果为0
AND指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义 例4.30:测试为0或1
test al,01h ;测试AL的最低位D0
jnz there ;标志ZF=0,即D0=1 ;则程序转移到there...
;否则ZF=1,即D0=0,顺序执行
there: ...
TEST指令通常用于检测一些条件是否满足,但又不希望改变原操作数的情况 二、 移位指令(shift) 1、移位指令(shift)
A)将操作数移动一位或多位,分成逻辑移位和算术移位,分别具有左移或右移操
作
SHL reg/mem,1/CL ;逻辑左移,最高位进入CF,最低位补0 SHR reg/mem,1/CL ;逻辑右移,最低位进入CF,最高位补0 SAL reg/mem,1/CL ;算术左移,最高位进入CF,最低位补0 SAR reg/mem,1/CL ;算术右移,最低位进入CF,最高位不变 B)移位指令的功能 C)移位指令的操作数
移位指令的第一个操作数是指定的被移位的操作数,可以是寄存器或存储单元 后一个操作数表示移位位数,该操作数为1,表示移动一位;当移位位数大于1时,则用CL寄存器值表示,该操作数表达为CL D)移位指令对标志的影响
按照移入的位设置进位标志CF
根据移位后的结果影响SF、ZF、PF 对AF没有定义
如果进行一位移动,则按照操作数的最高符号位是否改变,相应设置溢出标志OF:如果移位前的操作数最高位与移位后操作数的最高位不同(有变化),则OF = 1;否则OF = 0。当移位次数大于1时,OF不确定
例4.31:移位指令 mov cl,4
mov al,0f0h ;al=f0h
shl al,1 ;al=e0h ;CF=1,SF=1、ZF=0、PF=0,OF=0 shr al,1 ;al=70h ;CF=0,SF=0、ZF=0、PF=0、OF=1 sar al,1 ;al=38h ;CF=0,SF=0、ZF=0、PF=0、OF=0 sar al,cl ;al=03h ;CF=1,SF=0、ZF=0、PF=1 例4.32:移位乘法 mov si,ax
shl si,1 ;si←2×ax
add si,ax ;si←3×ax mov dx,bx mov cl,03h
shl dx,cl ;dx←8×bx sub dx,bx ;dx←7×bx
add dx,si ;dx←7×bx+3×ax
逻辑左移一位相当于无符号数乘以2 逻辑右移一位相当于无符号数除以2 2、循环移位指令(rotate)
将操作数从一端移出的位返回到另一端形成循环,分成不带进位和带进位,分别具有左移或右移操作
ROL reg/mem,1/CL ;不带进位循环左移 ROR reg/mem,1/CL ;不带进位循环右移 RCL reg/mem,1/CL ;带进位循环左移 RCR reg/mem,1/CL ;带进位循环右移 A)不带进位循环移位指令 B)循环移位指令对标志的影响
按照指令功能设置进位标志CF 不影响SF、ZF、PF、AF
如果进行一位移动,则按照操作数的最高符号位是否改变,相应设置溢出标志OF:如果移位前的操作数最高位与移位后操作数的最高位不同(有变化),则OF = 1;否则OF = 0。当移位次数大于1时,OF不确定 例4.33:32位数移位
;将DX.AX中32位数值左移一位 shl ax,1 rcl dx,1
例4.34:位传送
;把AL最低位送BL最低位,保持AL不变
ror bl,1 ror al,1 rcl bl,1 rol al,1
例4.35:BCD码合并
;AH.AL分别存放着非压缩BCD码的两位 ;将它们合并成为一个压缩BCD码存AL and ax,0f0fh ;保证高4位为0 mov cl,4
rol ah,cl ;也可以用shl ah,cl add al,ah ;也可以用or al,ah
第四节 串操作类指令
一、概念
1、 串操作指令是8086指令系统中比较独特的一类指令,采用比较特殊的数据串
寻址方式,在操作主存连续区域的数据时,特别好用、因而常用 重点掌握: MOVS STOS LODS CMPS SCAS REP 一般了解: REPZ/REPE REPNZ/REPNE 2、串数据类型
串操作指令的操作数是主存中连续存放的数据串(String)——即在连续的主存区域中,字节或字的序列 串操作指令的操作对象是以字(W)为单位的字串,或是以字节(B)为单位的字节串
3、串寻址方式
源操作数用寄存器SI寻址,默认在数据段DS中,但允许段超越:DS:[SI] 目的操作数用寄存器DI寻址,默认在附加段ES中,不允许段超越:ES:[DI] 每执行一次串操作指令,SI和DI将自动修改:
±1(对于字节串)或±2(对于字串)
执行指令CLD指令后,DF = 0,地址指针增1或2 执行指令STD指令后,DF = 1,地址指针减1或2
二、串传送MOVS(move string)
把字节或字操作数从主存的源地址传送至目的地址 MOVSB ;字节串传送:ES:[DI]←DS:[SI] ;SI←SI±1,DI←DI±1 MOVSW ;字串传送:ES:[DI]←DS:[SI] ;SI←SI±2,DI←DI±2 例4.36:字节串传送 mov si,offset source mov di,offset destination
mov cx,100 ;cx←传送次数 cld ;置DF=0,地址增加 again: movsb ;传送一个字节 dec cx ;传送次数减1
jnz again ;判断传送次数cx是否为0 ;不为0,则到again位置执行指令
;否则,结束 offset是汇编操作符,求出变量的偏移地址 例4.36:字串传送 mov si,offset source
mov di,offset destination
mov cx,50 ;cx←传送次数 cld ;置DF=0,地址增加 again: movsb ;传送一个字 dec cx ;传送次数减1 jnz again ;判断传送次数cx是否为0 ;不为0,则到again位置执行指令 ;否则,结束 三、串存储STOS(store string)
把AL或AX数据传送至目的地址 STOSB ;字节串存储:ES:[DI]←AL ;DI←DI±1
STOSW ;字串存储:ES:[DI]←AX
;DI←DI±2 例4.37:串存储 mov ax,0 mov di,0
mov cx,8000h ;cx←传送次数(32×1024) cld ;DF=0,地址增加 again: stosw ;传送一个字 dec cx ;传送次数减1
jnz again ;传送次数cx是否为0
可将CLD改为STD吗?如何改用STOSB? 可不用给DI赋值吗? 四、串读取LODS(load string)
把指定主存单元的数据传送给AL或AX
LODSB ;字节串读取:AL←DS:[SI] ;SI←SI±1 LODSW ;字串读取:AX←DS:[SI] ;SI←SI±2 例4.38:串读取-1 mov si,offset block
mov di,offset dplus mov bx,offset dminus mov ax,ds
mov es,ax ;数据都在一个段中,所以设置es=ds mov cx,count ;cx←字节数 cld
例4.38:串读取-2
go_on: lodsb ;从block取出一个数据 test al,80h ;检测符号位,判断是正是负 jnz minus ;符号位为1,是负数,转向minus
stosb ;符号位为0,是正数,存入dplus jmp again ;程序转移到again处继续执行 jnz go_on ;完成正负数据分离 例4.38:串读取-3 minus: xchg bx,di stosb ;把负数存入dminus xchg bx,di
again: dec cx ;字节数减1 jnz go_on ;完成正负数据分离 五、串比较CMPS(compare string)
将主存中的源操作数减去至目的操作数,以便设置标志,进而比较两操作数之间的关系
CMPSB ;字节串比较:DS:[SI]-ES:[DI] ;SI←SI±1,DI←DI±1 CMPSW ;字串比较:DS:[SI]-ES:[DI] ;SI←SI±2,DI←DI±2 例4.39a:比较字符串 mov si,offset string1 mov di,offset string2 mov cx,count
cld
again: cmpsb ;比较两个字符 jnz unmat ;有不同字符,转移 dec cx
jnz again ;进行下一个字符比较 mov al,0;字符串相等,设置00h jmp output ;转向output
unmat: mov al,0ffh ;设置ffh
output: mov result,al ;输出结果标记 六、串扫描SCAS(scan string)
将AL/AX减去至目的操作数,以便设置标志,进而比较AL/AX与操作数之间的关系
SCASB ;字节串扫描:AL-ES:[DI] ;DI←DI±1 SCASW ;字串扫描:AX-ES:[DI] ;DI←DI±2 例4.40a:查找字符串 mov di,offset string mov al,20h mov cx,count
cld
again: scasb ;搜索 jz found ;为0(ZF=1),发现空格 dec cx ;不是空格 jnz again ;搜索下一个字符... ;不含空格,则继续执行
found: ...
七、重复前缀指令(repeat)
串操作指令执行一次,仅对数据串中的一个字节或字量进行操作。但是串操作指令前,都可以加一个重复前缀,实现串操作的重复执行。重复次数隐含在CX寄存器中 重复前缀分2类,3条指令:
配合不影响标志的MOVS、STOS(和LODS)指令的REP前缀 配合影响标志的CMPS和SCAS指令的REPZ和REPNZ前缀
1、REP重复前缀指令
REP ;每执行一次串指令,CX减1
;直到CX=0,重复执行结束
REP前缀可以理解为:当数据串没有结束(CX≠0),则继续传送 例2.36和例2.37中,程序段的最后3条指令,可以分别替换为: REP MOVSB 和 REP STOSW 重复串传送(例4.36)
mov si,offset source
mov di,offset destination mov cx,100 ;cx←传送次数 cld
rep movsb
again: movsb ;传送一个字节 dec cx ;传送次数减1
jnz again ;判断传送次数cx是否为0
;不为0(ZF=0),则转移again位置执行 ;否则,结束
重复串存储(例4.37) mov ax,0 mov di,0
mov cx,8000h cld
rep stosw
again: stosw ;传送一个字 dec cx ;传送次数减1
jnz again ;判断传送次数cx是否为0 2、REPZ重复前缀指令 REPZ ;每执行一次串指令,CX减1 ;并判断ZF是否为0, ;只要CX=0或ZF=0,重复执行结束
REPZ/REPE前缀可以理解为:当数据串没有结束(CX≠0),并且串相等(ZF=1),则继续比较 REPNZ重复前缀指令 REPZ ;每执行一次串指令,CX减1 ;并判断ZF是否为1, ;只要CX=0或ZF=1,重复执行结束
REPNZ/REPNE前缀可以理解为:当数据串没有结束(CX≠0),并且串不相等(ZF=0),则继续比较 例4.39b:比较字符串 mov si,offset string1 mov di,offset string2 mov cx,count cld
repz cmpsb ;重复比较两个字符 jnz unmat ;字符串不等,转移 mov al,0;字符串相等,设置00h jmp output ;转向output
unmat: mov al,0ffh ;设置ffh output: mov result,al ;输出结果标记 重复比较的解释
指令repz cmpsb结束重复执行的情况 ① ZF=0,即出现不相等的字符 ② CX=0,即比较完所有字符:
这种情况下,如果ZF=0,说明最后一个字符不等;而ZF=1表示所有字符比较后都相等,也就是两个字符串相同
所以,重复比较结束后,jnz unmat指令的条件成立ZF=0,表示字符串不相等 例4.40b:查找字符串 mov di,offset string mov al,20h mov cx,count cld
repnz scasb ;搜索 jz found ;为0(ZF=1),发现空格 ... ;不含空格,则继续执行 found: ...
第五节 控制转移类指令
控制转移类指令
控制转移类指令用于实现分支、循环、过程等程序结构,是仅次于传送指令的最常用指令
重点掌握:JMP/Jcc/LOOP CALL/RET INT n/IRET 常用系统功能调用
一般了解: LOOPZ/LOOPNZ INTO
控制转移类指令通过改变IP(和CS)值,实现程序执行顺序的改变 一、无条件转移指令
JMP label ;程序转向label标号指定的地址
只要执行无条件转移指令JMP,就使程序转到指定的目标地址处,从目标地址处开始执行那里的指令
操作数label是要转移到的目标地址(目的地址、转移地址) JMP指令分成4种类型: ⑴ 段内转移、直接寻址 ⑵ 段内转移、间接寻址 ⑶ 段间转移、直接寻址 ⑷ 段间转移、间接寻址 1、目标地址的寻址方式 直接寻址方式
转移地址象立即数一样,直接在指令的机器代码中,就是直接寻址方式 间接寻址方式
转移地址在寄存器或主存单元中,就是通过寄存器或存储器的间接寻址方式 2、目标地址的范围:段内
段内转移——近转移(near)
在当前代码段64KB范围内转移( ±32KB范围) 不需要更改CS段地址,只要改变IP偏移地址 段内转移——短转移(short)
转移范围可以用一个字节表达,在段内-128~+127范围的转移
3、目标地址的范围:段间 段间转移——远转移(far)
从当前代码段跳转到另一个代码段,可以在1MB范围 需要更改CS段地址和IP偏移地址
目标地址必须用一个32位数表达,叫做32位远指针,它就是逻辑地址 实际编程时,汇编程序会根据目标地址的距离,自动处理成短转移、近转移或远转移
程序员可用操作符short、near ptr 或far ptr 强制 A)段内转移、直接寻址
JMP label ;IP←IP+位移量
位移量是紧接着JMP指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移
当向地址增大方向转移时,位移量为正;向地址减小方向转移时,位移量为负
jmp again ;转移到again处继续执行 ……
again: dec cx ;标号again的指令 …… jmp output ;转向output ……
output: mov result,al ;标号output的指令 B)段内转移、间接寻址
JMP r16/m16 ;IP←r16/m16
将一个16位寄存器或主存字单元内容送入IP寄存器,作为新的指令指针,但不修改CS寄存器的内容 jmp ax ;IP←AX
jmp word ptr [2000h] ;IP←[2000h] C)段间转移、直接寻址
JMP far ptr label ;IP←label的偏移地址 ;CS←label的段地址
将标号所在段的段地址作为新的CS值,标号在该段内的偏移地址作为新的IP值;这样,程序跳转到新的代码段执行
jmp far ptr otherseg ;远转移到代码段2的otherseg D)段间转移、间接寻址
JMP far ptr mem ;IP←[mem],CS←[mem+2]
用一个双字存储单元表示要跳转的目标地址。这个目标地址存放在主存中连续的两个字单元中的,低位字送IP寄存器,高位字送CS寄存器
mov word ptr [bx],0
mov word ptr [bx+2],1500h
JMP far ptr [bx] ;转移到1500h:0 二、 条件转移指令
Jcc label ;条件满足,发生转移:IP←IP+8位位移量 ;条件不满足,顺序执行
指定的条件cc如果成立,程序转移到由标号label指定的目标地址去执行指令;条件不成立,则程序将顺序执行下一条指令 操作数label是采用短转移,称为相对寻址方式 1、相对寻址方式
Jcc指令的操作数label是一个标号 一个8位位移量,表示Jcc指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移
8位位移量是相对于当前IP的,且距当前IP地址-128~+127个单元的范围之内,属于段内短距离转移 Jcc目标地址就采用这种相对寻址方式
Jcc指令为2个字节,条件不满足时的顺序执行就是当前指令偏移指针IP加2
2、Jcc指令的分类
Jcc指令不影响标志,但要利用标志(表4.4)。根据利用的标志位不同,17条指令分成4种情况: ⑴ 判断单个标志位状态 ⑵ 比较无符号数高低 ⑶ 比较有符号数大小 ⑷ 判断计数器CX为0 3、条件转移指令中的条件
实际虽然指令只有16条,但却有30个助记符 采用多个助记符,只是为了方便记忆和使用 4、判断单个标志位状态
这组指令单独判断5个状态标志之一
⑴JZ/JE和JNZ/JNE:利用零标志ZF,判断结果是否为零(或相等) 例4.39:JZ/JNZ指令
repz cmpsb ;重复比较两个字符 jnz unmat ;ZF=0(不等),转移 mov al,0;顺序执行(相等) jmp output
unmat: mov al,0ffh output: mov result,al repz cmpsb ;重复比较两个字符
jz mat ;ZF=1(相等),转移 mov al,0ffh ;顺序执行(不等) jmp output mat: mov al,0 output: mov result,al
⑵JS和JNS:利用符号标志SF,判断结果是正是负 例4.41:JS/JNS指令 ;计算|X-Y|(绝对值)
;X和Y为存放于X单元和Y单元的16位操作数 ;结果存入result
mov ax,X sub ax,Y jns nonneg neg ax ;neg是求补指令 nonneg: mov result,ax
⑶JO和JNO:利用溢出标志OF,判断结果是否产生溢出 例4.42:JO/JNO指令 ;计算X-Y;
;X和Y为存放于X单元和Y单元的16位操作数 ;若溢出,则转移到overflow处理
mov ax,X sub ax,Y jo overflow ... ;无溢出,结果正确 overflow: ... ;有溢出处理
⑷JP/JPE和JNP/JPO:利用奇偶标志PF,判断结果中“1”的个数是偶是奇 例4.43:JP/JNP指令
;设字符的ASCII码在AL寄存器中 ;将字符加上奇校验位
;在字符ASCII码中为“1”的个数已为奇数时
;则令其最高位为“0”;否则令最高位为“1” and al,7fh ;最高位置“0”,同时判断“1”的个数 jnp next ;个数已为奇数,则转向next or al,80h ;否则,最高位置“1” next: ...
⑸JC/JB/JNAE和JNC/JNB/JAE:利用进位标志CF,判断结果是否进位或借位
例4.44:JC/JNC指令 ;记录BX中1的个数 xor al,al ;AL=0,CF=0
again: test bx,0ffffh ;等价于 cmp bx,0 je next shl bx,1 jnc again inc al jmp again
next: ... ;AL保存1的个数 另一种做法
记录BX中“1”的个数 xor al,al ;AL=0,CF=0 again: cmp bx,0 jz next shl bx,1 ;也可使用 shr bx,1 adc al,0 jmp again
next: ... ;AL保存1的个数 比较无符号数高低
无符号数的大小用高(Above)低(Below)表示 利用CF确定高低、利用ZF标志确定相等(Equal) 两数的高低分成4种关系: ⑴ 低于(不高于等于):JB(JNAE) ⑵ 不低于(高于等于):JNB(JAE) ⑶ 低于等于(不高于):JBE(JNA) ⑷ 不低于等于(高于):JNBE(JA ) 例4.45a:比较无符号数 cmp ax,bx ;比较ax和bx jnb next ;若ax≥bx,转移 xchg ax,bx ;若ax<bx,交换 next: ...
结果:AX保存较大的无符号数 比较有符号数大小
例4.45b:比较有符号数 cmp ax,bx ;比较ax和bx jnl next ;若ax≥bx,转移 xchg ax,bx ;若ax<bx,交换
next: ...
结果:AX保存较大的有符号数 计数器CX为0转移 (6)JCXZ label
;CX=0,发生转移:IP←IP+8位位移量 ;CX≠0,顺序执行
这是一条较特殊的指令
CX寄存器通常在程序中用做计数器 JCXZ指令用来判断计数是否为0 判断计数器为0(例4.36)
mov cx,100
again: movsb ;传送一个字节 dec cx ;传送次数减1 jnz again ;判断传送次数cx是否为0 ;不为0(ZF=0),则转移;否则,结束 mov cx,100
again: jcxz next ;判断传送次数cx是否为0 movsb dec cx jmp again
next: ...
三、循环指令(loop)
LOOP label ;CX←CX-1, ;CX≠0,循环到标号label
LOOPZ label ;CX←CX-1, ;CX≠0且ZF=1,循环到标号label LOOPZ label ;CX←CX-1, ;CX≠0且ZF=0,循环到标号label
循环指令利用CX计数器自动减1,方便实现计数循环的程序结构 label操作数采用相对寻址方式 例4.46:记录空格个数
mov cx,count ;设置循环次数 mov si,offset string xor bx,bx ;bx清0,用于记录空格数 mov al,20h
again: cmp al,es:[si] jnz next ;ZF=0,非空格,转移 inc bx ;ZF=1,是空格,个数加1 next: inc si loop again ;字符个数减1,不为0继续循环 四、 子程序指令
子程序是完成特定功能的一段程序
当主程序(调用程序)需要执行这个功能时,采用CALL调用指令转移到该子程序的起始处执行
当运行完子程序功能后,采用RET返回指令回到主程序继续执行 主程序与子程序 1、子程序调用指令
CALL指令分成4种类型(类似JMP) CALL label ;段内调用、直接寻址 CALL r16/m16 ;段内调用、间接寻址 CALL far ptr label ;段间调用、直接寻址
CALL far ptr mem ;段间调用、间接寻址
CALL指令需要保存返回地址:
段内调用——入栈偏移地址IP
SP←SP-2,SS:[SP]←IP
段间调用——入栈偏移地址IP和段地址CS
SP←SP-2,SS:[SP]←IP SP←SP-2,SS:[SP]←CS 2、子程序返回指令
根据段内和段间、有无参数,分成4种类型 RET ;无参数段内返回
RET i16 ;有参数段内返回 RET ;无参数段间返回 RET i16 ;有参数段间返回
需要弹出CALL指令压入堆栈的返回地址
段内返回——出栈偏移地址IP
IP←SS:[SP], SP←SP+2
段间返回——出栈偏移地址IP和段地址CS
IP←SS:[SP],SP←SP+2 CS←SS:[SP],SP←SP+2 返回指令RET的参数
RET i16 ;有参数返回 RET指令可以带有一个立即数i16, 则堆栈指针SP将增加,即 SP←SP+i16
这个特点使得程序可以方便地废除若干执行CALL指令以前入栈的参数 例4.47:子程序 ;主程序 mov al,0fh ;提供参数AL call htoasc ;调用子程序
...
;子程序:将AL低4位的一位16进制数转换成ASCII码 htoasc: and al,0fh ;只取al的低4位 or al,30h ;al高4位变成3 cmp al,39h ;是0~9,还是0Ah~0Fh jbe htoend add al,7 ;是0Ah~0Fh,加上7 htoend: ret ;子程序返回 五、 中断指令
中断(Interrupt )是又一种改变程序执行顺序的方法
中断具有多种中断类型 中断的指令有3条:
INT i8 IRET INTO
本节主要掌握类似子程序调用指令的中断调用指令INT i8,进而学习使用DOS功能调用
中断的过程
中断请求可以来自处理器外部的中断源,也可以由处理器执行指令引起: 例如执行INT i8指令。 1、8086的外部中断
8086可以管理256个中断 各种中断用一个向量编号来区别 主要分成外部中断和内部中断
外部中断——来自CPU之外的原因引起的中断,又可以分成
可屏蔽中断:可由CPU的中断允许标志IF控制 非屏蔽中断:不受CPU的中断允许标志IF控制
2、8086的内部中断
内部中断——CPU内部执行程序引起的中断,又可以分成:
除法错中断:执行除法指令,结果溢出产生的 0 号中断 指令中断:执行中断调用指令INT i8产生的 i8 号中断 断点中断:用于断点调试(INT 3)的 3 号中断 溢出中断:执行溢出中断指令,OF=1产生的 4 号中断 单步中断:TF=1在每条指令执行后产生的 1 号中断
中断指令INT
INT i8 ;中断调用指令:产生i8号中断 IRET ;中断返回指令:实现中断返回
INTO ;溢出中断指令: ;若溢出标志OF=1,产生4号中断
;否则顺序执行
六、 系统功能调用
21H号中断是DOS提供给用户的用于调用系统功能的中断,它有近百个功能供用户选择使用,主要包括设备管理、目录管理和文件管理三个方面的功能
ROM-BIOS也以中断服务程序的形式,向程序员提供系统的基本输入输出程序
汇编语言程序设计需要采用系统的各种功能程序
充分利用操作系统提供的资源是程序设计的一个重要方面,需要掌握 功能调用的格式
通常按照如下4个步骤进行:
⑴ 在AH寄存器中设置系统功能调用号
⑵ 在指定寄存器中设置入口参数
⑶ 执行指令INT 21H(或ROM-BIOS的中断向量号)实现中断服务程序的功能调用
⑷ 根据出口参数分析功能调用执行情况 输入输出类功能调用
向显示器输出字符 ⒈ 字符的输出
⒉ 字符串的输出 从键盘输入数据 ⒊ 字符的输入 ⒋ 字符串的输入
⒌ 按键的判断
字符输出的功能调用
DOS功能调用INT 21H
功能号:AH=02H
入口参数:DL=字符的ASCII码
功能:在显示器当前光标位置显示给定的字符,光标右移一个字符位置。如按Ctrl-Break或Ctrl-C则退出
例4.48:显示问号
;在当前显示器光标位置显示一个问号 mov ah,02h ;设置功能号:ah←02h
mov dl,'?' ;提供入口参数:dl←'?' int 21h ;DOS功能调用:显示
进行字符输出时,当输出响铃字符(07H)以及退格(08H)、回车(0DH)和换行(0AH)字符时,该功能调用可以自动识别并能进行相应处理 字符输出的功能调用
显示器功能调用INT 10H
功能号:AH=0EH
入口参数:AL=字符的ASCII码
BL=字符的颜色值(图形方式) BH=页号(字符方式) 通常使BX=0
功能:将字符按原属性在光标处显示,光标自动移到下一个字符位置
字符串输出的功能调用
DOS功能调用INT 21H
功能号:AH=09H 入口参数:
DS:DX=欲显示字符串在主存中的首地址 字符串应以$(24H)结束
功能:在显示器输出指定的字符串
可以输出回车(0DH)和换行(0AH)字符产生回车和换行的作用 例4.49:显示字符串
string db 'Hello,Everybody !',0dh,0ah,'$' ;在数据段定义要显示的字符串 ... mov ah,09h ;设置功能号:ah←09h mov dx,offset string ;提供入口参数:dx←字符串的偏移地址 int 21h ;DOS功能调用:显示 字符输入的功能调用
DOS功能调用INT 21H
功能号:AH=01H
出口参数:AL=字符的ASCII码 功能:获得按键的ASCII代码值
调用此功能时,若无键按下,则会一直等待,直到按键后才读取该键值 例4.50:判断按键
getkey: mov ah,01h ;功能号:ah←01h int 21h ;功能调用 cmp al,’Y’ ;处理出口参数al je yeskey ;是“Y” cmp al,’N’ je nokey ;是“N” jne getkey ... yeskey: ...
nokey: ...
字符输入的功能调用
键盘功能调用INT 16H
功能号:AH=0
出口参数:AX=键值代码
对于标准ASCII码按键:AL=ASCII码,AH=扫描码; 对于扩展按键:AL=00H,AH=键扩展码;
对于alt+小键盘数字按键:AL=ASCII码,AH=00H
此功能类同DOS功能01H,会一直等待按键 例4.51:字符输入输出
mov ah,0 ;键盘功能调用(int 16h) int 16h ;al←按键的ASCII码
mov bx,0 ;显示功能调用(int 10h) mov ah,0eh int 10h ;显示
字符串输入的功能调用
DOS功能调用INT 21H
功能号:AH=0AH
入口参数:DS:DX=缓冲区首地址
执行该功能调用时,用户按键,最后用回车确认
本调用可执行全部标准键盘编辑命令;用户按回车键结束输入,如按Ctrl+Break或Ctrl+C则中止
缓冲区的定义
第1字节事先填入最多欲接收的字符个数(包括回车字符,可以是1~255) 第2字节将存放实际输入的字符个数(不包括回车符) 第3字节开始将存放输入的字符串
实际输入的字符数多于定义数时,多出的字符丢掉,且响铃 扩展ASCII码(如功能键等)占两个字节,第1个为0 例4.52:输入字符串
buffer db 81 ;定义缓冲区
;第1个字节填入可能输入的最大字符数 db 0 ;存放实际输入的字符数 db 81 dup(0) ;存放输入的字符串 ... mov dx,seg buffer ;伪指令seg取得buffer的段地址 mov ds,dx ;设置数据段DS mov dx,offset buffer
mov ah,0ah int 21h
按键判断的功能调用
DOS功能调用INT 21H
功能号:AH=0BH
出口参数:AL=0,当前没有按键;
AL=FFH,当前已经按键。
功能:仅判断当前是否有按下的键,设置AL后退出
例4.53:按任意键继续 ... ;提示“按任意键继续”
getkey: mov ah,0bh int 21h or al,al ;al=0? jz getkey ;al=0,没有按键,继续等待 按键判断的功能调用
键盘功能调用INT 16H
功能号:AH=1
出口参数:若标志ZF=1,无键按下;
若ZF=0,有键按下,且AX=键值代码
功能:此子功能仅判断是否按键,设置零位标志ZF后退出
这两个功能调用都不循环等待按键,即使有键按下,键盘缓冲区仍然保留键值并且没有被清空,必要时必须用字符输入功能取走键值清空缓冲区
七、处理机控制类指令
这些指令在特定的情况下,必须使用 对标志位进行设置的指令
CLC STC CMC CLD STD CLI STI
对CPU状态进行控制的指令 NOP CS: SS: DS: ES:
LOCK HLT ESC WAIT
进位标志操作指令
用于任意设置进位标志 CLC ;复位进位标志:CF←0 STC ;置位进位标志:CF←1 CMC ;求反进位标志:CF←~CF 方向标志操作指令
串操作指令中,需要使用
CLD ;复位方向标志:DF←0 STD ;置位方向标志:DF←1 中断标志操作指令
在编写中断服务程序时,需要控制可屏蔽中断的允许和禁止 CLI ;复位中断标志:DF←0 STI ;置位中断标志:DF←1 空操作指令 NOP
不执行任何操作,但占用一个字节存储单元,空耗一个指令执行周期
NOP常用于程序调试
在需要预留指令空间时用NOP填充 代码空间多余时也可以用NOP填充 还可以用NOP实现软件延时
事实上,NOP和XCHG AX,AX的指令代码一样,都是 90H 段超越前缀指令
在允许段超越的存储器操作数之前,使用段超越前缀指令,将采用指定的段寄存器寻址操作数
CS: ;使用代码段的数据 SS: ;使用堆栈段的数据
DS: ;使用数据段的数据 ES: ;使用附加段的数据 封锁前缀指令
LOCK ;封锁总线
这是一个指令前缀,可放在任何指令前
这个前缀使得在这个指令执行时间内,8086 处理器的封锁输出引脚有效,即把总线封锁,使别的控制器不能控制总线;直到该指令执行完后,总线封锁解除
暂停指令
HLT ;进入暂停状态
暂停指令使CPU进入暂停状态,这时CPU不进行任何操作。当CPU发生复位或来自外部的中断时,CPU脱离暂停状态
HLT指令可用于程序中等待中断。当程序中必须等待中断时,可用HLT,而不必用软件死循环。然后,中断使CPU脱离暂停状态,返回执行HLT的下一条指令
交权指令
ESC 6位立即数,reg/mem
;把浮点指令交给浮点处理器执行
浮点协处理器8087指令是与8086的整数指令组合在一起的,当8086发现是一条浮点指令时,就利用ESC指令将浮点指令交给8087执行 实际编写程序时,一般采用易于理解的浮点指令助记符格式 ESC 6,[SI] ;实数除法指令:FDIV dword ptr [SI] ESC 20H,AL ;整数加法指令:FADD ST(0),ST 等待指令
WAIT ;进入等待状态
8086利用WAIT指令和测试引脚实现与8087同步运行
浮点指令经由8086处理发往8087,并与8086本身的整数指令在同一个指令序列;而8087执行浮点指令较慢,所以8086必须与8087保持同步
第五章 输入/输出接口
[教学目的]:1.掌握常用进位计数制及输入/输出(I/O)接口电路是计算机的重要组成部分。通过I/O接口电路可实现计算机与外部设备通讯,与外部设备交换信息。 在微机系统中,最常用的外部设备有键盘、显示器、打印机、磁盘机等。在工业微机控制系统中,I/O接口电路还可通过A/D转换器或D/A转换器与各种工业检测和控制仪表相连接,这些仪表装置也属于外部设备。
第一节 接口与接口技术
所谓接口就是微处理器或微机与外界的连接部件(电路),它是CPU与外界进行信息交换的中转站。 一、接口的功能
CPU与外设(或总线与外设)之间的借口,从解决CPU与外设在连接时存在的矛盾的观点,一般应具有如下功能: 1、数据缓冲功能
为了解决CPU高速与外设低速的矛盾,避免因速度不一致而丢失数据,接口中一般都设置数据寄存器或锁存器,称之为数据口。为了实现CPU与外设之间的联络,接口电路还要提供寄存器“空”、“满”、“准备好”、“忙”、“闲”等状态信号,以便向CPU报告接口或外设的工作情况,称之为状态口。 2、接收和执行CPU命令的功能
CPU对I/O设备的控制命令一般均以代码的形式送到接口的命令寄存器,称之为命令口,再由接口电路对命令代码进行识别和分析,产生若干个控制信号,再传到I/O设备,使其产生相应的具体操作。 3、信号转换功能
由于外设所需的控制信号和它所能提供的状态信号往往与微机的总线信号不匹配,信号变换就不可避免。因此,信号转换包括CPU的信号与外设信号的逻辑关系、时序配合以及电平匹配上的转换,它是接口设计中的一个重要内容。 4、设备选择功能
微机系统中一般带有多种外设,同一种外设也可能配备多台,一台外设也可能包含多个I/O端口,这就要借助于接口中的地址译码电路对外设进行I/O端口寻址。
5、中断管理功能
当外设需要及时得到CPU的服务,特别是在出现故障时,在接口中设置中断控制器,为CPU处理有关中断事务(如发出中断请求、进行中断优先级排队、提供中断向量等),这样既做到微机系统对外界的实时响应,又使CPU与外设并行工作,提高了CPU的效率。 6、数据宽度变换的功能
CPU能直接处理的是并行数据(8位、16位或32位等),而有的外设(如串行通信设备、绘图仪、电传打字机等)只能处理串行数据,在这种情况下,接口就应具有数据“并→串”和“串→并”变换的能力。
7、可编程功能
现在的接口芯片基本上都是可编程的,这样在不改动硬件的情况下,只修改响应的驱动程序就可以改变接口的工作方式,大大的增加了接口的灵活性和可扩充性。
二、输入/输出的控制方式 1、程序控制:
是指在程序控制下进行信息传送。
无条件传送方式:当外设已准备就绪,那就不必查询外设的状态而进行信息传输,这就称之为无条件传送,这种信息传送方式只适用于简单的个设,如开关和数码段显示器等。
条件传送方式:CPU通过执行程序不断读取并测试外设状态,如果输入外设处于已准备好状态或输出外设为空闲状态时,则CPU执行传送信息指令。 2、中断控制方式
中断控制方式一般用来传送低速外设与CPU之间的信息交换。当外设需要与CPU进行数据交换时,由接口部件的CPU发出一个中断请求信号,CPU响应这一中断请求,便可在中断服务程序中完成一个字节或一个字的信息交换。这样操作一次,CPU要打断原来执行的程序去执行一般中断服务程序,对速度较高的外设会产生信息丢失,因此不能采用。 3、DMA控制方式
DMA控制方式是一种成块传送数据的方式。当某一外设需要输入/输出一批数据时,向DMA控制器发出请求,DMA控制器接收到这一请求后,向CPU发出总线请求,若CPU响应DMA的请求把总线使用权赋给DMA控制器,数据不通过CPU,可直接在DMA控制器操纵下进行的控制功能。 4、输入/输出处理机控制方式
对于有大量输入/输出设备的微机系统,DMA控制方式已不能满足这种需要。当CPU需要进行输入或输出操作时只需在存储器中建立一个规定格式的信息块,设置好需要执行的操作和有关参数,然后把这些参数送入8089,IOP即会执行输入/输出操作。 三、通信基础知识
计算机与个设或其他计算机交换信息,称计算机通信有两种方式——并行和串行。
并行通信——个数据的各位通过各自的信号线同时传输。
特点:传输速度快,但传输所需信号线多,距离越远成本越高适于短距离的高速传输
串行通信——数据各位通过同一信号线一位一位地顺序传输。
特点:传输所需信号线少,成本低,传输速度较慢,适合于远距离传输。 四、端口地址编址方式
I/O端口寻址方式有两种:一种是存储器映射方式,即把端口地址与存储器
地址统一编址,所以这种编址方式也称之为统一编址方式;另一种是I/O映射方式,即把I/O端口地址与存储器地址分别进行独立的编址,也称之为独立编址。 1、统一编址
这种编址方式是从存储空间中划出一部分地址空间分配给I/O设备,而把I/O接口中的端口作为存储器单元一样进行访问,不设置专门的I/O指令。 在统一编址方式中,可以将I/O端口看作是内存单元。从原则上说,用于内存的指令均可用于外设,这给使用者提供了极大的方便。但由于I/O端口占用了内存地址,就相对减少了内存可用范围。而且,从指令上不易区分是访问内存还是访问外的指令,这种编址方式在68系列微机中得到广泛使用。 2、独立编址
在这种编址方式中,内存地址空间和I/O端口地址是相对独立的。比如,在8086/8088CPU中,其内存地址是从00000H~FFFFFH连续的1M字节。其I/O端口的地址范围从0000H~FFFFH,它们互相独立,互不影响。同时,设置了专门的IN、OUT等I/O指令。内存与端口独立编址,各自有自己的寻址空间,用于内存和I/O用于端口的指令是不一样,很容易辨认。但是用于I/O端口的指令功能较弱,在I/O操作中必须通过CPU的寄存器进行中转才能完成。
第二节、可编程并行通信接口芯片8255A
一、8255A的内部结构及其功能
1、外围设备接口部份(通道A、B、C)
端口A —一个8位数据输入锁存器;一个8位数据输出锁存/缓冲器。 用作输入端口或出端口数据均受锁存。
端口B —一个8位数据输入缓冲器;一个8位数据输入/出,锁存/缓冲器。 用作输入端口时可以不锁,而且作输出时数据受到锁存。
端口C—具有一个8位数据输入缓冲器,一个8位数据输出锁存/缓冲口,一般作为控制或状态信息端口,可分成两个4位端口(高位、低位),分别和A、B配合。当CPU与外围设备连接不须要联络控制线时,通道C可以与A、B一样作为输入/出的数据通道。
2、内部逻辑部分(A、B组控制部件)
A、B两组控制电路每组控制电路从读/写控制逻辑接收各种命令,从内部数据总线接收控制字并发出相应命令到各自端口,控制各个端口的工作方式还可以根据CPU的命令对C的每一位置或复位。 A组控制A与C高4位(PC7-PC4) B组控制B与C低4位(PC3-PC6)
3、数据总线缓冲器:CPU接口部分包括数据总线缓冲器和读/写控制逻辑。
数据缓冲器是8255A与CPU数据总线的接口,所有数据的输入/出。以及CPU与8255A的控制,从8255A读出的外围设备状态信息,都是通过这个缓冲
器传送的。
4、读/写控制部件
接收有关控制信号,REDET、WR、RD和地址总线的A1A0,地址译码信息号CS对A、B组控制电路实施控制,管理内部和外部数据,状态或控制字的传送。
二、8255A芯片的控制字及其工作方式
8255A中各端口可有三种基本工作方式: (1)方式0—基本输入/输出方式; (2)方式1—选通输入/输出方式; (3)方式2—双向传送方式
端口A可处于三种工作方式(方式0,方式1和方式2),端口B只可处于两种
方式(方式0和方式1),端口C常常被分成高4位和低4位两部分,可分别用来传送数据或控制信息。
用户可用软件来分别定义三个端口的工作方式,可使用的控制字有定义工作方
式控制字和置位/复位控制字。 1.控制字
(1)定义工作方式控制字 (2)置位/复位控制字 三、工作方式 (1)工作方式0
这是8255A中各端口的基本输入/输出方式。 (2)工作方式1
被称作选通输入/输出方式,在这种工作方式下,数据输入/输出操作要在选通
信号控制下完成。
采用工作方式1进行输入操作时,需要使用的控制信号如下: 1)STB—选通信号。由外部输入,低电平有效。
2)IBF—输入缓冲器满信号。向外部输出,高电平有效。 3)INTR—中断请求信号。向CPU输出,高电平有效。
采用工作方式1也可完成输出操作,这时需要使用的控制信号如下: 1)OBF—输出缓冲器满信号。向外部输出,低电平有效。
2)ACK—外部应答信号。向外部输入,低电平有效。 3)INTR—中断请求信号。向CPU输出,高电平有效。 从图8-13中可看出,当端口A和端口B同时被定义为工作方式1完成输出操作时,端口C的PC6,7和PC3—PC0被用作控制信号,只有PC4,5两位可完成数据输入或输出操作。因此可构成两种组合状态。 1)端口A、B输出,PC4,5输入; 2)端口A、B输出, PC4,5输出;
采用工作方式1时,还允许将端口A和端口B分别定义为输入和输出
端口。如果将端口A定义为方式输入端口,而将端口B定义为方式1输出端口,则其方式控制字格式如图8-14所示。
从图8-15a可看出,这种情况下端口C的PC5—PC0用作控制信号,只有PC7,6可作数据输入/输出用,这又能构成两种状态:
1)端口A输入,端口B输出PC7,6输入。 2)端口A输入,端口B输出PC7,6输出。 反之,如果将端口A定义为方式1输出,将端口B定义为方式1输入,其方式控制字如图8-16所示。经过这样定义是端口状态如图8-15b所示。从图8-15b可看出,端口C的PC7和PC6,PC3—PC0分别用作控制信号,只有PC4和PC5可作数据输入/输出用,根据PC4,5的两种方式又可组合成两种端口状态: 1)端口A输出,端口B输入,PC4,5输入; 2)端口A输出,端口B输入,PC4,5输出。 (3)工作方式2 被称作带选通的双向传送方式。
8255A中只允许端口A处于工作方式2,可用来在两台处理机之间实现双向并行通信。其有关的控制信号由端口C提供,并可向CPU发出中断请求信号。 端口A工作于方式2所需控制信号如下:
①OBFA—输出缓冲器满信号。向外部输出,低电平有效。 ② AC —应答信号。由外部输入,低电平有效。
③STBA —数据选通信号。由外部输入,低电平有 效。 ④ IBFA—输入缓冲器满信号。向外部输出,高电平有效。 ⑤INTR—中断请求信号。向本端CPU输入,高电平有效。
因篇幅问题不能全部显示,请点此查看更多更全内容