440 likes | 555 Views
第 6 讲 8086 指令系统(续) 2006.10.24 (星期二). 可以分成 6 个功能组: 1 . 数据传送 (Data transfer) 2 . 算术运算( Arithmetic ) 3 . 逻辑运算和移位指令 (Logic& Shift) 4 . 串操作 (String manipulation) 5 . 控制转移( Control Transfer ) 6 . 处理器控制( Processor Control ). 1 . 数据传送 (Data transfer) (一)通用传送指令( General Purpose Transfer )
E N D
第6讲 8086指令系统(续)2006.10.24(星期二) 可以分成6个功能组: 1. 数据传送(Data transfer) 2. 算术运算(Arithmetic) 3. 逻辑运算和移位指令(Logic& Shift) 4. 串操作(String manipulation) 5. 控制转移(Control Transfer) 6. 处理器控制(Processor Control)
1. 数据传送(Data transfer) (一)通用传送指令(General Purpose Transfer) (二)输入输出指令(Input and Output) (三)目的地址传送指令(Address-object transfer) (四)标志传送指令(Flag register transfer)
(三)目的地址传送指令(Address-object transfer) 8086 /8088 提供三条: 地址指针写入指定寄存器或寄存器对指令。 已知变量DDR对应一内存单元DS :EA (1000H:2000H) LEA BX,DDR表明把DDR的偏移量2000H送入BX寄存器。 1、LEA(Load Effective Address)(熟练掌握内容) 格式: LEA reg16 , mem16 ;EA(reg16) 功能:加载有效地址,用于写近地址指针。 把指令中指定的存储器操作数有效地址装入指定的寄存器 。 例: LEA BX,[SI]得到什么?
例:设(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 指令与MOV等价: LEA BX , BUFFER ; (BX)=1000H MOV BX , OFFSET BUFFER ; (BX)=1000H (2)LEA 指令中的目标寄存器必须是16位的通用寄存器, 源操作数必须是一个存储器。 (3)请思考下列指令的正、误 LEA DX ,BETA[BX][SI] (对) LEA DX , AX(错)
2、LDS (Load pointer using DS) 格式:LDS reg16, mem32 ;(reg16)←(EA) (DS)←((EA)+2)) 功能:将指令指定32位地址指针送指令指定寄存器和DS。 将指令指定mem32单元的前两个单元内容(16位偏移量)装入指定通用寄存器,把后两个单元内容(段地址) 装入到DS段寄存器。 用于写远地址指针。
例: 假设:(DS)=C 000H 指令: LDS SI, [0010H] 执行指令后: (SI)=0180H (DS)=2000H
3、LES (Load pointer using ES) 格式:LES reg16, mem32 ;(reg16)←(EA) (ES)←((EA)+2)) 功能:把源操作数指定的4个相继字节送指令指定的寄存器 及ES寄存器中。 此指令常常指定DI寄存器。 将指令指定mem32单元的前两个单元内容(16位偏移量)装入指定通用寄存器,把后两个单元内容(段地址) 装入到ES段寄存器。 用于写远地址指针。
例: 假设:(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 from 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 from flags) 格式:LAHF ;(AH)←(PSW的低字节) 功能:标志寄存器低八位 (AH)。 7 6 5 4 3 2 1 0 AH FLAGS 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 OF DF IF TF SF ZF AF PF CF LAHF指令操作图示意
2. SAHF(Store AH into flags) 格式:SAHF ;(FR的低字节)←(AH) 功能:(AH)送标志寄存器低八位。 3. PUSH F(Push flags onto stack) 格式:PUSH F ;(SP)←(SP)-2 ((SP)+1,(SP))←(FR) 功能 : 标志进栈。 4. POP F(Pop flags off stack) 格式:POP F;(PSW)←((SP)+1,(SP)) (SP)←(SP)+2 功能 :标志出栈。
注意: (1) 标志位的影响 LAHF、PUSHF不影响标志位, SAHF、POPF由装入的值确定标志位的值,直接对标志位的操作,影响标志位。 (2)PUSH F、POPF用于保护调用过程前(PSW),过程返回后恢复。 例: … PUSH AX PUSH CX PUSH F CALL TRANS 返回顺序 POPF POP CX POP AX …
三. 算术运算指令 指令分类: 二进制运算 十进制调整 ADD, ADC, INC AAA, DAA 加 SUB, SBB, DEC, NEG, CMP AAS, DAS 减 MUL, IMUL AAM 乘 DIV, IDIV AAD 除 CBW CWD 符号扩展指令: 、
特点: • 带符号数用补码表示 如 MOV AX, -1 等价于MOV AX, 0FFFFh • 对加、减运算,不区分无符号数、带符号数 对乘、除运算,区分无符号数、带符号数 • 可进行字节或字操作 • 影响状态标志 • 十进制运算方法: • 当数据用组合(压缩)或分离(非压缩)BCD码表示时, • 为使运算的结果仍为BCD码表示,需对结果进行调整。 • 十进制运算 = 二进制运算 + 十进制调整
0 1 2 3 4 十进制数码 0000 0001 0010 0011 0100 8421 BCD 码 5 6 7 8 9 十进制数码 • BCD码( Binary Coded Decimal ) • 用二进制编码表示十进制数。 • 常用8421 BCD码, 与十进制数码对应关系: 0101 0110 0111 1000 1001 8421 BCD 码 例 48的BCD码为 ( 0100 1000)BCD
ASCII码是一种分离BCD码 • 数字的ASCII的高4位0011无意义; • 低4位是以8421码形式表示的十进制数位。 • 符合分离BCD码高4位无意义的规定。 • 2的ASCII码: • 高4位0011无意义
计算机计算过程 看作压缩BCD 0000 1000 08 + 0000 1001 09 0001 0001 11 二进制运算 + 0000 0110 0001 0111 17 十进制调整 当数据用组合或分离BCD码表示时, 为使运算的结果仍为BCD码表示,需对结果进行调整。 十进制运算 = 二进制运算 + 十进制调整 • 例 (0000 1000 )压缩BCD+ (0000 1001)压缩BCD • = (0001 0111 ) 压缩BCD
OF DF IF TF SF ZF AF PF CF 1. 加法运算指令 指令格式 执 行 操 作 ADD dst, src (dst) (dst) + (src) ← ADC dst, src (dst) (dst) + (src) + CF ← INC oprd (oprd) (oprd) + 1 ← • ADD、ADC为双操作数指令 • INC为单操作数指令 • 除INC指令不影响CF外,其余指令6个状态标志均据结果置位 • ADC带进位加法,实现字以上运算(进位是上条指令运算的进位)
CFA1H 1100 1111 1010 0001 • + 62A0H + 0110 0010 1010 0000 • 111 1 1 1 1111 1 • 3241H 0011 0010 0100 0001 例1 加法指令: 编程完成CFA1H + 62A0H MOV DX,0CFA1H ADD DX,62A0H • 执行后: • (DX)=3241H CF=1,OF=0,SF=0, ZF=0 • (注意:CF和OF的判断方法,OF=CD6 CD7)
FFH • + 01H • 11 • 00H 例2加1指令 :INC AL 执行前 (AL)= FFH 执行后: (AL)=00H CF=不变,OF=0,ZF=1,SF=0
例3value 是一个字变量 OFFSET value = 1000H (DS)=2000H,(21000H)=01FFH 执行前 value FF 21000H 01 执行后: (21000H)=0200H CF=不变,OF=0,ZF=0,SF=0 执行后 value 00 21000H 02 01FFH + 0001H 进位11 0200H INC value 或写成: INC [value] 注意: INC value是内存单元内容加1,而非地址加1
例4 将buffer为首的4个字节内存内容相加,存放在AL中。 buffer 1A B7 C5 D6 • …... • MOV CX, 4 • LEA BX, buffer • MOV AL, 0 • exit: ADD AL, [BX] • INC BX • DEC CX • JNZ exit • 注意若编程如下, • MOV CX, 4 • MOV AL, 0 • exit: ADD AL, [buffer] • INC buffer • DEC CX • JNZ exit 不能实现, 为什么? 实现的是(1A)+(1B)+(1C)+(1D) 指令INC buffer 将buffer指向的内存单元内容加1,而不是地址buffer加1
0002 F365 H +0005 E024 H 进位1 0008 D389 H 0008 D389 (BX) (AX) 结果存放在: 例5 带进位加:两双字相加 0002F365H + 0005 E024 H = ? • 分析: 8086/8088只能按字节或字相加。 • 位数在字以上的操作数,先加低位,再加高位, • 加高位时加入从低位产生的进位。 MOV AX,0F365H ① ADD AX,0E024H ② MOV BX,0002H ③ ADC BX,0005H ④ • 执行完①、②:(AX)= D389H CF=1, OF=0, SF=1, ZF=0 • 执行完③、④:(BX)= 0008H CF=0, OF=0, SF=0, ZF=0
指令格式 执行操作 SUB dst, src (dst) (dst) (src) ← - SBB dst, src (dst) (dst) (src) CF ← - - DEC oprd (oprd) (oprd) 1 ← - NEG oprd (oprd) 0 (oprd) ← - CMP oprd1, oprd2 (oprd1) (oprd2) - 2. 减法运算指令 • SUB、SBB、 CMP为双操作数,DEC、NEG为单操作数 • SBB为带进位减法(进位是上条指令运算的进位)。 • 除DEC不影响CF标志外,其余指令6个状态标志均据结果置位。 • NEG求补运算,等价于用0减去操作数。 • 其对标志位的影响,由0减去该操作数的过程决定。
2D04H 0010 1101 0000 0100 • - 3AB0H - 0011 1010 1011 0000 • 1 11111 1 1 111 • F254H 1111 0010 0101 0100 例1 减法指令:编程完成 2D04H – 3AB0H MOV AX ,2D04H SUB AX ,3AB0H 借位 • 执行后: • (AX)=0F254H CF=1,OF=0,SF=1,ZF=0
0546 7A70H • - F001 A543H 例2 带进位减法: 用指令完成两双字相减运算 MOV AX,7A70H SUB AX,A543H MOV BX,0546H SBB BX,0F001H
00 H - 01 H 11 FFH • 例3 减1指令:value 是一个字节变量 • OFFSET value = 1000H • (DS)=2000H,(21000H)=00H • DEC value • 执行后:(21000H)=0FFH • CF=不变,OF=0,ZF=0,SF=1 注意:DEC value 是内存单元内容减1,而非地址减1
00 H 0000 0000 B - 80 H - 1000 0000 B 1 1 80H 1000 0000B • 例4 求补指令:MOV AH, 80H • NEG AH 执行后: (AL)=80H , CF=1,OF=1,ZF=0,SF=1
例5:求绝对值 在内存中, 从AREA1开始存放100个带符号数。 求各数的绝对值存于AREA2的开始单元。 流程图
程序: LEA SI, AREA1 LEA DI, AREA2 MOV CX, 100 CHECK: MOV AL, [SI] OR AL, AL ;(AL)内容不变,置标志 JNS NEXT ;SF=0转NEXT NEG AL;负数求补 NEXT: MOV [DI], AL ;送目标 INC SI INC DI DEC CX JNZ CHECK HLT 负数的真值和它的补码互为补(本位和为0)。
CF= 1 A低于B • CF= 0 A高于或等于B • CF=1或 ZF=1 A低于等于B • CF=0且 ZF=0 A高于B 比较指令: CMP oprd1, oprd2 ; (oprd1) - (oprd2) • 比较指令CMP,进行两操作数相减操作, 但只影响标志值,不影响操作数(减的结果不保存) • 利用CMP执行后的标志值,比较两操作数之间的关系 CMP A, B • ① 据ZF判断两数是否相等 ZF=1 两数相等, A = B ; ZF=0 两数不等, A ≠ B • ② 据ZF和CF判断两无符号数关系
条件转移指令 判断条件 JB next CF = 1 低于 JBE next CF = 1 ZF = 1 低于或等于 或 JA next CF = 0 ZF = 0 高于 且 JAE next CF = 0 高于或等于 例 将AX和BX中较大的无符号数,存于AX中 • CMP AX, BX ;比较 • JAE above ;高于或等于则跳转 • XCHG AX, BX ;低于则交换 • above: 、、、 比较指令常常根据条件(标志)转移,无符号数转移指令如下:
CMP A,B • 例 将AX和BX中较大的带符号数,存于AX中 • CMP AX, BX ;比较 • JGE great ;大于或等于则跳转 • XCHG AX, BX ;小于则交换 • great: 、、、
CMP指令应用举例:带符号数找最大值 • 若自BLOCK开始的内存缓冲区中,有100个带符号数。 • 找出最大值。并存放到MAX单元中。 • 思路: • 第一个数取出( AX), • 取出第二个数(第二个字单元内容)与(AX)比较 : • (AX)>第二个数,不做交换, • 否则,(第二个字单元内容) (AX)。 • 再取第三个数, • … • 经过99次比较,在(AX)中得到最大数。 • …
编程: MOV BX,OFFSET BLOCK MOV AX,[BX] INC BX INC BX MOV CX,99 AGAIN:CMP AX,[BX] JG NEXT;(AX) >(16(ds)+(BX))转NEXT MOV AX,[BX] NEXT: INC BX INC BX DEC CX JNE AGAIN MOV MAX,AX ;MAX单元存放最大值
指令格式 执行操作 src 若 为字节类型: ( AX ) ( AL ) (src) ← × src 若 为字类型: MUL src ( DX ) ( AX ) ( AX ) (src) , ← × 将被乘数、乘数看作无符号数,进行乘运算 乘的结果也为无带符号数 MUL 执行的操作与 相似 I MUL src , 将被乘数、乘数看作带符号数 进行乘运算 乘的结果也为带符号数 3. 乘法指令 无符号数乘法 带符号数乘法 问题思考:乘法中为什么要用MUL,IMUL 指令 ?
指令格式 执行操作 (src) 为字节类型: ( A L) ( A X) / (src) ← 的商 ( AH ) ( A X) / (src) ← 的余数 (src) 为字类型: DIV src ( AX ) (D X ) ,( AX ) / (src) ← 的商 无符号数除法 (DX) (DX ) , ( A X) / (src) ← 的余数 将被除数、除数看作无符号数,进行除法运算, 商、余数也为无符号数 DIV 执行的操作与 相同, IDIV src 将被除数、除数看作带符号数,进行除法运算 带符号数除法 商、余数也为带符号数,余数的符号与被除数同 4. 除法指令
指令格式 执行操作 ( AL ) AH 将 的符号扩展到 中 CBW ( AL ) D7=0 ( AH ) =0 0H 的 , D7=1 ( AH ) =FFH , ( AX ) D X 将 的符号扩展到 中 CWD (AX ) D15=0 ( DX ) =0 000H 的 , D15=1 ( DX ) =FFFFH , 5. 符号扩展指令
6、调整指令 前面提到的所有算术运算指令都是二进制的运算指令, 但人们常用的是十进制。 当用计算机进行计算时: 必须先把十进制 二进制数, 计算结果 十进制数输出。 为便于十进制运算,计算机提供了一组十进制调整指令, 这组指令在二进制基础上给予十进制调整,直接得到十进制数。 8086/8088中提供了六条调整指令。
8088中有六条调整指令: • (1)、DAA(Decimal adjust for addition)加法十进制调整指令 • (2)、DAS(Decimal adjust for subtration)减法十进制调整指令 • (3)、AAA(ASCII adjust for addition)加法ASCII调整指令 • (4)、AAS(ASCII adjust for subtration)减法ASCII调整指令 • (5)、AAM(ASCII adjust for multiply)乘法ASCII调整指令 • (6)、AAD(ASCII adjust for division)除法ASCII调整指令 • 共同点: • 调整指令后边不跟操作数: • 十进制调整指令隐含寄存器操作数AL; • ASCII调整指令隐含寄存器操作数AL或AH。 • 调整对象: 十进制调整指令对组合BCD码进行调整; • ASCII调整指令对分离BCD码进行调整,
算术运算指令复习 二进制运算 十进制调整 ADD, ADC, INC AAA, DAA 加 SUB, SBB, DEC, NEG, CMP AAS, DAS 减 MUL, IMUL AAM 乘 DIV, IDIV AAD 除 CBW CWD 符号扩展指令: 、
作业: 41,48,53