第3章 指令系统和寻址方式 3.1指令系统概述 3.2 8088/8086CPU的寻址方式 3.3 指令的机器码表示方法(略)
3.1指令系统概述 1、指令、指令系统和程序 指令是CPU能执行的一个基本操作。 如:取数、加、减、乘、除、存数等 指令系统是CPU所能执行的全部操作,即全部指令 的集合。 不同的CPU,其指令系统不同。 程序是用户在使用计算机时,针对要解决的问题, 用一条条指令编写的指令的序列。
*一个CPU能执行什么操作,是工程人员设计和制造好的,是固定的,用户不能改变。 构成程序的指令在存储器中一般都是顺序存放,要破坏这种顺序性,必须由转移指令操作。 2、指令组成 计算机中指令由操作码和操作数两部分组成。一条指令可以由1~6个字节组成。 操作码-----指示计算机要执行的操作, 操作数-----指出在指令执行操作过程中的操作对象; 可以是操作数本身;可以是操作数地址或是地址的一部分;可以是指向操作数地址的指针或其他有关 操作数的信息。
3、指令的一般格式: 操作码字段: 在机器里只需对某种操作指定确定的二进制代码。 通常用指令的第一个字节表示,不够可以占第二个字节中的3位。 操作数字段: 操作数字段可以有一个,二个或三个。 例: INC CX ADD AX , BX
4、操作数的存放 操作数的存放不外乎三种情况: (1) 操作数包含在指令中 即指令的操作数字段包含操作数本身。这种操作数为立即数。——数在指令队列中,执行数度较快。 例:MOV AL , 08H (2)操作数包含在CPU的一个内部寄存器中 例:INC CX 指令中的操作数字段是CPU内部寄存器的一个编码。这种寻址方式称为寄存器寻址。——数在寄存器中,无需BIU去取,执行速度最快。
(3)操作数在内存数据区 操作数在内存数据区,操作数字段包含着此操作数地址。——存储容量大 在8086中,任何内存地址是由两部分组成: 段的基地址:存储单元所在段的基地址 (大部分情况是数据段寄存器DS中); 段内偏移量:此单元与段基地址的距离。 有效地址EA(Effective Address) : 段内偏移量为适应各种数据结构的需要,可以有几个部分组成,所以也把它称为有效地址EA。
3.2 8088/8086CPU的寻址方式 寻址方式: 寻找和获得操作数、操作数存放地址或指令转移地址的方法。分数据寻址和指令寻址。 本节介绍数据寻址,根据操作数的三处存放地点对应有三种基本寻址方式:立即寻址方式、寄存器寻址方式和存储器寻址方式。
3.2.1 立即寻址方式(Immediate addressing) 操作数直接存放在指令中,紧跟在操作码之后,作为指令 的一部分,存放在代码段里,这种操作数称为立即数。 立即数可以是8位或16位的。16位的立即数是高位字节放在高地址,低位字节放在低地址。 使用场合:经常用于给寄存器赋初值。 注意:只能用于源操作数字段,不能用于目的操作数字段。 例: MOV AX, 267; 数字 MOV AL, 10010011B AND 0FEH;表达式 MOV AL, PORT1;符号名 MOV AX, DATA1;段名
例: MOV AL,05H 指令执行后: (AL)=05H 例: MOV AX,3064H 指令执行后: (AX)=3064H 立即寻址方式
3.2.2 寄存器寻址方式( Register addressing ) 操作数在寄存器中,指令指定寄存器号。 对于16位操作数,寄存器可以是: AX,BX,CX,DX,SI,DI,SP,BP 以及段寄存器。 对于8位操作数,寄存器可以是: AL,AH,BL,BH,CL,CH,DL,DH。 寄存器寻址方式特点:指令长度短,执行速度快。
例: 指令执行前:(AX)=3064H (SS)=1234H MOV SS,AX 指令执行后: (SS)=3064H (AX)保持不变。 寄存器寻址方式 指令执行前: 指令执行后:
3.2.3 存储器寻址方式(Memory addressing) 1、直接寻址(Direct addressing) 操作数地址的16位偏移量(有效地址EA) ,直接包含在指令中, 存放在代码段中指令操作码之后。 操作数一般存放在数据段中, 必须先求出操作数的物理地址, 然后再访问存储器才能取得操作数。 物理地址 : PA=16d或(10H) ×(DS)+EA IBM PC机允许数据存放在数据段以外的其它段中。此时应在指令中指定段超越(可以是CS,SS,ES)。
例:MOV AX,[3100H] (DS)=6000H , (63100H)=3050H 则:(AX)=3050H 例:用符号地址代替数值地址。 MOV AX,VALUE 或 MOV AX,[VALUE] VALUE——变量名,代表有效操作数单元的符号地址。 如VALUE在附加段中,则应指定段超越。 MOV AX,ES:VALUE 或MOV AX,ES:[VALUE] 直接寻址方式
例: 假设TABLE是在数据段定义的一个字节数组的首地址标号(变量名),其偏移地址为1000H,则指令 MOV AL, TABLE MOV AL, [1000H] 是等效的。 指令 MOV AL, TABLE+2 MOV AL, [TABLE+2 ] MOV AL, [1000H+2] 也是等效的,都是直接寻址方式。
注意: (1)直接寻址方式适用于处理单个变量。 (2)直接寻址方式隐含的段寄存器是 DS, 8086/8088允许段超越,即允许使用 CS 、SS 、ES作为段寄存器,这时必须在指令中特别标明。 (3)IBM PC机中规定双操作数指令必须有一个操作数使用寄存器方式,这就是常常先要把一个变量送到寄存器中的原因。
2、寄存器间接寻址方式(Register indirect addressing) 操作数在存储器中,操作数地址的16位偏移量(有效地址EA)包含在:BP、BX、SI、DI寄存器中。 1)、若选择SI、DI、BX作为间接寻址 操作数一般在现行数据段区域中,用(DS)作为段地址。 即操作数物理地址为: 物理地址PA=16 d ×(DS)+(BX) 物理地址PA=16 d × (DS)+(SI) 物理地址PA=16 d × (DS)+(DI)
例:MOV BX,[DI] (DS)=6000H (DI)=2000H PA=62000H (62000H)=50A0H (BX)=50A0H 寄存器间接寻址方式 MOV BX,[DI]
操作数在堆栈段区域中,用SS寄存器的内容作为段地址。 操作数物理地址: PA=16d × (SS)+(BP) 例: MOV [BP], AX 执行前: (SS)=1000H , (BP)=3000H , (AX)=1234H 执行后:PA=13000H (13000H)=1234H 寄存器间接寻址方式 MOV [BP], AX 寄存器间接寻址方式 MOV [BP], AX
3 )、用 SI、DI、BX 、BP作为间接寻址允许段超越 指令中可以指定段超越前缀来取得其他段中的数据。 例: MOV ES:[DI], AX MOV DX, DS:[BP] 这种寻址方法可以用于表格处理,在循环结构程序设计中经常用到间址方式。
3、寄存器相对寻址方式(Register relative addressing) 或变址寻址 (Index Addressing) 操作数的有效地址(EA)是一个基址或变址寄存器的内容和指令中指定的8位或16位位移量(displacement)之和。
操作数一般在内存的数据段中,但允许段超越。 除有段超越前缀之外,形成物理地址有二种方式:
例: MOV AX, COUNT[BP] 或MOV AX, [COUNT+BP] 设COUNT为16位位移量。 指令执行前: (SS)=5000H, (BP)=3000H, COUNT=2040H, (AX)=1234H 指令执行后:EA=5040H PA=55040H (55040H)=5548H (AX)=5548H 寄存器相对寻址方式 MOV AX,COUNT[BP]
例: TABLE是在数据段定义的一个字节数组的首地址标号(变量名),则有如下程序: MOV SI, 5 MOV AL, TABLE[SI];or MOV AL, [TABLE+SI] ABC EQU 5 LEA SI, TABLE MOV AL, ABC[SI];or MOV AL, [ABC+SI]
用途:这种寻址方式同样用于表格处理。 例:某数据表的首地址为COUNT,修改基址或变址寄存器来取得表格中的值。 欲读取表中第10个数据,存放到(AL)中。 第10个数据的有效地址: EA= COUNT + 9 MOV SI , 09H MOV AL , [SI+COUNT] * 寄存器相对寻址方式也可以使用段超越前缀 MOV DL,ES:STRING[SI]
4、基址变址寻址方式(Based indexed addressing) 操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和,基址寄存器名和变址寄存器名均由指令指定。
除有段超越前缀之外,形成物理地址有二种方式:
例: MOV AX, [BX][SI] 或 MOV AX, [BX+SI] 执行指令前: (DS)=3200H, (BX)=0456H, (SI) =1094H (334EAH)=4567H 执行指令后: EA=14EAH PA=334EAH (AX)=4567H 基址加变址寻址方式 MOV AX,[BX+SI]
用途:这种寻址方式同样适用于数组或表格处理。 表格首地址 基址寄存器中, 用变址寄存器来访问数组中的元素。 二个寄存器都能修改, 所以比寄存器相对寻址更灵活。 这种寻址方式允许段超越。 使用段超越前缀格式: MOV AX,ES:[BX][SI]
5、相对基址加变址寻址方式(Relative based indexed addressing) 操作数有效地址是一个基址寄存器和一个变址寄存器的内容和8位或16位位移量之和 。
除有段跨越前缀之外,形成物理地址有二种方式:
例: MOV AX, MASK[BX][DI] MOV AX, MASK [BX+DI] MOV AX,[MASX+BX+DI] 执行指令前: (DS)=3000H (BX)=1346H (DI)=0500H MASK=1234H (32A7AH)=4050H 执行指令后: EA=2A7AH PA=32A7AH (AX)=4050H 相对基址加变址 MOV AX, MASK+[BX+DI]
用途之一: 这种寻址方式为堆栈处理提供方便: (BP) 栈顶(一般 BP 可指向栈顶) 从栈顶到数组的首地址可以用位移量表示(MASK)。 变址寄存器(SI)或(DI)——指向数组中某个元素。
小结: 1、三种类型操作数 综观8086/ 8088寻址方式,其操作数有三种类型: 立即操作数、寄存器操作数、存储器操作数。 综观8086/ 8088寻址方式,其操作数有三种类型: 立即操作数、寄存器操作数、存储器操作数。 2、三种类型操作数特点 (1)立即操作数 可以使用立即操作数指令有: 数据传送指令、算术运算指令(乘、除运算指令除外)、 逻辑运算指令等。 立即数只能作为源操作数,不能作为目标操作数。
寄存器操作数 寄存器操作数可能存放在: 8086 /8088的通用寄存器、地址指针或变址寄存器以及段寄存器。 对段寄存器ES 、DS 、SS进行赋值,不能将立即数直接送段寄存器,要将立即数送通用寄存器,再从通用寄存器送段寄存器。CS一般不用赋值。
隐含操作数 某些指令规定只能使用指定操作数寄存器, 从汇编形式看,似乎没有指出操作数,实际隐含某些特定寄存器操作数。该寄存器可能是:累加器 、通用寄存器、变址寄存器、某些段寄存器。
(3)、存储器操作数 存储器操作数可能存放在一个、二个、或四个存储器单元中。 操作数类型分别为:字节、字、双字。 存储器操作数可以作为源操作数,也可以作为目标操作数。 但不允许源操作数、目标操作数同时为存储器操作数。 存储器操作数的有效地址EA的取得方法: 直接寻址 寄存器间接寻址 相对寄存器寻址 基址加变址寻址 相对基址加变址寻址 存储器操作数的物理地址PA的取得方法: 一般存储器操作数指令中隐含段寄存器,有的指令允许段超越, 需要在指令中标明。
需说明的几个问题 1、指令中使用方括号的地址表达式必须遵循下列规则: * 立即数可以出现在方括号内,表示直接地址; * 只有SI、BP、DI、BX可以出现在方括号内,它们可以单独出现,也可以相加后出现,或以寄存器与立即数相加的形式出现,但BX和BP或SI和DI不能同时出现在同一个[ ]内。 * 方括号有相加的含义,下面几种写法都是等价的: 1200[BX][SI] [BX+1200][SI] [BX+ SI +1200] * 方括号内包含BP,则隐含使用SS提供基地址;其余情况均使用DS提供基地址。
2、段超越: 在8088系统中,数据通常在数据段中,但若需要,数据也可存放在码段,堆栈段以及附加段中,这种情况就是段超越。应用时,需在指令中加以说明。 例:MOV AX,ES:[0500H] ES表示数据在附加段中; : 是修改属性运算符。
3、其它寻址方式 (1)隐含寻址:指令中不指明操作数 (2)I/O端口寻址:8086有直接端口寻址和间接端口寻址两种方式,端口寻址范围分别为0-0FFH和0-FFFFH。 (3)转移类指令寻址 (4)一条指令有几种寻址方式 例:MOV AX, [SI]
3.3 指令的机器码表示方法(略) 8086指令系统采用变长指令,指令的长度可有1~6字节组成。
3.4 8088/8086CPU的指令系统 1. 数据传送(Data transfer) 2. 算术运算(Arithmetic) 8086/8088的指令系统中共有92种基本指令。 可以分成6个功能组: 1. 数据传送(Data transfer) 2. 算术运算(Arithmetic) 3. 逻辑运算和移位指令(Logic& Shift) 4. 串操作(String manipulation) 5. 控制转移(Control Transfer) 6. 处理器控制(Processor Control)
3.4.1 数据传送指令(Data transfer) 功能: 负责把数据、地址或立即数传 送到寄存器或存储单元。 特点: 它是计算机最基本、最重要的一种操作,使用比例最高。 种类(分四种): (一)通用传送指令(General Purpose Transfer) 包括: MOV, PUSH, POP ,XCHG, XLAT。
* 除 SAHF和POPF指令外,对标志位没有影响。 (二)输入输出指令(Input and Output) 包括: IN, OUT。 (三)目的地址传送指令(Address-object transfer) 包括: LEA, LDS, LES (四)标志传送指令(Flag register transfer) 包括 : LAHF, SAHF, PUSHF, POPF * 除 SAHF和POPF指令外,对标志位没有影响。
(一)通用传送指令(General Purpose Transfer) 8088提供方便灵活的通用的传送操作,适用于大多数操作数。 通用传送指令(除了XCHG以外)是唯一允许以段寄存器为操作数的指令。 通用传送指令包括: 1、MOV (Movement) 2、PUSH (Push word onto stack) POP (Pop word off stack) 3、XCHG (Exchange) 4、XLAT (Translate)
MOV dst, src ; (dst) (src) 目的 源 目的 源 功能: 把一个字节(B)或一个字(W)操作数由源传送至目的。 实现: 寄存器 寄存器/存储器之间; 立即数寄存器/存储器 寄存器/存储器段寄存器之间的数据传送。 说明:* 指令中至少要有一项明确指出传送的是字节还是字; * 可用不同的寻址方式; * 不影响标志位; * 源操作数不变; * 存储器之间,立即数与段寄存器,段寄存器之间不能用一条指令完成数据传送。 注意: 参看教材 P70
例: CPU内部寄存器之间的数据的任意传送(除了段寄存器CS和指令指针IP以外,注意:段寄存器之间不能传送,且段寄存器CS 不能做目的操作数)。 MOV DL,CH ; 8位寄存器 8位寄存器 MOV AX,DX ; 16位寄存器 16位寄存器 MOV SI, BP MOV DS,BX ;通用寄存器 段寄存器 MOV AX, CS ;段寄存器 通用寄存器
例:立即数传送至CPU内部通用寄存器组(AX、BX、CX、DX、BP、SP、SI、DI), 用于给寄存器赋初值。注意: 不能直接给段寄存器赋值 MOV CL,04H ;立即数8位寄存器 MOV AX,03FFH ;立即数16位寄存器 MOV WORD PTR [SI] ,057BH ;立即数存储器 MOV BYTE PTR MEM, 5 ;立即数存储器 思考:为什么加WORD PTR , BYTE PTR ?不加对吗?
例:CPU内部寄存器(除CS和IP外)与存储器(所有寻址方式)之间数据传送,可以实现一字节或一个字的传送。 注意:两存储单元之间不能直接传送 MOV MEM , AX ; 累加器存储器,直接寻址 MOV MEM ,DS ;段寄存器存储器,直接寻址 MOV DISP[BX] ,CX ;寄存器存储器,相对寻址 MOV AX , DISP[SI] ;存储器累加器,相对寻址 MOV DS , MEM ;存储器段寄存器,直接寻址 MOV CX , DISP [BX] [SI] ;存储器寄存器,相对基址加变址
MOV指令小结: 不能用一条MOV指令实现以下传送。 两存储单元之间的传送 MOV MEM2 , MEM1 错。 MOV AX , MEM1 MOV MEM2 , AX 对。 立即数送段寄存器 例 : MOV DS,2000H 错。 MOV AX, 2000H MOV DS , AX 对。
段寄存器之间的传送 MOV ES , DS ; 错 MOV AX , DS MOV ES , AX ; 对 。 注意CS和IP的使用 CS和IP不能作为目标操作数,CS可以作为源操作数。 例: MOV CS,AX ; 错 MOV AX,CS ;对 MOV IP, AX ;错
2、 PUSH 、 POP 指令 这是两条堆栈操作指令。 (1) 先复习什么是堆栈,为什么需要堆栈 堆栈——按照先进后出或后进先出原则组织的一段内存区域, 特点: 压入堆栈内容增加,SP的值减少。注意: SP——堆栈指针,始终指向栈顶。 先进后出工作原则( First In Last Out 简称FILO)
堆栈在内存中的情况 可以用一条立即数传送指令给SP赋值,确定SP在SS段中的初始位置。 例: 设: (SS)=9000H , 堆栈段为64KB MOV SP,0E200H ;(SP)=0E200H 则: 整个堆栈段的物理地址范围为: 90000H~9FFFFH 栈顶的物理地址为: 9E200H 堆栈在内存中的情况如右图所示: 堆栈在内存中的情况
堆栈用途: 存放CPU寄存器或存储器中暂时不使用的数据, 使用数据时将其弹出; 调用子程序, 响应中断时都要用到堆栈。 调用子程序, 响应中断时都要用到堆栈。 调用子程序(或过程)或发生中断时要保护断点的地址(即当前CS和IP的值),子程序或中断返回时再恢复断点。 在进入子程序和中断处理后,还需要保存通用寄存器的值,子程序或中断处理返回前,再恢复通用寄存器的值。 子程序嵌套或子程序递归(自调自)时,要使保留的许多信息正确返回,必须后进先出。
(2) 堆栈操作指令 (堆栈操作指令有两条): (2) 堆栈操作指令 (堆栈操作指令有两条): 入栈指令 格式:PUSH src ; (SP) (SP)-2 ((SP)+1,(SP)) (src) 先修改堆栈指针,然后把一个字从源操作数压入堆栈顶部。 操作如:PUSH AX 出栈指令 格式:POP dst ; (dst) ((SP)+1,(SP)) (SP) (SP)+2 把现行SP所指向堆栈顶部的一个字 弹出到目的操作数,再进行修改堆栈指针的操作。 操作如: POP BX
例: 存放CPU寄存器或存储器中暂时不使用的数据, 使用数据时将其弹出: PUSH AX ; 将(AX)入栈 (AX) (AX)
使用数据时将其弹出: POP BX
例: 调用子程序(或过程)或发生中断时要保护断点的地址, 子程序或中断返回时恢复断点。 子程序嵌套 断点地址压入和弹出情况
应用时注意: 堆栈操作都按字操作。低字节放在低地址,高字节放在高地址。 PUSH , POP 指令的操作数可能有三种: 寄存器(通用寄存器,地址指针,变址寄存器), 段寄存器(CS除外,PUSH CS 合法,POP CS 非法), 存储器。 堆栈工作原则后进先出,且 SP总是指向栈顶。 PUSH ,POP指令应该成对使用,保持堆栈原有状态。 堆栈最大容量为64KB。
堆栈应用举例: 例:用BP的基址指令 代替POP指令 例 : 压入堆栈的内容 … 与弹出内容顺序相反 MOV BP,SP PUSH AX … 例 : 压入堆栈的内容 与弹出内容顺序相反 … PUSH AX PUSH BX PUSH CX POP CX POP BX POP AX 例:用BP的基址指令 代替POP指令 … MOV BP,SP PUSH AX PUSH BX PUSH CX MOV CX,[BP-6] MOV BX,[BP-4] MOV AX,[BP-2] ADD SP, 6
3、 XCHG 交换指令 注意: 格式:XCHG dst , src ;(dst) (src) 执行操作: 把一个字节或一个字的源操作数与目的操作数相交换。 可以实现: 寄存器之间、寄存器和存储器之间信息的交换。 注意: 源、目的操作数的寻址方式不允许是立即寻址方式; 两存储器之间不能交换,即两个操作数中必须有一个在寄存器中; 段寄存器及IP寄存器不能作为一个操作数; 允许字或字节操作,不影响标志位。
应用举例: XCHG AX,SI XCHG COUNT[DI], AX XCHG DS, AX (错) XCHG BL,DL XCHG [BX],[DI] (错) XCHG DS, AX (错)
4、XLAT 换码指令 该指令不影响标志位。 格式: XLAT str_table;(AL)←((BX )+(AL)) 或 XLAT str_table——表格符号地址(首地址), 只是为了提高可读性而设置,汇编时仍用BX。
XLAT指令使用方法: 表格首偏移地址存入BX; 需要转换代码的序号(相对于表格首地址位移量)存入AL; (表中第一个元素的序号为0) 先建立一个字节表格; 表格首偏移地址存入BX; 需要转换代码的序号(相对于表格首地址位移量)存入AL; (表中第一个元素的序号为0) 执行XLAT指令后,表中指定序号的元素存于AL中。 (AL)为转换的代码。
例:内存的数据段中有一张十六进制数字的ASCII码表。 XLAT指令应用: 若把字符的扫描码转换成ASCII码; 或数字0~9转换成7段数码所需要的相应代码(字形码)等就要用XLAT指令。 例:内存的数据段中有一张十六进制数字的ASCII码表。 首地址为:Hex_table ,欲查出表中第10个元素(‘A’)
执行指令序列: MOV BX,OFFSET Hex_table MOV AL,0AH XLAT Hex_table 假设: (DS)=F000H, Hex_table=0040H (AL)=0AH 执行XLAT以后: (AL)=41H=(F004AH), 即“A”的ASCII码。 30H 31H 32H ... 39H 41H 42H 46H Hex_table Hex_table+1 Hex_table+2 Hex_table+0AH Hex_table+0BH Hex_table+0FH 'F' 'B' 'A' '9' '1' '2' '0' 16进制数的ASCII码表
(二)输入输出指令(Input and Output) 输入输出指令共两条: 1、IN (Input byte or word) 2 、OUT (Output byte or word) 输入指令用于CPU从外设端口接受数据, 输出指令用于CPU向外设端口发送数据。 无论接受还是发送数据,必须通过累加器AX(字)或AL(字节),又称累加器专用传送指令 。 输入、输出指令不影响标志位。
信息交换要通过端口 每个外设要占几个端口:数据口,状态口和控制口。
*访问端口不需要用任何段寄存器来修改它的值。 8086系统 端口地址由A0~A15译码形成。外部设备最多有65536个I/O端口。外设端口地址范围:0000H~FFFFH。 PC机 仅使用A0~A9译码形成I/O口地址,即1024个端口地址。 端口地址范围:0000H~03FFH,其中: A9=1,表示扩充槽上的口地址。 当端口地址是8位时(0~FFH),可以用直接寻址方式,即在指令中直接给出8位端口地址。 当端口地址超过8位(≥FFH)时,只能使用间接寻址方式。即先把端口地址放到DX寄存器中。且间接寻址仅能使用DX寄存器。 *访问端口不需要用任何段寄存器来修改它的值。
1、IN (Input byte or word) 输入指令 格式: IN AL, data8 ; 端口地址8位,输入一个字节 IN AX, data8 ;端口地址8位,输入一个字 IN AL, DX ;端口地址16位,输入一个字节 IN AX, DX ;端口地址16位,输入一个字 必须通过累加器AX(字)或AL(节)输入数据。
2 、OUT(Output byte or word) 输出指令 格式: OUT data8, AL ; 端口地址8位,输出一个字节 OUT data8, AX ;端口地址8位,输出一个字 OUT DX , AL ;端口地址16位,输出一个字节 OUT DX , AX ;端口地址16位,输出一个字 必须通过累加器AX(字)或AL(节)输出数据。
例1:实现端口(29H)(28H)→内存(DATA_WORD) IN AX,28H MOV DATA_WORD,AX 例2:从端口3FCH 送一个字到AX寄存器 MOV DX,3FCH IN AX,DX ; (AL)←(3FCH), (AH)←(3FDH) 例3:实现将(AL) →内存(05H) OUT 05H,AL;(05H)←(AL)
(三)地址传送指令(Address-object transfer) 8086 /8088 提供三条: 地址指针写入指定寄存器或寄存器对指令。 1、LEA(Load Effective Address) 2、LDS (Load pointer using DS) 3、LES (Load pointer using ES)
1、LEA(Load Effective Address) 格式:LEA reg16 , mem16;EA(reg16),源操作数为存储器 寻址方式 功能:加载有效地址,用于写近地址指针。 把指令中指定的存储器操作数有效地址装入指定的寄存器 。 例:设(BX)=0400H,(SI)=003CH LEA BX,[BX+SI+0F62H] 执行指令后: EA=(BX)+(SI)+0F62H=0400H+003CH+0F62H=139EH (BX)=139EH
注意:设 (DS)=3000H BUFFER=1000H (31000H)=0040H (1) LEA 与MOV指令的区别 LEA BX , BUFFER ;(BX)=1000H MOV BX , BUFFER ; (BX)=0040H 下两条指令功能等价: LEA BX , BUFFER ; (BX)=1000H MOV BX , OFFSET BUFFER ; (BX)=1000H
(2)LEA 指令中的目标寄存器必须是16位的通用寄存器, 源操作数必须是一个存储器。 错误指令: LEA DX , AX ;
2、LDS (Load pointer using DS) 格式:LDS reg16, mem32 ;(reg16)←(EA) (DS)←((EA)+2)) 功能:用于写远地址指针。 将指令指定32位地址指针送指令指定寄存器(不能是段寄存器)和DS寄存器中。 将指令指定mem32单元的前两个单元内容(16位偏移量)装入指定通用寄存器,把后两个单元内容(段地址) 装入到DS段寄存器。
3、LES (Load pointer using ES) 格式:LES reg16, mem32 ;(reg16)←(EA) (ES)←((EA)+2)) 功能:用于写远地址指针。 把源操作数指定的4个相继字节送指令指定的寄存器(不能是段寄存器)及ES寄存器中。 *此指令常常指定DI寄存器 将指令指定mem32单元的前两个单元内容(16位偏移量)装入指定通用寄存器,把后两个单元内容(段地址) 装入到ES段寄存器。
例: 假设: (DS)=C 000H 指令: LDS SI, [0010H] 执行指令后: (SI)=0180H (DS)=2000H
例: 假设: (DS)=B 000H (BX)=080AH 指令: LES DI, [BX] 执行指令后: (DI)=05A2H (ES)=4000H
综合举例: 设: (DS)=5000H TABLE=1000H 分析下列指令执行结果: MOV BX,TABLE ;(BX)=0040H MOV BX,OFFSET TABLE ;(BX)=1000H LEA BX,TABLE ;(BX)=1000H LES BX,TABLE ;(BX)=0040H,(ES)=3000H LDS BX,TABLE ;(BX)=0040H,(DS)=3000H
(四)标志传送指令(Flag register transfer) 采用了隐含寄存器(AH、Flags)操作数方式。 8088有四条标志传送操作指令: 1. LAHF(Load AH into flags) 2. SAHF(Store AH into flags) 3. PUSH F(Push flags onto stack) 4. POP F(Pop flags off stack)
1. LAHF(Load AH flags flags) 格式:LAHF ;(AH)←(PSW的低字节) 功能:标志寄存器低八位 (AH)。 LAHF指令操作图示意
2. SAHF(Store AH into flags) 格式:SAHF ;(PSW的低字节)←(AH) 功能:(AH)送标志寄存器低八位。 3. PUSH F(Push flags onto stack) 格式:PUSH F ;(SP)←(SP)-2 ((SP)+1,(SP))←(PSW) 功能 : 标志进栈。 4. POP F(Pop flags off stack) 格式:POP F;(PSW)←((SP)+1,(SP)) (SP)←(SP)+2 功能 :标志出栈。
SAHF、POPF由装入的值确定标志位的值, 即影响标志位。 (2)PUSHF、POPF用于保护调用过程前(PSW),过程返回后恢复。 注意: (1) 标志位的影响 LAHF、PUSHF不影响标志位; SAHF、POPF由装入的值确定标志位的值, 即影响标志位。 (2)PUSHF、POPF用于保护调用过程前(PSW),过程返回后恢复。 例: … PUSH AX PUSH CX PUSHF CALL TRANS POPF POP CX POP AX …
作业三: 教材:P120 习题 1,2,3,6
第1题答题格式说明 说明指令的源操作数和目的操作数各采用什么寻址方式? 设定如下: ①立即寻址 ②寄存器寻址 ③直接寻址 ④寄存器间接寻址 ⑤寄存器相对寻址 ⑥基址变址寻址 ⑦相对基址变址寻址 例:MOV AX,2408H; ② ①