第 三 章 指令系统 - jpk.pku.edu.cnjpk.pku.edu.cn/course/wjyl/script/chapter9.pdf比较指令....
TRANSCRIPT
-
《微机原理A》
第九讲:寻址方式与指令系统(三)
主讲老师:王克义
-
本讲主要内容
• 8086/8088指令系统
• 算术运算与逻辑运算指令
• 指令的机器语言表示形式
-
9.1 运算类指令• 二进制算术运算指令
• BCD数运算指令
• 逻辑运算和移位指令
-
1. 算术运算指令(1) 二进制加法和减法指令
名称 格式 操作
加法 ADD DST,SRC DST SRC+DST
带进位加法 ADC DST,SRC DST SRC+DST+CF
减法 SUB DST, SRC DST DST-SRC
带借位减法 SBB DST,SRC DST DST-SRC-CF
标志: O D I T S Z A P C 所有状态标志都受影响×---×××××
-
Example 1• 编写实现下列二进制运算的程序段
W X+Y+24-Z(X,Y,Z均为字变量)MOV AX, X ;ADD AX, Y ;ADD AX, 24 ;SUB AX, Z;MOV W, AX;
-
• 双倍精度运算(操作数的长度为双字--两个16位)
2000H 3000H低16位 低16位
高16位 高16位
• 把2000H地址开始的两个字(低字在前)和3000H地址开始的两个字相加,和存放在2000H开始处。
Example 2
-
程序段
MOV SI , 2000H ;取第一个数的首地址MOV AX, [SI] ; 将第一个数的低16位送AXMOV DI ,3000H ; 取第二个数的首地址ADD AX, [DI] ; 第一个数的低16位和第2个数 的低16位相
;加.(不加CF,但此条指令的执行影响CF)MOV [SI],AX ; 存低16位相加结果MOV AX, [SI+2]ADC AX,[DI+2] ;两个高16位连同CF(低16位相加形成的)相加.MOV [SI+2],AX ; 存高16位相加结果.
-
例3:假设数的长度(以字计)存放 于2500H字节单元,两个无符号二进制数分别 从2000H和3000H开始存放(低字在前),求两数之和并存放于2000H开始处,试编程实现。
-
参考答案MOV CL , DS:[2500H] MOV SI , 2000H MOV DI , 3000H CLC ; 清CF
LOOP1: MOV AX , [SI] ADC AX , [DI] MOV [SI] , AX INC SI INC SI INC DI INC DI DEC CL JNZ LOOP1 MOV AX , 0H ;ADC AX , 0H ; 处理最高位产生的进位MOV [SI] , AX ; HLT
-
(2) 加1 减1和比较指令名称 格式 操作
加 1 INC OPR OPR OPR+1减 1 DEC OPR OPR OPR-1求补(Negate) NEG OPR OPR -OPR比较 CMP OPR1,OPR2 OPR1-OPR2
标志:INC和DEC: O D I T S Z A P C × - - - ×××× -
NEG和CMP: × - - - ×××××
-
NEG指令• NEG指令把操作数当成一个带符号数,如果原操作数是正数,NEG指令则将其变成负数(用补码表示);如果原操作数是负数(用补码表示),NEG指令则将其变成正数。
• 方法:“各位(包括符号位)求反,末位加1”.
-
Example• 若AL=00010001B=+17,执行NEG AL后,
AL=11101111B=[-17]补
• 若AL=11010001B=[-47]补,执行NEG AL后,AL=00101111B=+47
-
比较指令
• 比较指令实际上是做减法,但不回送相减的结果,只是根据结果置标志。通常,把CMP指令安排在条件转移指令(如JZ , JG , JO 等)之前。
• 例:如果X>50,转移到TOO-HIGH; 如果带符号减法X-Y引起溢出,则转移到OVERFLOW; 否则,计算 X-Y ,并将结果存放在RESULT中。(其中,X、Y、RESULT均为字变量)。
-
程序段
• 下述程序段使用了前面介绍的几条指令,也用到了后面即将
介绍的条件转移指令.
MOV AX , X ;将(X)移入AXCMP AX , 50 ; 比较JG TOO-HIGH ; 如果(X)大于50,则转向 TOO-HIGHSUB AX, Y ; 否则减去(Y)JO OVERFLOW ;溢出则转移JNS NONNEG NEG AX
NONNEG: MOV RESULT , AX ;无溢出,取绝对值并将结果存入RESULT…
TOO-HIGH: …
OVERFLOW: …
-
(3) 乘法指令(i) 带符号乘法格式:IMUL SRC 所执行的操作:
字节操作数: AX (Al)*(SRC)字操作数:DX:AX (AX)*(SRC)(乘积带符号,并符合一般代数符号规则)(ii) 无符号乘法格式:MUL SRC所执行的操作:
同IMUL,但操作数和乘积均不带符号。
-
(4) 除法指令• 带符号除法• 格式:IDIV SRC
所执行的操作:字节除数:AL (AX)/(SRC) 之商
AH (AX)/(SRC) 之余数字除数: AX (DX:AX)/(SRC)之商
DX (DX:AX)/(SRC) 之余数商和余数是带符号的:商的符号符合一般代数符号规则,余数的符号与被除数相同.
• 无符号除法• 格式:DIV SRC
所执行的操作:与IDIV相同,但操作数,商和余数均是无符号的。
-
例:二进制四则混合算术运算程序段
• 试计算:AX (V-(X*Y+Z-540))/X 之商DX 余数
(其中,X ,Y ,Z ,V 均为字变量)
-
MOV AX, X ;IMUL Y ; X*Y,结果在DX:AX中MOV CX, AX;MOV BX, DX; 将乘积存在BX:CX中MOV AX, Z;CWDADD CX, AX ; 将符号扩展后的Z加到BX:CX中的乘积上去ADC BX, DX;SUB CX, 540;SBB BX, 0; 从BX:CX中减去540MOV AX, V;CWD;SUB AX, CX; 从符号扩展后的V中减去(BX:CX)并SBB DX, BX; 除以X,商在AX中,余数在DX中。IDIV X;
PROGRAM
-
• 所谓BCD数,就是二进制编码的十进制数(Binary Coded Decimal),它是用4位二进制码表示一位十进制数(0000~1001是合法BCD码;1010~1111是非法BCD码).
• 组合BCD数:用一个字节表示2位BCD数例:37
• 分离BCD数:用一个字节的低4位表示一位BCD数,高4位为0.例:37
0011 0111
0000 0011 0000 0111
2. BCD数运算指令
-
(1)组合BCD数十进制调整原理例 1 : 18 + 7 = 25
0 0 0 1 1 0 0 0 - - - - - - - - 18+ 0 0 0 0 0 1 1 1 - - - - - - - - 7
0 0 0 1 1 1 1 1 - - - - - - - - ?(1111是非法BCD码)
需要对结果进行变换(调整),方法:“加6调整”0 0 0 1 1 1 1 1
+ 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 1 - - - - - - - - 25(正确结果)
第3位向第4位(低半字节向高半字节)有进位,AF=1
-
例2 : 19 + 8 = 270 0 0 1 1 0 0 1 --------- 19
+ 0 0 0 0 1 0 0 0 --------- 80 0 1 0 0 0 0 1----------21(结果不对)
运算时,低位数字向高位数字产生了进位(AF=1或 CF=1),实际上是“满16进一”,但进到高位,当成了10,
“少6”,需“加6调整”。0 0 1 0 0 0 0 1
+ 0 0 0 0 0 1 1 00 0 1 0 0 1 1 1-----------27(结果正确)
可见,在BCD数运算时,若AF=1(或CF=1)就需在低4位(或高4位)上进行“加6调整”。
-
BCD数十进制调整规则• BCD数加法十进制调整规则:
如果两个BCD数字相加的结果是一个在1010~1111之间的二进制数,或者有向高一位数字的进位(AF=1或CF=1),则应在现行数字上加6(0110B)调整。
• BCD数减法十进制调整规则:(1) AF=1, 或运算结果的低位是一个在1010~1111之间的二进制数,则在低位上要进行-6调整。
(2) CF=1,或运算结果的高位是一个在1010~1111之间的二进制数,则在高位上要进行-6调整。
-
(2)组合BCD数十进制调整指令• 加法的十进制调整指令 :
格式: DAA 操作:AL AL中的和数调整到组合BCD格式
• 减法的十进制调整指令:格式: DAS操作:AL AL中的差数调整到组合BCD格式
DAA-- Decimal Adjust for AdditionDAS-- Decimal Adjust for Subtraction
标志:O D I T S Z A P CU ---×××××
-
• 其中,BCD1,BCD2, BCD3定义为字变量,可分别存放4位数字的组合BCD数。假定字变量BCD1的值为1834 ,字变量BCD2的值为2789,指出执行每条指令的操作及执行指令后AL, AF, CF 的内容。
3 4
1 8
8 9
2 7
2 34 6
BCD1
BCD1+1
BCD2
BCD2+1
例:计算BCD3 BCD1+BCD2
-
指令 操作 AL CF AFMOV AL, BCD1; AL 34 34 - - 不受影响ADD AL, BCD2 ; AL 34+89 BDH 0 0DAA ; 调整 23 BCD 1 * 无关紧要MOV BCD3,AL; (BCD3) 23 23 1 *MOV AL, BCD1+1; AL 18 18 1 *ADC AL, BCD2+1; AL 18+27+CF 40H 0 1DAA ; 调整 46 BCD 0 *MOV BCD3+1,AL; (BCD3+1) 46 46 0 *
即 1834+2789=4623
程序段
-
组合BCD数• 8086没有组合BCD数的乘法和除法调整指令,主要原因是相应的调整算法比较复杂,所以,8086不支持组合BCD数的乘除法运算。
• 如果要处理组合BCD数的乘除法问题,可以把操作数(组合BCD数)变换成相等的二进制数,然后用二进制算法进行运算,运算完成后再将结果转换成BCD数。
-
(3)分离BCD数调整指令• 加法调整指令(AAA)• 减法调整指令(AAS)• 乘法调整指令(AAM)• 除法调整指令(AAD)
-
3. 逻辑运算和移位指令(1)逻辑运算指令
名称 格式 操作
非 NOT OPR OPR OPR或 OR DST,DST DST DST V SRC 与 AND DST,SRC DST DST SRC异或 XOR DST,SRC DST DST SRC测试 TEST OPR1,OPR2 OPR1 OPR2
-
CF
CF
CF
CF
名称 格式 操作
逻辑左移 SHL OPR,CNT 0(其中,OPR是除立即数以外的任何一种寻址方式,CNT可以是1或CL)
算术左移 SAL OPR,CNT 0 左移1位时,若最高位(即符号位)发生改变(0 1或1 0),
则OF=1,未发生改变时,OF =0;逻辑右移 SHR OPR,CNT 算术右移 SAR OPR,CNT
(2) 移位指令
-
• 逻辑移位:把操作数作为无符号数进行移位。
右移时,最高位补0;左移时,最低位补0。
• 算术移位:把操作数作为有符号数进行移位。
右移时,最高位保持不变;左移时,最低位补0。
-
CF
CF
(3) 循环移位指令
• 不带进位的循环左移ROL OPR ,CNT
• 不带进位的循环右移ROR OPR , CNT
-
CF
CF
• 带进位的循环左移RCL OPR , CNT
• 带进位的循环右移RCR OPR , CNT
-
移位指令的应用
• 用来改变数据格式,有时用来提供程序 控制功能(例如根据移位后的CF状态作JC或JNC转移,或一些专门的运算功能。
• 注意:左移n位与乘以2 (n)等效,例如:6×2 (2)= 00000110×100=00011000
• 同样,右移n位与除以2(n)等效,如果是逻辑右移,除法是无符号的;如果是算术右移,则除法是带符号的。(保持最高位不变,并做符号的扩展)
-
例1:编程实现将AL中的数乘以10(求10x)SAL AL, 1 ; 将AL中数左移1位,得2xMOV BL, AL ; 2x保存在BL中.MOV CL, 2 ; 移位次数送入CLSAL AL, CL ; 2x左移2位,得8xADD AL, BL ; 2x 加上8x,AL中为10x
-
0000 4
0000 5
0000 6
0000 7
…
5 4
7 6
…
• 例2:把从UNPACKED开始的16位分离BCD数转换成组合BCD数,并把结果存在从PACKED开始的单元里。
UNPACKED PACKED
-
程序段
MOV DX, 8 ;将循环次数计数初值置为8 MOV CL, 4 ;移位次数置为4MOV SI, 0MOV DI, SI
CONVERT:MOV AX, [SI+UNPACKED]SHL AL, CLSHR AX, CLMOV PACKED[DI], AL ;存储结果ADD SI, 2INC DI DEC DX ;循环计数值减1JNZ CONVERT
-
9.2 转移指令• 无条件转移指令• 条件转移指令• 循环控制指令• 中断及中断返回指令
-
无条件转移指令示例
• 段内直接转移: JMP L ;• 段内间接转移: JMP AX;(转移地址的偏移量在寄存器或内存单元中)
• 段间直接转移: JMP 2500H:3600H• 段间间接转移: JMP DWORD PTR[DI](转移地址在DI,DI+1,DI+2,DI+3四个字节单元中)
-
1. 段内直接转移段内直接短转移:格式: JMP SHORT OPR (符号地址)
操作: IP IP+8 位位移量(-127~+128)段内直接近转移: 格式: JMP NEAR PTR OPR(符号地址)
操作: IP IP+16位位移量2. 段内间接转移:
格式: JMP WORD PTR OPR(可使用除立即数之外的任何一种寻址方式)
操作: IP (EA)
-
3. 段间直接(远)转移格式: JMP FAR PTR OPR ( 标号)操作: IP OPR的段内偏移量
CS OPR所在段的段基值4. 段间间接转移
格式: JMP DWORD PTR OPR操作: IP (EA)
CS (EA+2)例: JMP DWORD PTR [BX+DI+6]
-
循环控制指令
• 通常的循环控制MOV CX , N
BEGIN: ….…. 循环体….
DEC CXJNZ BEGIN LOOP BEGIN
有了LOOP指令,程序得到简化
-
• 从技术上讲,循环控制指令是条件转移指令,只不过它是专门为实现循环控制而设计的。
名称 格式/其它格式 测试条件
循环 LOOP OPR CX = 0
为零或相等循环 LOOPZ OPR/LOOPE OPR ZF=1且CX=0
非零或不相等循环 LOOPNZ OPR/LOOPNE OPR ZF=0 且CX=0
-
• 执行每条指令时,CX CX-1• OPR为一个标号• 标志---------• 意味着ZF并不受CX-1的影响,即ZF=1时,CX未必为0;ZF是前面指令决定的,与loop 指令执行时CX是否为0无关。
-
• 例1:执行下述程序段后,AX=MOV CX , 5MOV AX , 50
LP1: SUB AX , CXLOOP LP1HLT
-
例2:在100个字符构成的字符串中寻找第一个$字符。(在循环出口处可以根据ZF标志和CX寄存器的值来确定是否找到以及该字符的位置)
MOV CX , 100 MOV SI,0FFFH;假设字符串从偏移地址1000H处开始存放
NEXT:INC SI CMP BYTE PTR[SI], ’$’ LOOPNZ NEXT
• 注意,上面程序段中ZF标志是由CMP指令设置的,而与CX减1动作无关。
-
子程序调用和返回指令
(1)调用指令
名称 格式 操作
段内直接调用 Call DST SP SP-2(SP+1,SP) IP(保存返回地址)IP IP+位移量(形成转移地址)
段内间接调用 Call DST SP SP-2(SP+1,SP) IPIP (EA) (EA:由DST 的寻址方式
计算出的有效地址
例: Call Display ( 段内直接调用);Call WORD PTR [BX] (段内间接调用)
-
名称 格式 操作段间直接调用 Call DST SP SP-2
(SP+1,SP) CSSP SP-2 保存返回地址(SP+1,SP) IPIP 偏移量CS 段基值 形成转移地址
例:Call FAR PTR Display
-
名称 格式 操作段间间接调用 Call DST SP SP-2
(SP+1,SP) CSSP SP-2 保存返回地址(SP+1,SP) IP
IP (EA)CS (EA+2) 形成转移地址
EA:由DST的寻址方式计算出的有效地址
例:Call DWORD PTR [BX+SI]
-
(2) 返回指令
名称 格式 操作
段内返回 RET (C3H) IP (SP+1,SP)SP SP+2
段内带参数返回 RET n IP (SP+1,SP)SP SP+2SP SP+n(n 为偶数)
-
名称 格式 操作
段间返回 RET (CBH) IP (SP+1,SP)SP SP+2CS (SP+1,SP)SP SP+2
段间带参数返回 RET n IP (SP+1,SP)SP SP+2CS (SP+1,SP)SP SP+2SP SP+n(n为偶数)
-
• Proc-A PROC NEAR(或FAR)____________
过程名 ____________ ...
____________RET
Proc-A ENDP
过程(子程序)的基本结构
-
堆栈操作及RET n 指令使用举例• 例.在进入子程序FFIT 之前,主程序将字符串的首地址放于堆栈顶部,执行子程序FFIT 时,将字符串首址取到ES和DI 中,并取出要显示的字符,然后调用DISPLAY 子程序进行显示。主程序: FFIT: DISPLAY:
call FFIT call DISPLAY ret ? ret 2
-
FFIT 子程序段FFIT: PUSH BP
MOV BP, SPPUSH ESPUSH DILES DI , [BP+04] ; 将字符串首址送ES和DI
AAA: ES:MOV AL, [DI] ; 从ES和DI所指单元取字符CMP AL,00 ; 判取出的字符是否为结束符JZ EEEPUSH AX ;通过堆栈为DISPLAY子程序传递参数(要显示的字符)CALL DISPLAY INC DI JMP AAA
EEE: POP DIPOP ESPOP BPRET ?
-
堆栈操作及RET n 指令使用举例
DISPLAY 子程序返回地址AX
DIES
sp BPFFIT 子程序的返回地址字符串首址偏移量
字符串首址段基值
-
9.3 指令的机器码格式1. 指令前缀和段超越前缀的编码前缀并不是一条独立的指令,而是对其后的指令或对
指令中操作数的一种限制。
• 8086/8088提供的前缀有三种:串操作的重复前缀(REP 、REPE/REPZ、EPNE/REPNZ)总线封锁前缀(LOCK)段超越前缀(ES:、CS:、SS:、DS:)
• 这些前缀共有7种不同的编码,长度都是一个字节,如表9-20所示。
-
指令前缀 指令前缀的编码 段超越前缀 段超越前缀的编码
LOCK 11110000(F0H)REPNE/REPNZ 11110010(F2H)REPE/REPZ 11110011(F3H)REP 11110011(F3H)
ES: 00100110(26H)CS: 00101110(2EH)SS: 00110110(36H)DS: 00111110(3EH)
指令前缀及段超越前缀的编码
-
2. 指令的机器码格式• 8086/8088的机器指令长度(不包括前缀)随指令的不同而不同,最短的为1个字节,最长为6个字节。
• 指令代码中各字节的排列顺序依次为:1个字节的操作码,可能存在的1个寻址方式字节,可能存在的1~2个字节的地址位移量(或地址)和可能存在的1~2个字节的立即数。
• 指令中的地址位移量(或地址)和立即数如果是16位的话,都是低字节放在存储器的低地址单元,高字节放在存储器的高地址单元。指令的一般格式如下图所示:
-
如下图所示:
操作码字节
寻址方式字节
低字节 高字节 低字节 高字节
位移量(或地址) 立即数
8086/8088指令编码的一般格式
-
(1) 操作码字节• 操作码字节用来表示该指令执行的操作,每条指令都有操
作码字节。大多数指令都使用8位的操作码,但有些指令的操作码少于8位或多于8位。
• 各种情况下的操作码字节共有10种格式。• D位用于需要指明两个寄存器/存储器操作数的双操作数
指令中。这种指令的两个操作数必须有一个是寄存器,D位则用来指出寻址方式字节中用reg域标识的那个寄存器是源操作数还是目的操作数:
若D=0,则该寄存器是源操作数;若D=1,则该寄存器是目的操作数。
• W位用于指明是字节操作还是字操作:若W=0,则是字节操作;若W=1,则是字操作。
-
(2) 寻址方式字节• 大多数指令的寻址方式字节分为三个域,即mod域、reg域和r/m域。
• mod域占两位,代表“方式”;reg域占3位,是通用寄存器的3位代码;r/m域占3位,代表存储器的某个地址或某个通用寄存器。
• 各种情况下的寻址方式字节共有5种格式,如图9.1所示。
mod reg r/m mod 0 sr r/m mod XXX r/m XXXXXXXX mod UUU r/m
图9.1 寻址方式字节的各种编码格式
-
reg域 sr域
000 001
010 011 100 101 110 111 00 01 10 11
W=1 AX CX DX BX SP BP SI DI
W=0 AL CL DL BL AH CH DH BHES CS SS DS
表9-1 reg域和sr域所代表的寄存器
-
表9-2 mod域和r/m域的编码及解释
00 01 10 11
寄存器寻址存储器寻址不带位移量
存储器寻址带8位位移量
存储器寻址带16位位移量
W=1 W=0
000 [BX+SI] [BX+SI+disp8] [BX+SI+disp16] AX AL
001 [BX+DI] [BX+DI+disp8] [BX+DI+disp16] CX CL
010 [BP+SI] [BP+SI+disp8] [BP+SI+disp16] DX DL
011 [BP+DI] [BP+DI+disp8] [BP+DI+disp16] BX BL
100 [SI] [SI+disp8] [SI+disp16] SP AH
101 [DI] [DI+disp8] [DI+disp16] BP CH
110 16位直接地址 [BP+disp8] [BP+disp16] SI DH
111 [BX] [BX+disp8] [BX+disp16] DI BH
mod
r/m
-
例1: 将指令“MOV [BX+DI-6],CL”写成机器码格式。
• 解 :这是一条寄存器送存储器的指令。由附录二可知该指令的格式如下,是一条3字节指令:
10 00 10 DW mod reg r/m disp8因为(reg域指出的)寄存器是源操作数,所以D=0;由CL寄
存器的编码知reg=001。因为是字节操作,所以W=0。因为目的操作数是存储器且带有8位位移量,所以mod=01。寻址方式[BX+DI+disp8]的r/m=001。位移量为(-6),其补码是11111010。因此,该指令的机器码是“10001000 01 001 001
11111010”。
-
例例2:2: 将指令将指令““ADD AXADD AX,,BXBX””写成机器码格式写成机器码格式。
• 解: 这是一条将两个寄存器的内容相加,将结果送入其中一个寄存器的指令。由附录二可知该指令的格式如下,是一条两字节指令:
00 00 00 DW mod reg r/m设 reg域指出的寄存器是目的操作数,所以D=1;由AX寄存器的编码知reg=000。
因为是字操作,所以W=1。因为另一个操作数(源操作数)也是寄存器,所以
mod=11,另一个寄存器BX的编码为011。因此,该指令的机器码是“00000011 11 000 011”。
-
作业(九)
• 教材 P290• 12. 15. 17.
第九讲:寻址方式与指令系统(三) ��主讲老师:王克义本讲主要内容 9.1 运算类指令1. 算术运算指令Example 1Example 2程序段例3:参考答案(2) 加1 减1和比较指令NEG指令Example比较指令程序段(3) 乘法指令(4) 除法指令例:二进制四则混合算术运算程序段PROGRAM2. BCD数运算指令(1)组合BCD数十进制调整原理BCD数十进制调整规则(2)组合BCD数十进制调整指令例:计算BCD3 BCD1+BCD2程序段组合BCD数(3)分离BCD数调整指令3. 逻辑运算和移位指令(2) 移位指令 (3) 循环移位指令移位指令的应用例1:编程实现将AL中的数乘以10(求10x) 程序段 9.2 转移指令无条件转移指令示例循环控制指令 子程序调用和返回指令(2) 返回指令过程(子程序)的基本结构堆栈操作及RET n 指令使用举例 FFIT 子程序段堆栈操作及RET n 指令使用举例9.3 指令的机器码格式指令前缀及段超越前缀的编码2. 指令的机器码格式8086/8088指令编码的一般格式(1) 操作码字节(2) 寻址方式字节例1: 将指令“MOV [BX+DI-6],CL”写成机器码格式。例2: 将指令“ADD AX,BX”写成机器码格式。作业(九)