Download presentation
Presentation is loading. Please wait.
1
第3章 80x86汇编语言程序设计(中) 时间不够的情况下只讲16位汇编
2
3.4 顺序结构程序设计 顺序结构是最简单也是最基本的程序结构。程序按顺序执行,不发生任何转移,通常非控制转移类指令都可编写顺序结构程序。
语句1 语句2 . 语句n
3
3.4.1数据传送指令 通用数据传送指令 地址传送指令 标志寄存器传送指令 输入输出指令 类型转换指令
4
1、通用数据传送指令 MOV(move) 传送 MOVSX(move with sigh-extend) 带符号扩展传送
MOVZX(move with zero-extend) 带零扩展传送 PUSH(push onto the stack) 进栈 POP(pop from the stack) 出栈 PUSHA/PUSHAD (push all registers) 所有寄存器进栈 POPA/POPAD (pop all registers) 所有寄存器出栈 XCHG(exchange) 交换 XLAT(translate) 换码(查表)
5
MOV 传送指令 格式:MOV DST, SRC 操作:DST<--(SRC) 即把源操作数的内容送入目的操作数
说明:1)可以进行8位、16位或32位数据的传送 2)SRC可为立即数、寄存器、存储器操作数 3)DST可为寄存器、存储器操作数 4)该指令不影响任何状态标志位 段寄存器 CS DS SS ES 通用寄存器 AX BX CX DX BP SP SI DI 立即数 存储器
6
MOV指令示例 MOV AL, BL ;寄存器之间传送 MOV BP, SI MOV AX, [BX+DI] ;存储器操作数 MOV AX, ARRAY[SI] ;传送到寄存器 MOV AX, 0B00H ;立即数传送到寄存器 MOV CL, B MOV VALUE, 100H ;立即数传送到存储单元 MOV ES:[BX], 4BH MOV [BX], CX ;寄存器内容传送到存储器 MOV BUFF [BP][DI], AX
7
MOV指令注意事项: (1)两个操作数长度必须一致 MOV AL, BX ;不合法 例外:源是16进制立即数,位数小于目的操作数时,高位按0扩展,源是10进制立即数,位数小于目的操作数时,高位按符号位扩展 MOV AX, 0D8H 执行后,(AX)=00D8H MOV AX, -40 执行后,(AX)=FFD8H (2)不允许用立即数为段寄存器赋值 例:MOV ES, 10A0H ;不合法
8
(3)不允许两个操作数均是存储器操作数 MOV X, Y ;不合法 可以通过一个寄存器传送: MOV AX, Y MOV X, AX (4)不允许两个操作数均为段寄存器 MOV ES, DS ;不合法 (5)不允许CS、IP和立即数做目标操作数 MOV CS, AX ;不合法 MOV 100H, AX ;不合法 MOV IP, BX ;不合法
9
MOVSX 带符号扩展传送指令 MOVZX 带零扩展传送指令 格式:MOVSX DST, SRC 操作:DST<--符号扩展(SRC)
说明: 1) 源操作数是8位或16位寄存器或存储器的内容 2) 目的操作数必须是16位或32位寄存器
10
MOVSX指令示例 MOVSX EAX, CL 设(CL)=0ABH, 执行后 (EAX)=0FFFFFFABH 负号扩展 若(CL)=57H, 执行后 (EAX)= H 正号扩展 MOVZX指令示例 MOVZX EAX, DATA 设(DATA)=87ADH,执行后 (EAX)=000087ADH 0扩展
11
PUSH 压栈指令 格式:PUSH SRC 举例:PUSH AX 操作: PUSH DAT[BX][SI] SP<--(SP)-2
((SP)+1,(SP))<--(SRC) 32位指令: ESP(ESP)-4 ((ESP)+3,(ESP)+2,(ESP)+1,(ESP))(SRC) 举例:PUSH AX PUSH DAT[BX][SI] PUSH H PUSH H PUSH EAX 说明:1) 源操作数可以是寄存器或存储器操作数 2) 必须以字或双字为单位操作 3) 32位指令允许SRC是16位或32位立即数,也容许是32位寄存器和存储器操作数
12
压栈指令示例 PUSH AX 执行前 AX AX 25H 31H SP H 执行后 31 25H 3125H 3125H 低地址 低地址 524FEH 524FFH SP 52500H 进栈方向
13
POP 出栈指令 格式:POP DST 操作: 16位指令: DST<--((SP)+1,(SP)) SP<--(SP)+2
32位指令: DST((ESP)+3,(ESP)+2,(ESP)+1,(ESP)) (ESP)(ESP)+4 举例:POP AX POP DAT[BX][SI] POP DS POP ECX
14
出栈指令示例 POP BX 执行前 执行后 BX BX 75C1H 低地址 低地址 SP Bh H Bh H 48h H h H 9Ah H Ah H 28h H h H 48h 6Bh SP 6Bh 48h 48h 出栈方向
15
PUSHA 所有寄存器进栈 格式:PUSHA 操作: PUSHA: (286及其后继机型)
16位通用寄存器依次进栈,次序为: AX,CX , DX,BX,指令执行前的SP,BP,SI,DI 指令执行后 SP(SP)-16 仍指向栈顶 PUSHAD: (386及其后继机型) 32位通用寄存器依次进栈,次序为:EAX,ECX, EDX,EBX,指令执行前的ESP,EBP,ESI,EDI 指令执行后 ESP(ESP)-32 仍指向栈顶
16
PUSHA指令示例 执行前 执行后 (DI) -16 (SI) -14 (BP) -12 (SP)原 -10 (BX) -8 (DX) -6
(CX) (AX) (SP)原
17
POPA所有寄存器出栈 格式:POPA 操作: POPA: (286及其后继机型) 16位通用寄存器依次出栈,次序为:
DI,SI,BP,SP,BX,DX,CX , AX 指令执行后 SP(SP) +16 仍指向栈顶 POPAD: (386及其后继机型) 32位通用寄存器依次出栈,次序为:EDI,ESI, EBP,ESP,EBX,EDX,ECX , EAX 指令执行后 ESP(ESP) +32 仍指向栈顶
18
XCHG 交换指令 格式:XCHG OPR1, OPR2 操作:(OPR1) (OPR2) 如: XCHG AX, BX ;寄存器之间交换
XCHG BX, [BP+DI] ;寄存器与存储器之间交换 XCHG [SI], DX 说明: 1)操作数不允许为段寄存器 2)两个操作数长度必须相同 3)本指令不影响状态标志位 4)两个操作数不能同时为存储器操作数
19
交换指令示例 XCHG DX, DATA[BP] 设(SS)=5000H, (BP)=0400H, DATA=1800H 物理地址=5000H× H+1800H=51C00H 执行前 执行后 DX DX 37CDH 51C00H 42H C00H 1H 6DH H 6D42H CDH 37H
20
XLAT查表指令(换码指令) 格式:XLAT TABLE 或 XLAT
操作:AL<--((BX)+(AL))或 AL((EBX)+(AL)) 将AL中的当前内容转换为表中某一种代码。执行前一定要将表(TABLE)的EA赋给BX (或EBX)寄存器,将代码在表中距首址的偏移放在AL寄存器中。 XLAT指令示例 TABLE H MOV BX, OFFSET TABLE H ;表首址给BX H MOV AL, H ;待转换内容到AL H XLAT H H H 34H AL
21
2、地址传送指令 LEA (load effective address) 有效地址送寄存器
LDS (load DS with pointer) 指针送寄存器和DS LES (load ES with pointer) 指针送寄存器和ES LFS (load FS with pointer) 指针送寄存器和FS LGS (load GS with pointer) 指针送寄存器和GS LSS (load SS with pointer) 指针送寄存器和SS
22
LEA 装载有效地址指令 格式: LEA DST, SRC 操作:DST<--SRC的有效地址EA
说明:SRC必须是存储器操作数,而DST则必须是一个16位或32位的通用寄存器(AX..DI..) LEA指令示例 设(DS)=2000H, (BX)=1234H LEA DI, [BX] MOV SI, [BX] 执行后 执行后 21234H 78H 5H 56H SI 5678H DI 1234H 78H 56 BX 1234H 1234H
23
LEA DI, BUFFER ; 将变量BUFFER的 ; 有效地址送到DI, ;而不是将BUFFER ;变量的值送DI
MOV DI, BUFFER ; 将变量BUFFER的有效地址 ; 所指单元的值送DI 执行后 注意LEA与OFFSET的区别 执行后 DI 1234H Offset只能返回变量与标号的EA,不如LEA能返回任何寻址方式下的内存数据的EA 如:LEA AX,MYDAT[SI] 是对的,但是,mov AX, OFFSET MYDAT[SI]就是错的 DI 5678H BUFFER 2000H:1234H 1234H 78H 78H 5H 56 56H
24
LDS 装载数据段指针指令 操作:DST(SRC) DS(SRC+2) 或 DS(SRC+4) LES 、LFS、LGS、LSS
格式:同LDS,目标分别是ES,FS,GS,和SS寄存器 说明: 1) 源操作数必须是32位或48位存储器操作数 2) 目的操作数必须是寄存器 3) 完成一个逻辑地址的传送,该逻辑地址须用伪指令预先定义在当前数据段中
25
LDS指令示例 LDS DI, [BX] 设(DS)=2000H, (BX)=1000H 执行前 执行后 DI DI 7659H D645H H 45H H D6H H 00H H 50H 45 DS D6 DS 00 2000H 5000H 50 再比如:LDS BX, BUFF[SI] LDS DI, BUFF
26
LEA与LDS的区别 LEA SI, BUFF LDS DI, BUFF 设(DS)=2000H EABUFF=1000H 执行后:
BUFF(21000H) 45H +1 D6H H H 设(DS)=2000H EABUFF=1000H 执行后: SI=1000H DI=D645H DS=5000H 不合法,SRC必须是存储器操作数 思考: LDS DI, BX是合法指令吗?
27
3、标志寄存器传送指令 LAHF(load AH with flags) 标志送AH SAHF(store AH into flags)
PUSHF/PUSHFD(push the flags or eflags) 标志进栈 POPF/POPFD(pop the flags or eflags) 标志出栈
28
LAHF 标志寄存器送AH指令 SAHF 送标志寄存器指令 格式:LAHF 操作:AH<--FLAGS 7-0
操作:FLAGS 7-0<--(AH) 即将AH寄存器内容送FLAGS最低8位 说明:1) 无操作数 2) FLAGS中含若干标志位,但LAHF指令本身不影响标志位
29
PUSHF 标志进栈指令 格式:PUSHF 操作: PUSHF:SP (SP)-2 ((SP)+1,(SP)) (FLAGS)
PUSHFD: (ESP)(ESP)-4 ((ESP)+3,(ESP)+2,(ESP)+1,(ESP)) (EFLAGS AND 0FCFFFFH) (清除VM和RF位) 说明:无操作数
30
POPF 标志出栈指令 格式:POPF 操作: POPF:FLAGS ((SP)+1,(SP)) SP (SP)+2
POPFD: EFLAGS((ESP)+3,(ESP)+2,(ESP)+1,(ESP)) ESP(ESP)+4
31
4、输入输出指令 IN(input) 输入 OUT(output) 输出
32
IN 输入指令 (从接口电路的端口输入数据)
格式1:IN AL, Port(字节) (Port是0-FFH的立即数) IN AX, Port(字) (Port是0-FFH的立即数) IN EAX, Port(双字) (Port是0-FFH的立即数) 格式2:IN AL, DX (字节) IN AX, DX(字) IN EAX, DX (双字) 操作: AL/AX/EAX<--(Port) 从外设读入字节或字或双字数据 AL/AX/EAX<--(DX) 以DX内容为端口地址,读入数据 说明:用Port指明8位端口地址时,地址范围为00H-FFH 以DX间接给出端口地址时,最大地址为0FFFFH
33
OUT 输出指令 (向接口电路的端口输出数据)
格式1:OUT Port, AL (字节) OUT Port, AX(字) OUT Port, EAX(双字) 格式2:OUT DX, AL (字节) OUT DX, AX(字) OUT DX, EAX(双字) 操作: (Port)<--(AL)/(AX)/(EAX) 传送数据到Port端口 (DX)<--(AL)/(AX) /(EAX) 传送数据到DX指出的端口 说明:用Port指明8位端口地址时,地址范围为00H-FFH 以DX间接给出端口地址时,最大地址为0FFFFH
34
IN AX, 48H ;从48H端口读入字数据-->AX MOV DX, 3FCH
IN AL, 20H ;从20H端口读入字节数据-->AL IN AX, 48H ;从48H端口读入字数据-->AX MOV DX, 3FCH IN AX, DX ;从03FCH端口读入字数据-->AX OUT指令示例 OUT 32H, AX ;传送字数据到32H端口 MOV DX,400H MOV AL, 86H OUT DX, AL ;传送字节数据到DX指出的端口
35
5、类型转换指令 CBW(convert byte to word) 字节转换为字
CWD/CWDE(convert word to double word) 字转换为双字 CDQ(convert double to quad) 双字转换为4字 BSWAP(byte swap) 字节交换
36
CBW 字节转换为字 CWD/CWDE 字转换为双字 格式:CBW 操作:扩展AL中的符号至AH中, 将8位数扩展成等效的16位数
操作:扩展AX中的符号至DX中,将16位数扩展成 等效的32位数 格式:CWDE 操作:AX的内容符号扩展到EAX 说明: 用于在符号数除之前,形成双倍长度的被除数
37
CDQ 双字转换为4字 BSWAP 字节交换 格式:CDQ 操作:EAX的内容符号扩展到EDX,形成EDX:EAX 中的4字
格式:BSWAP r32 操作:使32位寄存器的字节次序变反 (1、4字节交换,2、3字节交换) BSWAP指令示例 BSWAP EAX 执行前 (EAX)= H 执行后 (EAX)= H
38
数据传送指令小结 1、数据传送指令不影响标志位(除SAHF) 2、除XCHG指令外,都是从源到目的的单向传送
3、注意MOV指令与 LEA指令的区别 4、堆栈的存取在16位指令中必须以字为单位, 5、8086 不允许PUSH指令使用立即数寻址方式 如:PUSH ;8086中不合法 但286及其后继机型中允许 6、POP 指令不允许使用立即数寻址方式, 不允许使用CS寄存器 例: POP ;不合法 POP CS ;不合法
39
7、段寄存器只能在MOV、PUSH、POP 指令中作为操作数出现
例:MOV ES, AX PUSH CS POP DS 但下列指令不合法: MOV CS, reg POP CS 8、指令有多种格式,一般都遵循以下规则: 双操作数指令中不允许两个操作数均为存储器操作数 单操作数指令不允许立即寻址方式 目的操作数不允许使用立即寻址方式
40
3.4.2 算术运算指令 加法指令 ADD ADC INC XADD 减法指令 SUB SBB DEC NEG CMP CMPXCHG
CMPXCHG8B 乘法指令 MUL IMUL 除法指令 DIV IDIV 算术运算中关于溢出的结论: OF——表示有符号数的溢出 CF——表示无符号数的溢出(进位)
41
ADD 常规加指令 格式:ADD DST, SRC 操作:DST<--(DST)+(SRC) 指令构成方式:
ADD reg,imme ;寄存器与立即数相加 ADD reg,reg ;寄存器之间 ADD reg,mem ;寄存器加存储器操作数 ADD mem,imme ;存储器加立即数 ADD mem,reg ;存储器操作数加寄存器 说明:运行结果对CF、SF、OF、PF、ZF、AF都会影响
42
ADD指令示例1 ADD DX, BX 设(DX)=4652H, (BX)=0F0F0H 0100 0110 0101 0010
4652H + F0F0H 1 3742H 进位 进位 执行后 (DX)=3742H ZF=0 结果不为0 SF=0 结果为正 CF=1 有进位 OF=0 不溢出
43
ADD指令示例2 ADD WORD PTR[BX], 9F76H 设(DS)=2000H, (BX)=1000H 执行前: H A988H A9H F76H 1 48FEH 执行后: FEH CF=1 有进位 48H OF=1 溢出 ZF=0 结果不为0 SF=0 结果为正 进位
44
ADC 带进位加指令 INC 增1指令 格式:ADC DST, SRC 操作:DST<--(DST)+(SRC)+(CF)
说明:该指令除了多一个进位标志外,同ADD指令。 常用于多字节运算 INC 增1指令 格式:INC DST 操作:DST<--(DST)+1 说明: 1)DST可以是寄存器或存储器操作数 2)DST不允许是立即数 3)运行结果对SF、OF、PF、ZF、AF都会影响,但不影响CF
45
+ ADC指令示例——双字加法 设32位的目的操作数存放在DX和AX中,DX存放高位字,32位源操作数存放在BX和CX中,BX存放高位字
CF ADC ADD DX AX + BX CX DX AX 指令序列为: ADD AX, CX ;低位加 ADC DX, BX ;高位加
46
如:DX:AX=37A1FFFFH, 则DX:AX+1能否用: INC AX ADC DX,0 来实现?
执行前(DX)=0418H, (AX)=0F365H (BX)=1005H, (CX)=0E024H 0418H DX F365H AX 1005H BX E024H CX CF 141EH DX D389H AX CF=1 不能,因为INC不影响CF 如:DX:AX=37A1FFFFH, 则DX:AX+1能否用: INC AX ADC DX,0 来实现?
47
8088中,执行INC BYTE PTR[BX]指令(指令已在指令队列中)需要 个总线周期。 2
LEA BX, ARRAY MOV AL, [BX] …… INC BX ARRAY a1 a2 a3 a4 MOV BX, 0 MOV AL, ARRAY[BX] …… INC BX 先从内存中取出来是1个总线周期,加1后在存入内存又一个总线周期 8088中,执行INC BYTE PTR[BX]指令(指令已在指令队列中)需要 个总线周期。 2
48
XADD 交换并相加指令 格式: XADD DST, SRC 操作:TEMP(SRC)+(DST) SRC(DST)
DST(TEMP) 说明:1)仅用于486及其后继机型, 2)源操作数只能是寄存器 XADD指令示例 XADD BL, DL 如执行前 (BL)=12H, (DL)=02H 则执行后 (BL)=14H, (DL)=12H
49
SUB 常规减指令 格式:SUB DST, SRC 操作:DST<--(DST)-(SRC) 指令构成如下:
SUB reg, imme ;寄存器减立即数 SUB reg, reg ;寄存器之间相减 SUB reg, mem ;寄存器减存储器操作数 SUB mem, imme ;存储器操作数减立即数 SUB mem, reg ;存储器操作数减寄存器 说明:运行结果对CF、SF、OF、PF、ZF、AF都会影响
50
SUB指令示例 SUB BX, CX 执行前: (BX)=9543H (CX)=28A7H 9543H A7H 6C9CH 执行后: (BX)=6C9CH CF=0 OF=1 ZF= SF=0
51
SBB带进位减指令 格式:SBB DST, SRC 操作:DST<--(DST)-(SRC)-(CF)
说明:该指令除了多一个进位标志外,同SUB指令。 常用于多字节运算 SBB指令示例——双字减法 SUB AX, CX ;低16位减 SBB DX, BX ;高16位减 7456H AX H DX H CX H BX 1 E11EH H CF 0001H CF=1
52
DEC 减1指令 NEG 求补指令 格式:DEC DST 操作:DST<--(DST)-1 说明:用法同INC指令
格式:NEG DST 操作:DST <-- -(DST) 说明:1)-(DST)表示操作数按位求反后末位加1。 2)执行时,用零减去操作数
53
NEG指令示例1 NEG DX 执行前: (DX)=6780H 执行后: (DX)=9880H CF=1 借位 NEG指令示例2 NEG AL ;AL求补 ADD AL, ;(AL)+100-->AL 实现的功能为: (AL)
54
CMP 比较指令 格式 :CMP DST, SRC 操作:(DST)-(SRC) 说明: 1、两个操作数相减,但结果不回送
2、影响标志位的值,下一指令常是条件转移指令 3、必须区分无符号数比较与有符号数比较 如 比较 B 与 B 无符号数比较: > 0 有符号数比较: < 0 4、比较两数是否相等,根据标志位ZF判断 若相等,则ZF=1;否则ZF=0 5、指令构成同SUB指令
55
比较两数的大小 CMP DST, SRC 无符号数比较结论: 用标志位CF判断无符号数的大小 CF=0,则 DST ≥ SRC CF=1,则 DST < SRC 有符号数比较结论: 用标志位SF和OF判断有符号数的大小 SF、OF值相同,则 DST>SRC SF、OF值不同,则 DST<SRC
56
CMP指令示例1 CMP AL, BL 令 (AL)= (BL)=10 - 64 - 74 OF=0 SF= 结论: (DST)<(SRC) CMP指令示例2 CMP CL, [100H] 令 (CL)= (DS:100)= -110 -100 - (-110) 10 OF=0 SF= 结论: (DST)>(SRC)
57
CMPXCHG 比较并交换指令 格式:CMPXCHG DST, SRC 操作:累加器AC与DST比较 如 (AC)=(DST)
则 ZF1,DST(SRC) 否则 ZF0,AC(DST) 说明:1) 只用于486及其后继机型 2) 累加器可为AL、AX或EAX寄存器 3) SRC只能用寄存器,DST可用寄存器或存储器寻址方式
58
MUL 无符号数乘指令 IMUL 有符号数乘指令 格式: MUL SRC 格式: IMUL SRC
操作: 字节数乘, AX<--(AL)×(SRC)byte 字数据乘, DX:AX<--(AX)×(SRC)word 双字数乘,EDX:EAX(EAX)×(SRC)DW 说明: 1)SRC可用寄存器或存储器寻址方式 2)无符号数乘与有符号数乘不同 如 ( B)×( B) 无符号数乘: ×255 有符号数乘: (-1)×(-1) 3)本指令影响标志位CF和OF
59
硬件上怎么判断有符号数乘法结果符号 MUL, IMUL指令示例 MUL BL (AL)=0B4H=180 IMUL BL
(BL)=11H=17 IMUL BL (AL)=0B4H= -76, (BL)=11H=17 -76补=4CH × × 乘数与被乘数的符号位异或 (AX)=0BF4H=3060 (AX)=(-050C)补 =FAF4H= -1292 硬件上怎么判断有符号数乘法结果符号
60
格式:IMUL REG, SRC或IMM 操作:REG16(REG16)*(SRC或IMM) REG32(REG32)*(SRC或IMM) 格式:IMUL REG, SRC, IMM 操作:REG16(SRC)*IMM REG32(SRC)*IMM 说明:1)乘积的字长和源、目的操作数的字长一致 2)可能溢出 3)SRC可用寄存器或存储器寻址方式 REG只能是寄存器寻址方式 IMM是立即数 4)这些指令是80186后新增加的
61
DIV 无符号数除指令 IDIV 符号数除指令 格式:DIV SRC 格式:IDIV SRC
操作:AL(商), AH(余数)<--(AX)/(SRC)byte AX(商), DX(余数)<--(DX:AX)/(SRC)word EAX(商), EDX(余数)<--(EDX:EAX)/(SRC)DW 说明: 1) 被除数的长度是指令中操作数的两倍 2) 源操作数可用除立即数以外的寻址方式 3) 如果SRC=0或者商大于存放商的寄存器的最大数值范围,都会引发“Divide error”错误。因此,当被除数为AX, DX:AX时,商最大是255和65535
62
DIV指令示例 N1 DW ? N2 DW ? …… MOV DX, 0001H MOV BX, 100H ;装入除数
MOV AX, 0000H ;装入被除数 10000H MOV DX, 0001H MOV BX, 100H ;装入除数 DIV BX ;10000H/100H MOV N1, AX ;存商 MOV N2, DX ;存余数
63
IDIV指令示例 RESILT DB ? …… CBW ;字节扩充到字 MOV BL, 15 ;装入除数 IDIV BL ;-127/15
计算-127/15,商存入RESULT单元 RESILT DB ? …… MOV AL, ;装入被除数(81H) CBW ;字节扩充到字 MOV BL, ;装入除数 IDIV BL ;-127/15 MOV RESULT, AL ;存商 要解释为什么有字节扩展 CBW
64
计算(V-(X*Y+Z))/X,其中X,Y,Z,V均为16位有符号数,要求商存入AX,余数存入DX MOV AX, X
算术运算指令综合例 计算(V-(X*Y+Z))/X,其中X,Y,Z,V均为16位有符号数,要求商存入AX,余数存入DX MOV AX, X IMUL Y ; X*Y MOV CX, AX MOV BX, DX ;积存 BX: CX MOV AX, Z CWD ;Z扩展 ADD CX, AX ;X*Y+Z ADC BX, DX MOV AX, V CWD ;V扩展 SUB AX, CX ;相减 SBB DX, BX IDIV X ;除以X 注意学生编的时候,可能会忘记字扩展,这些细节要提醒学生
65
为什么需要调整?BCD码的1010~1111是无意义的。 例:非压缩十进数6和7相加 0000 0110 + 0000 0111
;调整 调整指令有两类: 1、非压缩BCD码调整指令 AAA AAS AAM AAD 2、压缩BCD码调整指令 DAA DAS
66
AAA 非压缩BCD码加调整 格式:AAA 操作:将存放在AL中的两个非压缩BCD码的和进行调整, 正确和在AX中 调整过程:
如果 (AL&0FH)>9 或 (AF)=1 则 (AL)+6-->AL (AH)+1-->AH 1-->AF, AF-->CF (AL)&0FH-->AL 否则 (AL)&0FH-->AL 0-->AF, (AF)-->CF 说明: 该指令放在二进制加法指令ADD之后 AH AL 正确和的有效位数
67
AAA指令示例 计算十进制数9+4 MOV AL, 9H H MOV BL, 4H H ADD AL, BL DH ;>9 AAA H ;调整 13H & 0FH 03H (AH)+ 1-->AH 结果: (AH)=01H (AL)=03H CF=AF=1
68
AAA指令示例 计算十进制数9+9 MOV AL, 9H H MOV BL, 9H H ADD AL, BL H ;AF=1 AAA H ;调整 18H & 0FH 08H (AH)+ 1-->AH 结果: (AH)=01H (AL)=08H CF=AF=1
69
AAS 非压缩BCD码减调整指令 格式:AAS 操作:将AL中的两个非压缩BCD码的差进行调整,正确结果送AX中 调整过程:
如果 (AL&0FH)>9 或 (AF)=1 则 (AL)-6-->AL (AH)-1-->AH (AL)&0FH-->AL 1-->AF, AF-->CF 否则 (AL)&0FH-->AL 0-->AF, (AF)-->CF AH AL 正确差的有效位数
70
(AH)-1-->AH AAS指令示例 计算十进制数16-7 MOV AX, 0106H 06H MOV BL, 7H - 07H
SUB AL, BL FFH ; (AL)&0FH>9 AAS H ;调整 F9H & 0FH 09H (AH)-1-->AH 结果: (AL)=09H CF=AF=1 (AH)=00H
71
AAM 非压缩BCD码乘调整指令 格式:AAM 操作:将AX中的两个非压缩BCD码之积进行调整 调整过程:
将AL除以10, 商送AH, 余数送AL AAM指令示例 MOV AL, 07H ;取被乘数 MOV CL, 09H ;取乘数 MUL CL × AAM ;调整 0000 0111 调整后,(AH)=6 (AL)=3
72
AAD 非压缩BCD码除调整指令 格式:AAD
操作:在除法运算前,用该指令将AX中的非压缩BCD码形式的被除数调整为二进制数,然后做除法运算 调整过程: (AL)+(AH)×10-->AL 0-->AH (AX)/除数,商-->AL,余数-->AH
73
AAD指令示例 MOV AX, 0208H ;AX<--被除数 MOV CL, ;除数 AAD ;调整,(AX)=28 DIV CL 结果:(AL)=7 (AH)=0
74
DAA 压缩的BCD码加调整 格式:DAA 操作:对AL寄存器中的压缩BCD码之和进行调整,结果在AL寄存器中 调整过程:
如果 (AL & 0FH)>9 或 (AF)=1 则(AL)+6-->AL 1-->AF 如果(AL)>9FH 或 (CF)=1 则(AL)+60H-->AL 1-->CF AH AL 正确和的有效位数
75
DAA指令示例1 计算十进制数29+18 MOV AL, 29H H MOV BL, 18H H ADD AL, BL H ;AF=1 DAA ; 调整 47H DAA指令示例2 计算十进制数54+63 MOV AL, 54H H MOV BL, 63H H ADD AL, BL B7 H ;>9F DAA H ; 调整 1 17H
76
DAS 压缩的BCD码减调整 格式:DAS 操作:对AL中的压缩BCD码差进行调整,结果在AL中 调整过程:
如果 (AL&0FH)>9 或 (AF)=1 则 (AL)-6-->AL 1-->AF 如果(AL)>9FH 或 (CF)=1 则 (AL)-60H-->AL 1-->CF AH AL 正确和的有效位数
77
DAS指令示例 计算十进数A-B A= B=3576 MOV AL, A H SUB AL, B H DAS CH ;AF,CF均=1 MOV D, AL H ;所以用-66H调整 MOV AL, A H D SBB AL, B CF=1 DAS MOV D+1, AL H 35H 10H D+1 结果=1036
78
3.4.3 逻辑运算指令 逻辑非指令 NOT 逻辑与指令 AND 逻辑或指令 OR 逻辑异或指令 XOR 测试指令 TEST
79
示例2和哪个指令类似?有无区别? NOT 逻辑非指令 格式: NOT OPR 操作: OPR按位取反后送回原处 说明:本指令不影响标志位
MOV AL, 52H NOT AL 执行前 AL 执行后 AL NOT指令示例2 MOV AL, 1 ;1-->AL NOT AL ;求反 INC AL ; mov al,1 neg al 区别是NEG指令会影响CF标志位,而NOT之后的INC不影响CF标志位 -1-->AL 示例2和哪个指令类似?有无区别?
80
AND 逻辑与指令 格式: AND DST, SRC 操作: (DST)<--(DST)&(SRC)
说明:本指令影响标志位PF、SF、ZF,使CF=0、OF=0 AND指令示例1 MOV AL , 32H AND AL, 0FH ;屏蔽高四位操作 执行前 AL (2的ASCII码) 执行后 AL AND指令示例2 AND AX, AX 执行后 AX内容不变, CF=0、OF=0
81
OR 逻辑或指令 格式: OR DST, SRC 操作:(DST)<--(DST)或(SRC)
说明:本指令影响标志位PF、SF、ZF,使CF=0、OF=0 OR指令示例1 MOV AL, 02H OR AL, 0F0H ; 高四位置位 执行前 AL 执行后 AL OR指令示例2 MOV AL, 02H OR AL, 30H 执行前 AL 执行后 AL ;’2’的ASCII码
82
XOR 异或指令 格式: XOR DST, SRC 操作: (DST)<--(DST)与(SRC)按位异或
说明:本指令影响标志位PF、SF、ZF,使CF=0、OF=0 XOR指令示例1 MOV AL, 0B6H XOR AL, 0FH 不变 变反 思考题的背景资料: 1.MOV AX, 0 ;在8088、286、386、486、Pentium中时钟数分别为: 4、3、2、1、 指令长度 2字节 2.AND AX, 0 ;在8088、286、386、486、Pentium中时钟数分别为: 4、3、2、1、 指令长度 3字节 3.XOR AX, AX ;在8088、286、386、486、Pentium中时钟数分别为:3、2、2、1、 指令长度 2字节 4.SUB AX, AX ;在8088、286、386、486、Pentium中时钟数分别为:3、2、2、1、 指令长度 3字节 5.MOV BL, 0; 在8088、286、386、486、Pentium中时钟数分别为: 4、3、2、1、 指令长度 2字节 MUL BL ; 在8088、286、386、486、Pentium中时钟数分别为:143、21、38、42、 指令长度 3字节 显然,使用XOR是合适的 XOR指令示例2 XOR AL, AL ; 清零操作,且CF=0 思考:让AX寄存器清0,有几种办法,在X86不同的CPU中,哪种方案最好?
83
指令 时钟数 指令字节数 8088 286 386 486 Pentium MOV AX, 0 4 3 2 1 AND AX, 0
XOR AX, AX SUB AX, AX MOV BL, 0 MUL BL 143 21 38 42 11 1.MOV AX, 0 ;在8088、286、386、486、Pentium中时钟数分别为: 4、3、2、1、 指令长度 2字节 2.AND AX, 0 ;在8088、286、386、486、Pentium中时钟数分别为: 4、3、2、1、 指令长度 3字节 3.XOR AX, AX ;在8088、286、386、486、Pentium中时钟数分别为:3、2、2、1、 指令长度 2字节 4.SUB AX, AX ;在8088、286、386、486、Pentium中时钟数分别为:3、2、2、1、 指令长度 3字节 5.MOV BL, 0; 在8088、286、386、486、Pentium中时钟数分别为: 4、3、2、1、 指令长度 2字节 MUL BL ; 在8088、286、386、486、Pentium中时钟数分别为:143、21、38、42、 指令长度 3字节
84
TEST 测试指令 格式:TEST OPR1, OPR2 操作:(OPR1)&(OPR2)
说明:本指令影响标志位PF、SF、ZF,使CF=0、OF=0 TEST指令示例1 测试AL中的数是否为奇数,若是则转移 TEST AL, 01H JNZ NEXT ;ZF=0转 TEST指令示例2 测试AX中的有符号数是否为正数,若是则转移 TEST AX, 8000H JZ THERE ;ZF=1转
85
386及其后继机型增加下列位测试、位扫描指令:
BT (bit test) 位测试 BTS(bit test and set) 位测试并置1 BTR(bit test and reset) 位测试并清0 BTC(bit test and complement) 位测试并变反 BSF(bit scan forward) 正向位扫描 BSR(bit scan reverse) 反向位扫描 指令格式:OP DST, SRC
86
指令 操作 BT 测试DST中由SRC指定的位, 将测试位送CF BTS 测试DST中由SRC指定的位, 将测试位送CF并将DST中该位置1 BTR 测试DST中由SRC指定的位, 将测试位送CF并将DST中该位置0 BTC 测试DST中由SRC指定的位, 将测试位送CF并将DST中该位变反 BSF 从低位至高位扫描SRC第一个为“1”的位, 且将位号送DST BSR 从高位至低位扫描SRC第一个为“1”的位,
87
位测试指令示例 BT AX, 4 若执行前 (AX)=1234H, 则执行后, CF=1 若执行前 (AX)=1224H, 则执行后, CF=0 位扫描指令示例 BSF ECX, EAX ; 从右至左扫描 BSR EDX, EAX ; 从左至右扫描 若执行前 (EAX)= H, 则执行后, (ECX)=29d, (EDX)=30d
88
3.4.4 移位指令 格式:OP DST, CNT 操作:对目的操作数移动CNT指定的次数, 移位结果送DST, 移出的位进入标志位CF
2)8086/8088中CNT为1或CL寄存器的内容,其他机型中CNT为1~31或CL寄存器的内容 格式2:OP DST, REG, CNT 操作2:对操作数DST和REG移动CNT指定的次数,移位后REG内容保持不变 说明:1)格式2用于双精度移位指令 2)格式2用于32位机器
89
3、双精度移位指令:SHLD——双精度左移 SHRD——双精度右移
移位指令有10条,分三类: 1、移位指令:SHL——逻辑左移 SHR——逻辑右移 SAL——算术左移 SAR——算术右移 2、循环移位指令:ROL——循环左移 ROR——循环右移 RCL——带进位循环左移 RCR——带进位循环右移 3、双精度移位指令:SHLD——双精度左移 SHRD——双精度右移
90
SHL/SAL 逻辑/算术左移 SHR 逻辑右移 SAR 算术右移 CF bn b0 bn b0 CF bn b0 CF
91
CF ROL 循环左移 RCL 带进位循环左移 ROR 循环右移 RCR 带进位循环右移 CF CF CF
92
CF DST SHLD 双精度左移 在移位后保持REG不变 REG CF DST SHRD 双精度右移 REG 在移位后保持REG不变
93
已知(AL)=0B4H, (CF)=1, 分析下列指令执行后的结果
CF AL (1) SAL AL, 1 (2) SAR AL, 1 (3) SHL AL, 1 (4) SHR AL, 1 算术左移与逻辑左移的结果相同 算术右移与逻辑右移的结果不同 执行前 1 1 1
94
通常:算术右移N位相当于有符号数除以2N(有例外) 逻辑右移N位相当于无符号数除以2N 算术/逻辑左移N位相当于无符号数乘以2N
移位指令示例1 MOV CL, 5 SAR AL, CL 执行前 AL (60H=96) 执行后 AL (03H=3) 通常:算术右移N位相当于有符号数除以2N(有例外) 逻辑右移N位相当于无符号数除以2N 算术/逻辑左移N位相当于无符号数乘以2N 移位指令示例2 设(AX)=0012H, (BX)=0034H, 要求装配成(AX) = 1234H MOV CL, 8 ROL AX, CL ADD AX, BX 算术右移的例外是操作数为负数且最低位有1移出的时候,SAR指令产生的结果会与等效的IDIV指令的结果不同
95
移位指令示例3 已知变量Y中为一字节无符号数,计算(Y)*10, 积放在AX中。 变换:(Y)*10=(Y)*(8+2)=(Y)*2+(Y)*8 (为什么要这样变换?) MOV AL, Y ; AL<--(Y) MOV AH, 0 SHL AX, ; (Y)*2 MOV BX, AX SHL AX, ; (Y)*4 SHL AX, ; (Y)*8 ADD AX, BX ; (Y)*10 思考题:利用移位指令计算DX=3×AX+7×BX
96
移位指令示例4 SHLD EBX, ECX, 16 如执行前,(EBX)= H, (ECX)= H 则执行后,(EBX)= H, 说明: 1)386及其后继机型中可用 2)作为源操作数的寄存器提供移位值,以补目的操作数因移位引起的空缺,而执行后源操作数寄存器的值不变
97
将ASCII码串‘96’转换成压缩BCD码96H ASC ‘9’ BCD ‘6’
综合应用例1 将ASCII码串‘96’转换成压缩BCD码96H ASC ‘9’ BCD ‘6’ 96H MOV AL, ASC ; AL<--39H (‘9’) MOV CL, 4 SHL AL, CL ;左移4位 39H->90H MOV BL, AL ;BL<--90H MOV AL, ASC ;AL<--36H (‘6’) AND AL, 0FH ;AL<--06H OR BL, AL ;BL<--96H MOV BCD, BL
98
综合应用例2 分析下列指令序列的功能 MOV CL, 4 SHL DX,CL MOV BL, AH DX AX SHL AX, CL
SHR BL, CL OR DL, BL 4 4 BL 4 结论: DX:AX双字左移4位
99
关于移位指令的几点说明: SHL与SHR均会影响OF、PF、SF、ZF、CF 如果SAL将DST的最高位移到CF,改变了CF的值,则OF=1。 循环移位指令操作结果只对CF和OF有影响,CF由移入CF的内容决定,OF取决于移位一次后符号位是否改变,如改变,则OF=1。
100
3.4.5 处理器控制指令 1、标志处理指令 CLC —— 进位标志CF置0 CMC ——进位标志CF求反 STC —— 进位标志CF置1
CLD ——方向标志DF置0 STD —— 方向标志DF置1 CLI —— 中断标志 IF置0 STI —— 中断标志 IF置1
101
ENTER——建立堆栈帧(286及其后继机型用) LEAVE——释放堆栈帧(286及其后继机型用)
2、其他处理器控制指令 NOP —— 空操作 HLT —— 停机 WAIT —— 等待 ESC —— 换码 LOCK —— 封锁 BOUND——界限(286及其后继机型用) ENTER——建立堆栈帧(286及其后继机型用) LEAVE——释放堆栈帧(286及其后继机型用) BOUND, ENTER, LEAVE 3条指令请参见《Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2(2A&2B)》
102
3.4.6 顺序结构程序设计 压缩的BCD码转化成ASCII码 BCD_BUF DB 96H ASC_BUF DB 2 DUP(?)
MOV AL, BCD_BUF MOV CL, 4 MOV BL, AL SHR AL, CL ; 右移4位,将高4位填0 ADD AL, 30H MOV ASC_BUF, AL AND BL, 0FH ADD BL, 30H MOV ASC_BUF+1, BL ASC_BUF ‘9’ ‘6’ 教材上的例子请看P98中的例3.17,上机调试该程序(注意给X,Y,Z赋初值)。
103
用直接查表法完成将键盘输入的一位10进制数(0—9)转换成对应的平方值并存放在SQRBUF单元中
SQUTAB DB 0,1,4,9,16,25,36,49,64,81 SQRBUF DB ? …… MOV AH, 1 INT 21H ; DOS功能调用的1号子功能是键盘输入 SUB AL, 30H MOV BX, OFFSET SQUTAB XLAT MOV SQRBUF, AL
104
把存储单元A和B中的两个单字节压缩BCD码相加,结果存到C单元中,进位存放到C+1中。
A DB 32H B DB 15H C DB 2 DUP(?) …… MOV AL, A ; 取被加数 ADD AL, B ; 二进制加法 DAA ; 调整为十进制结果 MOV C, AL ; 存回C单元 LAHF ; 取标志位 AND AH, 01 ; 取CF位 MOV C+1, AH ; 存进位到C+1单元 要求用顺序结构,该怎么做? 用分支的方法做: MOV AL, A ADD AL, B JC L1 MOV AH,0 JMP L2 L1: MOV AH,01 L2: MOV C+1, AH DAA MOV C, AL
Similar presentations