280 likes | 535 Views
第 3 章 程序设计的基本技术. 1 乘法指令 进行乘法时: 8 位* 8 位→ 16 位乘积 16 位* 16 位→ 32 位乘积 (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].
E N D
1 乘法指令 进行乘法时:8位*8位→16位乘积 16位*16位→32位乘积 (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.1 顺序程序设计
格式与MUL指令类似,只是要求两操作数均为有符号数。格式与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外,对其它标志位无定义。
00 乘积的高一半为零 11 否则 MUL指令: CF/OF = 00 乘积的高一半是低一半的符号扩展 11 否则 IMUL指令: CF/OF = 乘法指令对CF/OF的影响: 例:(AL) = A5H(-5B),(BL) = 11H (1) IMUL BL ; (AX) (AL)×(BL) ; A5×11 -5B×11=-060B F9F5 ; (AX) = F9F5HCF=OF=1 (2) MUL BL ; (AX) (AL)×(BL) ; A5×11= 0AF5 ; (AX) = 0AF5HCF=OF=1
2. 除法指令 • 进行除法时:16位/8位→8位商 32位/16位→16位商 • 对被除数、商及余数存放有如下规定: 被除数 商 余数 字节除法 AX AL AH 字除法 DX:AX AX DX
格式: 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
(2) 有符号数除法指令IDIV 格式: IDIV src 操作与DIV类似。商及余数均为有符号数,且余数符号总是与被除数符号相同。 注意: 对于DIV/IDIV指令 • AX(DX,AX)为隐含的被除数寄存器。 • AL(AX)为隐含的商寄存器。 • AH(DX)为隐含的余数寄存器。 • src不能为立即数。 • 对所有条件标志位均无定义。
关于除法操作中的字长扩展问题 • 除法运算要求被除数字长是除数字长的两倍,若不满足则需对被除数进行扩展,否则产生错误。 • 对于无符号数除法扩展,只需将AH或DX清零即可。 • 对有符号数而言,则是符号位的扩展。可使用符号扩展指令CBW和CWD
3 字节-字转换指令(因除法指令常要用到,故提前讲) 格式:CBW ;把AL的符号位复制到AH CWD ;把AX的符号位复制到DX 用途:用于有符号数的除法。 例如:(AL) = A7H,则执行CBW后,AH的内 容为FFH。
例: 写出34H÷25H的程序段。 MOV AL,34H MOV BL,25H CBW ; AL的符号扩展到AH IDIV BL ; 0034H÷25H,结果为 ; (AH)=0FH, (AL)=01H
*3.1.2.BCD码运算的十进制调整指令 • 专用于对BCD码运算的结果进行调整 • 包括:AAA、DAA、AAS、DAS、AAM、AAD • 均为隐含寻址,隐含的操作数为AL和AH • 为何要对BCD码的运算结果进行调整? BCD码本质上是十进制数,即应遵循逢十进一的规则。而计算机是按二进制(十六进制)进行运算,并未按十进制规则进行运算。
1)加法的十进制调整指令 (1)非压缩BCD码加法调整AAA 本指令对在AL中的由两个未组合的BCD码相加后的结果进行调正,得到一个正确的未组合的BCD码。 • AAA指令只影响AF和CF,其余标志无定义。 • AAA指令应紧跟在ADD或ADC指令之后。
如果AL的低4位>9∨AF=1,则: ① AL←(AL)+6,(AH)←(AH)+1,AF←1 ② AL←((AL)∧0FH) ③ CF←AF 否则AL←(AL)∧0FH AAA指令的操作如下:
调整原理:先看一个例子 计算8+9 0000 1000 见右式 +0000 1001 0001 0001 = 11 结果应为17,而计算机相加为11,原因在于运算过程中,如遇到低4位往高4位产生进位时(此时AF=1)是按逢十六进一的规则,但BCD码要求逢十进一,因此只要产生进位,个位就会少6,这就要进行加6调正。 这个1代表了16,而实际上仅应为10,即多进了6。
实际上当低4位的结果>9(即A~F之间)时,也应进行加6调正 (原因是逢十没有进位,故用加6的方法强行产生进位) 。 如对上例的结果进行加6: 0001 0001 11 + 0000 0110 6 0000 0111 17 ^ 0000 1111 ---------------------- 1 0000 1111
例2:有两个字符串形式的十进制数,2658和 3619,求二者之和。即2658+3619=? 由题意知,被加数和加数的每一位都以ASCII码形式存放在内存中。 假定二数在内存中均是低位在前,高位在后,另留出5个单元存放相加的结果。 内存中数据存放形式见下页图。
STRING1 38H ‘8’ 被加数 35H ‘5’ 36H ‘6’ 32H ‘2’ ... STRING2 ‘9’ 数据段 39H 31H ‘1’ 加数 36H ‘6’ 33H ‘3’ ... SUM 结果
程序段为: 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
思考题: 1.根据程序写出结果SUM的值。 2.若最高位有进位,程序如何修改? 3.从此例不难看出,用AAA指令也可对字符串形式的十进制数加法进行调整,所以它又被称为加法的ASCII调正指令。为什么AAA指令既可对非压缩BCD码加法进行调整,也可对ASCII码形式的十进制数进行调整?(注意AAA指令的第②步)
(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 • 除OF外,DAA指令影响所有其它标志。 • DAA指令应紧跟在ADD或ADC指令之后。
例:0100 1000 48H MOV AL,48H + 0111 010074H MOV BL,74H 1011 1100 BCH ADD AL,BL + 0110 011066H DAA 1 0010 0010 1 22H (进位) (进位) 执行ADD后,(AL)=BCH,高4位低4位均大于9,故DAA指令执行加66H调整,最后结果为: (AL)=22H, CF=1, AF=1
(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)减法的十进制调整指令
举例: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
(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 • DAS对OF无定义,但影响其余标志位。 • DAS指令要求跟在减法指令之后。
3) 乘法的十进制调正指令AAM 对AX中由两个非压缩BCD码相乘的结果进行调整。调整操作为: (AL)/0AH, (AH)←商,(AL)←余数 • 隐含的操作寄存器为AL和AH; • AAM跟在MUL指令之后使用; • 影响标志位PF、SF、ZF,其它无定义; • 用AAM可实现≤99的二-十进制转换。
例1:按十进制乘法计算7×8=? 程序段如下: MOV AL,07H ;(AL)=07H MOV CL,08H ;(CL)=08H MUL CL ;(AX)=0038H AAM ;(AH)=05H,(AL)=06H 所得结果为非压缩的BCD码。 例2:把3AH转换成等值的十进制数。 MOV AL,3AH ;58 AAM ;(AH)=05H,(AL)=08H
4) 除法的十进制调正指令AAD 对非压缩BCD除法运算进行调整。调整操作为: (AL)←(AH)×0AH+(AL) AH ← 0 • 隐含的操作寄存器为AH,AL; • AAD要在DIV指令之前使用; • 影响标志位PF、SF、ZF,其它无定义; • 用AAD可实现≤99的十-二进制转换。
例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