48
1 3.3.2 算算算算算算 涉涉两两两两两两 : 涉涉涉涉涉涉涉涉 涉涉涉 涉涉涉 涉涉涉涉涉涉涉涉涉涉涉 两两两 涉涉 两两 涉涉涉涉涉涉涉涉涉涉涉涉涉涉涉涉涉涉涉涉涉 涉涉涉涉涉涉涉涉涉 (CF,OF) 涉涉涉涉涉涉涉涉涉 涉涉涉涉涉涉涉涉涉涉涉涉 涉涉涉涉 涉涉 涉涉涉涉涉涉涉 FLAGS

3.3.2 算术运算指令

  • Upload
    marged

  • View
    111

  • Download
    0

Embed Size (px)

DESCRIPTION

3.3.2 算术运算指令. 涉及 两种类型数据 : 无符号数 和 有符号数 。对加减法指令,无符号和有符号数可采用 同一套指令 ,但应 注意: 参加的操作数必须 都是 无符号数或 都是 有符号数。 需使用不同的标志位 ( CF,OF ) 来检查无符号数和有符号数的运算结果是否溢出。 这类指令 一般都 影响标志寄存器 FLAGS 。. 表 4 - 2 算术运算类指令表. 无符号数范围 0~255 带符号数范围 -128~127. 两个 8 位数相加时有 4 种情况:. - PowerPoint PPT Presentation

Citation preview

Page 1: 3.3.2  算术运算指令

1

3.3.2 算术运算指令 涉及两种类型数据 : 无符号数和有符号数。对加减法指令,无符号和有符号数可采用同一套指令,但应注意: 参加的操作数必须都是无符号数或都是有符号数。 需使用不同的标志位 (CF,OF) 来检查无符号数和有符号数的运算结果是否溢出。 这类指令一般都影响标志寄存器 FLAGS 。

Page 2: 3.3.2  算术运算指令

2

表 4 - 2 算术运算类指令表

Page 3: 3.3.2  算术运算指令

3

• 两个 8 位数相加时有 4 种情况:

① 无符号数和有符号数均不溢出

二进制相加 无符号数加 有符号数加 0000 1000 8 +8+0001 1110 + 30 + (+30) 0010 0110 38 +38 结果 38 CF=0 OF=0

无符号数范围 0~255

带符号数范围 -128~127

Page 4: 3.3.2  算术运算指令

4

② 无符号数溢出 无符号数 有符号数 0000 1000 8 +8

+1111 1101 +253 +(-3)10000 0101 261 +5 结果 5 CF=1 OF=0

③ 有符号数溢出 0000 1000 8 +8

+0111 1101 +125 + (+125 ) 1000 0101 133 +133结果 -123 CF=0 OF=1

(补码表示)

Page 5: 3.3.2  算术运算指令

5

④ 无符号数和有符号数均溢出 无符号数 有符号数 1000 1000 136 -120+1111 0111 +247 + ( -9 )10111 1111 383 -129 结果 127 CF=1 OF=1

上面四种情况说明, CF 标志可用来表示无符号数的溢出, OF 标志可用来表示有符号数的溢出。

有符号数的溢出是一种出错状态,在运算过程中应当避免。

Page 6: 3.3.2  算术运算指令

6

• 所有的算术运算指令,都会影响 FLAGS 标志寄存器的6 个状态标志 CF/OF/ZF/SF/AF/PF(3 个控制标志 IF/DF/TF 不受影响 ) 。

• 总的讲,有这样一些规则: 当无符号数运算产生溢出 ( 即最高位向前有进位 或借位 ) 时, CF=1, 否则为 0;

当有符号数运算产生溢出时, OF=1(即 OF=CF⊕CF-

1) ,

否则为 0;

当运算结果为 0 时, ZF=1 , 否则为 0;

当运算结果为负数时, SF=1 , 否则为 0;

当运算一半位置有进位或借位时, AF=1 , 否则为 0;

  当运算结果中有偶数个1时, PF=1 , 否则为 0 。

Page 7: 3.3.2  算术运算指令

7

共有 5 条 :(1) 不带进位的加法指令 ADD 格式: ADD acc,data ADD mem/reg,data ADD mem/reg1,mem/reg2注: 1. 源和目的操作数不能同时为存储器操作数 2. 不能把段寄存器作为操作数例: ADD AL, 30H ADD AX, [BX+20H] ADD CX, SI ADD [DI], 200HADD 指令对标志位(指 6 个状态标志)都有影响。

1. 加法指令

Page 8: 3.3.2  算术运算指令

8

(2) 带进位位的加法指令 ADC

ADC 指令在形式上和功能上都有与 ADD 类似,只是相加时还要包括进位标志 CF 的内容。 例如: ADC AL, 68H ;AL←(AL)+68H+(CF) ADC AX, CX ;AX←(AX)+(CX)+(CF) ADC BX , [DI] ;BX←(BX)+[DI+1][DI]+(CF)

Page 9: 3.3.2  算术运算指令

9

例 : 有两个 4 字节的无符号数相加: 2C 56 F8 AC + 30 9E 47 BE = ? 设被加数、加数分别存放在 BUFFER1及BUFFER2 开始的两个存储区内,结果放回BUFFER1 存储区,如下页图所示。 因 CPU 只能进行 8 位或 16 位的加法运算,为此可将加法分 4 次进行。

ADC 指令主要用于多字节加法运算中

Page 10: 3.3.2  算术运算指令

10

56H

2CH

BEH

47H

BUFFER1

BUFFER2

ACH

F8H

9EH

30H

被加数

加数

数据段

多字节加法示意图

......

Page 11: 3.3.2  算术运算指令

11

程序段如下: MOV CX, 4 ; 置循环次数 MOV SI, 0 ;置 SI 初值为零 CLC ; 清进位标志 CFLL : MOV AL, BUFFER2[SI] ADC BUFFER1[SI], AL ; 带进位加 INC SI ;(SI)+1 DEC CX ;(CX)-1 JNZ LL ; 若 (CX)0, 则转 LL

思考:若最高位有进位,如何改?

Page 12: 3.3.2  算术运算指令

12

ADD/ADC 指令对条件标志位 (CF/OF/ZF/SF) 的影响:

CF 位表示无符号数相加的溢出。

OF 位表示带符号数相加的溢出。

1 结果为负0 否则

SF=1 结果为 0

0 否则ZF=

1 和的最高有效位有向高位的进位0 否则

CF=

1 两个操作数符号相同,而结果符号与之相反0 否则

OF=

Page 13: 3.3.2  算术运算指令

13

格式: INC reg/mem功能:类似于 C 语言中的 ++ 操作:对指定的

操作数加 1 例: INC AL INC SI INC BYTE PTR[BX+4]注意:本指令不影响 CF 标志,但对 AF/OF/

PF/SF/ZF 会产生影响。

3) 加 1 指令 INC (单操作数指令)

Page 14: 3.3.2  算术运算指令

14

(1) 不考虑借位的减法指令 SUB 格式: SUB dest, src 操作: dest←(dest)-(src)

注: 1. 源和目的操作数不能同时为存储器操作数 2. 不能把段寄存器作为操作数指令例子: SUB AL, 60H

SUB [BX+20H], DX SUB AX, CX

2. 减法指令

Page 15: 3.3.2  算术运算指令

15

SBB 指令主要用于多字节的减法。格式: SBB dest, src操作: dest←(dest)-(src)-(CF)

指令例子: SBB AX, CX SBB WORD PTR[SI], 2080H SBB [SI],DX

(2) 考虑借位的减法指令SBB

Page 16: 3.3.2  算术运算指令

16

例: x、 y、 z 均为 32 位数,分别存放在地址为X, X+2; Y,Y+2; Z,Z+2 的存储单元中,用指令序列实现 wx+y+24-z ,结果放在 W, W+2 单元中。

MOV AX, X MOV DX, X+2 ADD AX, Y ADC DX, Y+2 ; x+y

ADD AX, 24 ADC DX, 0 ; x+y+24

SUB AX, Z SBB DX, Z+2 ; x+y+24-z

MOV W, AX MOV W+2, DX ; 结果存入 W, W+2 单元

Page 17: 3.3.2  算术运算指令

17

作用类似于 C 语言中的”--”操作符。格式: DEC opr 操作: opr←(opr)-1

指令例子: DEC CL DEC BYTE PTR[DI+2] DEC SI

(3) 减 1 指令 DEC

注:该指令与 INC 一样,它不影响 CF 标志,但对AF/OF/PF/SF/ZF 会产生影响。

Page 18: 3.3.2  算术运算指令

18

格式: NEG opr操作: opr← 0-(opr)

对一个操作数取补码相当于用 0 减去此操作数,故利用 NEG 指令可得到负数的绝对值。 例: 若 (AL)=0FCH ,则执行 NEG AL 后, (AL)=04H, CF=1 本例中, 0FCH为 -4 的补码 , 执行求补指令后 , 即得到 4(-4 的绝对值 ) 。

(4) 求补指令 NEG

Page 19: 3.3.2  算术运算指令

19

SUB/SBB 指令对标志位 (CF/OF/ZF/SF) 的影响:

CF=1 表示无符号数减法溢出。 OF=1 表示带符号数减法溢出。

NEG 指令对 CF/OF 的影响:

CF:操作数为 0 时,求补的结果使 CF=0 ,否则 CF=1 。 OF:字节运算对 -128 求补或字运算对 -32768 求补时 OF=1, 否则 OF=0 。

1 被减数的最高有效位有向高位的借位0 否则

CF=

1 两个操作数符号相反,而结果的符号与减数相同0 否则

OF=

Page 20: 3.3.2  算术运算指令

20

格式: CMP dest, src操作: dest←(dest)-(src) (而 SUB dest, src ; dest←(dest)-(src) )

CMP 也是执行两个操作数相减 , 但结果不送目标操作数 , 其结果只反映在标志位上。

指令例子: CMP AL, 0AH CMP CX, SI CMP DI, [BX+03]

(5) 比较指令 CMP

Page 21: 3.3.2  算术运算指令

21

根据标志位来判断比较的结果 1) 根据 ZF判断两个数是否相等。若ZF=1, 则两数相等。

2)若 ZF=0 ,则两个数不相等 , 则分两种情况考虑 :

① 比较的是两个无符号数 若 CF=0,则 dest> src; 若 CF=1,则 dest< src 。 ② 比较的是两个有符号数 若 OF SF⊕ =0 ,则 dest> src; 若 OF SF⊕ =1 ,则 dest< src 。

Page 22: 3.3.2  算术运算指令

22

比较指令在使用时,一般在其后紧跟一条条件转移指令,判断比较结果的转向。

举例:比较 AL、 BL、 CL 中带符号数的大小,将 最小数放在 AL 中。程序: CMP AL,BL ; AL和 BL 比较 JNG BBB ;若 AL≤BL, 则转 XCHG AL,BL ;若 AL> BL, 则交换 BBB: CMP AL,CL ; AL和 CL 比较 JNG CCC ;若 AL≤CL, 则转 XCHG AL,CL ;若 AL> CL, 则交换 CCC: HLT思考 : 程序的结果 ? (AL、 BL、 CL 中数据的大小顺序 )

Page 23: 3.3.2  算术运算指令

23

进行乘法时: 8 位 8 位→ 16 位乘积 (即 AL mem8/reg8 → AX) 16 位 16 位→ 32 位乘积 (即 AX mem16/reg16 → DX

AX)(1) 无符号数的乘法指令 MUL mem/reg格式: MUL src操作:字节操作数 (AX) (AL) × (src) 字操作数 (DX, AX) (AX) × (src)指令例子: MUL BL ; (AL)×(BL), 乘积在 AX 中 MUL CX ; (AX)×(CX), 乘积在 DX,AX 中 MUL BYTE PTR[BX]

3. 乘法指令

Page 24: 3.3.2  算术运算指令

24

格式与 MUL 指令类似,只是要求两操作数均为有符号数。指令例子: IMUL BL ; (AX)←(AL)×(BL) IMUL WORD PTR[SI]

; (DX,AX)←(AX)×([SI+1][SI])

(2) 有符号数乘法指令 IMUL

注意: MUL/IMUL 指令中 ● AL(AX) 为隐含的乘数寄存器; ● AX(DX,AX) 为隐含的乘积寄存器; ● SRC 不能为立即数; ● 除 CF和 OF 外,对其它标志位无定义。

Page 25: 3.3.2  算术运算指令

25

MUL/IMUL 乘法指令对 CF/OF 的影响:00 乘积的高一半为零11 否则

MUL 指令 : CF/OF =

00 乘积的高一半是低一半的符号扩展11 否则

IMUL 指令 : CF/OF =

例: (AL) = A5H(-5B), (BL) = 11H (1) IMUL BL ; (AX) (AL)×(BL)

; A5×11 -5B×11=-060B F9F5

; (AX) = F9F5H CF=OF=1

(2) MUL BL ; (AX) (AL)×(BL)

; A5×11= 0AF5

; (AX) = 0AF5H CF=OF=1

Page 26: 3.3.2  算术运算指令

26

4. 除法指令进行除法时: 16位 /8 位 → 8 位商及 8 位余数

32位 /16 位 → 16 位商及 16 位余数

对被除数、商及余数存放有如下规定: 被除数 商 余数

字节除法 AX AL AH 字除法 DX:AX AX DX

Page 27: 3.3.2  算术运算指令

27

格式: DIV src

操作:字节操作 (AL) (AX) / (src) 的商 (AH) (AX) / (src) 的余数 字操作 (AX) (DX, AX) / (src) 的商 (DX) (DX, AX) / (src) 的余数指令例子: DIV CL DIV WORD PTR[BX]注:若除数为零或 AL 中商大于 FFH(或AX 中商大于 FFFFH) ,则 CPU 产生一个类型 0 的内部中断。

(1) 无符号数除法指令 DIV

Page 28: 3.3.2  算术运算指令

28

(2) 有符号数除法指令 IDIV

格式: IDIV src 操作与 DIV 类似。商及余数均为有符号数 , 且余数符号总是与被除数符号相同。 CBW与 CWD 两指令主要用于被除数扩展

注意 : 对于 DIV/IDIV 指令• AX(DX,AX) 为隐含的被除数寄存器。• AL(AX) 为隐含的商寄存器。• AH(DX) 为隐含的余数寄存器。• src 不能为立即数。• 对所有 FLAGS 的状态标志位均无定义。

Page 29: 3.3.2  算术运算指令

29

• 运算要求被除数字长是除数字长的两倍 ,若不满足则需对被除数进行扩展 , 否则产生错误。

8 位 16 位 16位 32 位 ALAX( AH AL ) AXDX AX• 对无符号数除法扩展,只需将 AH或

DX 清零即可。• 对有符号数而言,则是符号位的扩展。

可使用符号扩展指令 CBW和 CWD

关于除法操作中的字长扩展问题

Page 30: 3.3.2  算术运算指令

30

例 : 写出两带符号数 34H÷25H 的程序段。

MOV AL, 34H

MOV BL, 25H

CBW ; AL 的符号扩展到 AH

IDIV BL ; 0034H÷25H, 结果为 ; (AH)=0FH, (AL)=01H

Page 31: 3.3.2  算术运算指令

31

*5.BCD 码运算的十进制调整指令

• 专用于对 BCD 码运算的结果进行调整• 包括: AAA、DAA、 AAS、DAS、 AAM、

AAD• 均为隐含寻址,隐含的操作数为 AL和AH

• 为何要对 BCD 码的运算结果进行调整?

BCD 码本质上是十进制数,即应遵循逢十进一的规则。而计算机是按二进制(十六进制)进行运算,并未按十进制规则进行运算。

Page 32: 3.3.2  算术运算指令

32

1) 加法的十进制调整指令

(1) 非压缩 BCD 码加法调整 AAA 本指令对在 AL 中的由两个未组合的 BCD 码相加后的结果进行调正,得到一个正确的未组合的 BCD 码。注意:• AAA 指令只影响 AF和 CF ,其余标志无定义。• AAA 指令应紧跟在 ADD或 ADC 指令之后。

Page 33: 3.3.2  算术运算指令

33

如果 AL 的低 4 位> 9∨ AF=1 ,则: ① AL←(AL)+6,(AH)←(AH)+1,AF←1

② AL←((AL)∧0FH) ③ CF←AF

否则 AL←(AL)∧0FH

AAA 指令的操作如下:

Page 34: 3.3.2  算术运算指令

34

调整原理:先看一个例子 计算 8 + 9 0000 1000 +0000 1001 0001 0001 = 11

而计算机相加为 11 ,原因在于运算过程中,如遇到低 4 位往高 4 位产生进位时(此时 AF=1 )是按逢十六进一的规则,但 BCD码要求逢十进一,因此只要产生进位,个位就会少 6 ,这就要进行加 6 调正。

这个 1代表了 16 ,而实际上仅应为 10 ,即多进了 6 。

Page 35: 3.3.2  算术运算指令

35

实际上当低 4 位的结果> 9(即 A~ F 之间 )时,也应进行加 6 调正 (原因是逢十没有进位,故用加 6 的方法强行产生进位 ) 。 如对上例的结果进行加 6 : 0001 0001 11 + 0000 0110 6 0001 0111(压缩式 ) 17 ∧ 0000 1111---------------------- 0000 0001 0000 0111(非压缩式 )

调整方法:如果 AL 的低 4 位>9∨ AF=1 ,则: ① AL←(AL)+6,(AH)←(AH)+1,AF←1 ② AL←((AL)∧0FH) ③ CF←AF否则 AL←(AL)∧0FH

Page 36: 3.3.2  算术运算指令

36

例 2 :有两个字符串形式的十进制数, 2658和 3619,求二者之和。即 2658+3619=? 由题意知,被加数和加数的每一位都以ASCII 码(与非压缩 BCD 码区别)形式存放在内存中。 假定二数在内存中均是低位在前,高位在后,另留出 5 个单元存放相加的结果。内存中数据存放形式见下页图。

Page 37: 3.3.2  算术运算指令

37

36H

32H

39H

31H

STRING1

STRING2

38H

35H

36H

33H

被加数

加数

数据段

‘8’

‘5’

‘6’

‘2’

‘9’

‘1’

‘6’

‘3’

SUM 结果

......

非压缩 BCD 码3 改为 0

SI

DI

BX

CX

CX

CX

Page 38: 3.3.2  算术运算指令

38

程序段为: LEA SI, STRING1 ; STRING1偏移地址送 SI LEA DI, STRING2 ; STRING2偏移地址送DI LEA BX, SUM ; SUM偏移地址送 BX MOV CX, 4 ;循环 4 次 CLC ;清进位标志AGAIN:MOV AL, [SI] ADC AL, [DI] ;带进位加 AAA ;未压缩 BCD 码调正 MOV [BX], AL ;结果存入 SUM INC SI ;调整指针 INC DI INC BX DEC CX ;循环计数器减 1 JNZ AGAIN ;若未处理完 , 则转 AGAIN

Page 39: 3.3.2  算术运算指令

39

思考题:

( 1 ) 根据程序写出结果 SUM 的值。 ( 2 ) 若最高位有进位,程序如何修改? ( 3 ) 从此例不难看出,用 AAA 指令也可对字符串形式的十进制数加法进行调整 , 所以它又被称为加法的 ASCII 调正指令。 为什么 AAA 指令既可对非压缩 BCD 码加法进行调整 , 也可对 ASCII 码形式的十进制数进行调整? (注意 AAA 指令的第②步 )

Page 40: 3.3.2  算术运算指令

40

(2) 压缩 BCD 码加法调整 DAA 两个压缩 BCD 码相加结果在 AL 中,通过DAA 调整得到一个正确的压缩 BCD 码 .

指令操作 ( 调整方法 ) : 若 AL 的低 4 位>9∨AF=1 则 (AL)←(AL)+6, AF←1 若 AL 的高 4 位>9∨CF=1 则 (AL)←(AL)+60H, CF←1 DAA 指令影响除 OF 外所有其它标志。 DAA 指令应紧跟在ADD或ADC 指令

之后。

Page 41: 3.3.2  算术运算指令

41

例: 48H+74H=? 0100 1000 48 MOV AL, 48H + 0111 0100 74 MOV BL, 74H 1011 1100 BC ADD AL, BL + 0110 0110 66 DAA 1 0010 0010 1 22

( 进位 ) ( 进位 ) 执行 ADD 后, (AL)=BCH ,高 4 位低 4 位均大于 9,故 DAA 指令执行加 66H调整,最后结果为: (AL)=22H, CF=1, AF=1

Page 42: 3.3.2  算术运算指令

42

(1) 非压缩 BCD 码减法的十进制调正指令AAS

对 AL 中由两个非压缩的 BCD 码相减的结果进行调整。

调整操作为: 若 AL 的低 4 位>9或 AF=1, 则: ① AL←(AL)-6,AH←(AH)-1,AF←1 ② AL←(AL)∧0FH ③ CF←AF 否则: AL←(AL)∧0FH

2) 减法的十进制调整指令

Page 43: 3.3.2  算术运算指令

43

举例: 16-8=? MOV AX,0106H 0000 0110 06 MOV BL,08H - 0000 1000 - 08 SUB AL,BL 1111 1110 FE AAS - 0000 0110 - 06 1111 1000 F8 ∧0000 1111 ∧0F 0000 1000 08结果为: (AL)=08H,(AH)=0,CF=AF=1

Page 44: 3.3.2  算术运算指令

44

(2) 压缩 BCD 码减法的十进制调正指令 DAS

对 AL 中由两个压缩 BCD 码相减的结果进行调整。调整操作为:

若 AL 的低 4 位> 9∨AF=1, 则: AL←(AL)-6, 且 AF←1 若 AL 的高 4 位> 9∨CF=1, 则: AL←(AL)-60H ,且 CF←1 注意: AAS、 DAS 对标志位的影响与AAA、 DAA 相同。 AAS、 DAS 指令要求紧跟在减法指令 SUB或 SBB之后。

Page 45: 3.3.2  算术运算指令

45

3) 乘法的十进制调正指令 AAM 对 AX 中由两个非压缩 BCD 码相乘的结果进行调整。调整操作为: (AL)/0AH, (AH)← 商, (AL)← 余数注意: 隐含的操作寄存器为 AL和 AH ; AAM紧跟在MUL 指令之后使用; 影响标志位 PF、 SF、 ZF ,其它无定义 ; 用 AAM 可实现≤ 99 的二 - 十进制转换。

Page 46: 3.3.2  算术运算指令

46

例 1 :按十进制乘法计算 7×8=? 程序段如下:

MOV AL,07H ; (AL)=07HMOV CL,08H ; (CL)=08HMULCL ; (AX)=0038HAAM ; (AH)=05H,(AL)=06H

所得结果为非压缩的 BCD 码。例 2 :把 3AH 转换成等值的十进制数。 MOV AL, 3AH ; 58 AAM ; (AH)=05H , (AL)=08H

Page 47: 3.3.2  算术运算指令

47

4) 除法的十进制调正指令 AAD

对非压缩 BCD 除法运算进行调整。调整操作为: (AL)←(AH)×0AH+ (AL) AH ← 0注意: 隐含的操作寄存器为 AH, AL ; AAD 要在 DIV 指令之前使用; 影响标志位 PF、 SF、 ZF ,其它无定义 ; 用 AAD 可实现≤ 99 的十 -二进制转换。

Page 48: 3.3.2  算术运算指令

48

例 1 :按十进制除法计算 55÷7=?

程序段如下:MOV AX, 0505H ; (AX)=55BCD

MOV CL, 07H ; (CL)= 7

AAD ; (AX)=0037H

DIV CL ; (AH)=6, (AL)=7

所得结果为非压缩的 BCD 码(商 7余 6 )。

例 2 :把 73 转换成等值的二进制数。 MOV AX, 0703H ; (AX)= 73BCD

AAD ; (AX)= 0049H