8086的算术运算类指令能够对二进制或十进制(BCD码)数进行加、减、乘、除运算, *** 作数的数据形式可以是8位或16位的无符号数或带符号数。对于单 *** 作数指令,不允许使用立即数形式;对于双 *** 作数指令,只有源 *** 作可以使用立即数,两个 *** 作数中必须有一个在寄存器中。
1. 加法指令指令格式: 加法 ADD DST, SRC; (DST)←(SRC)+(DST)
带进位加法 ADC DST, SRC; (DST)←(SRC)+(DST)+CF
加1 INC OPR; (OPR)←(OPR)+1
注意:这三条指令运算结果将影响状态标志位,但是INC指令不影响标志CF。下面以8位数加法运算为例作简要说明。 [例4.20]因为运算结果没有超出单字节无符号数范围,所以CF=0;运算结果超出单字节有符号数范围,所以OF=1;其他标志 ZF=0,SF=1。 以上运算可以用两条指令实现: MOV AH,01 ADD AH,7FH
ADC指令主要用于多字节或多精度数据相加的运算。例如进行二组四字节(双精度)数1122 3344H和5566 7788H的相加运算时,使用单字节加法指令需要执行4次加法运算,运算过程中,通过ADC指令将低字节运算产生的进位加到高位字节,而使用字加法指令,只需要执行两次加法运算,当然也必须通过ADC指令处理低字运算产生的进位。使用ADC指令,必须先将CF标志置0。2. 减法指令
指令格式:
减法 SUB DST,SRC ; (DST)←(DST)-(SRC)
带进位减法SBB DST,SRC ; (DST)←(DST)-(SRC)-CF
减1 DEC OPR ; (OPR)←(OPR)-1
求补 NEG OPR ;(OPR)←0FFFFH-(0PR)+1
比较 CMP OPR1, OPR2 ; (OPR1)-(OPR2)
SBB指令主要用于多字节或多精度数据相减的运算;NEG指令对 *** 作数进行取反加1的 *** 作;CMP指令类似SUB指令执行减法 *** 作,但不产生运算结果,对标志位影响见表4.3。 这几条指令的运算结果都影响状态标志位,只是DEC指令不影响标志CF。
[例4.22]
直接相减算式结果为: (4006AH)=520FH,SF=0,ZF=0,CF=0,OF=0
补码加法算式结果为: (4006AH)=520FH,SF=0,ZF=0,CF=1,OF=0
算式中FECAH是(-0136H)的补码。
可见,两种算式中运算结果是相同的,但是对标志CF的影响不同,因为是减法运算,正确结果应是CF=0。用补码加法得到运算结果CF=1,应求反后送入CF。 表4-3 CMP指令对状态标志位的影响
3. 乘法指令乘法运算分为无符号数运算和有符号数运算,各有相应的指令,并使用双 *** 作数。两个8位二进制数相乘,积为16位二进制数;两个16位二进制数相乘,积为32位二进制数。指令格式:
无符号数乘法 MUL SRC;(AX)←(AL)×(SRC)8位数乘法
(DX,AX)←(AX)×(SRC)16位数乘法
带符号数乘法 IMUL SRC; *** 作同上,但是 *** 作数为带符号数
注意:
进行字节运算时,目的 *** 作数必须是累加器AL,乘积在寄存器AX中;进行字运算时,目的 *** 作数必须是累加器AX,乘积在寄存器DX、AX中。源 *** 作数不允许使用立即数寻址方式。
乘法指令运算结果只影响状态标志CF、OF,对其他状态标志位无影响(状态不定)。
对于 MUL 指令,如果字节型数据相乘之积(AH)=0或字数据相乘之积(DX)=0,则CF=OF=0,否则CF=OF=1;对于IMUL指令,如果字节数据相乘之积AH或字数据相乘之积DX的内容是低一半的符号扩展,则CF=OF=0,否则CF=OF=1。
4. 除法指令除法运算分为无符号数运算和有符号数运算,各有相应的指令,并使用双 *** 作数。当除数是8位或16位二进制数时,要求被除数是16位或32位的二进制数。指令格式:
无符号数除法 DIV SRC;(AL)←(AX)/(SRC)8位二进制数除法的商
(AH)←(AX)/(SRC)8位二进制数除法的余数
或(AX)←(DX,AX)/(SRC) 16位二进制数除法的商
(DX)←(DX,AX)/(SRC) 16位二进制数除法的余数
带符号数除法 IDIV SRC; *** 作同上,但是 *** 作数为带符号数
注意:
当除数是字节数据时,被除数必须放在AX中,当除数是字数据时,被除数必须放在DX,AX中。
除法指令运算结果对状态标志无定义(状态不定)。但是,若除数为0或带符号数,则当除法运算结果超出规定的范围时,将产生0号中断,与溢出标志OF无关。
8086/8088 规定 IDIV 指令运算结果余数的符号与被除数相同。
带符号数除法运算中,当被除数位数不够时,则需将被除数扩展到所需的位数。8086/8088设有带符号数扩展指令。
指令格式:
字节扩展到字CBW;将寄存器AL中的符号位扩展到寄存器AH
字扩展到双字CWD;将寄存器AX中的符号位扩展到寄存器DX
这两条指令不影响标志位。
5. 十进制调整指令BCD码是一种用二进制编码的十进制数,又称为二—十进制数。8086/8088中BCD码分为两种形式: 其一是用四位二进制数表示一位十进制数,称为压缩的BCD码;其二是用八位二进制数表示一位十进制数,称为非压缩的BCD码,它的低四位是BCD码,高四位没有意义。由于BCD码是四位二进制编码,四位二进制数共有16个编码,BCD码只用其中的10个,其余没用的编码称为无效码。BCD码运算结果进入或跳过无效码区时,都会出现错误。为了得到正确结果,必须进行调整。8086/8088针对压缩BCD码和非压缩BCD码,分别设有两组十进制调整指令,其调整方法略有不同。
(1) 压缩BCD码十进制调整指令指令格式:
加法十进制调整DAA;(AL)←把AL中的和调整到压缩BCD码格式
减法十进制调整DAS;(AL)←把AL中的差调整到压缩BCD码格式
调整方法是:
累加器AL低4位大于9或辅助进位标志位AF=1,则累加器AL加06H修正。累加器AL高4位大于9或进位标志位CY=1,则累加器AL加60H修正。累加器AL高4位大于等于9,低4位大于9,则累加器AL进行加66H修正。
[例4.26]进行BCD码加法运算59+68=127
此例中,BCD码加法结果的低四位使AF=1,高四位大于9,所以加66H进行修正。
注意:压缩BCD码加法或减法十进制调整指令必须用在ADD(ADC)或SUB(SBB)指令之后,调整结果对标志OF无影响,对其他状态标志位均有影响。
减法十进制调整方法与加法十进制调整类同,只是将加6变为减6 *** 作。
CODE SEGMENTASSUME CS:CODE
MAIN PROC FAR
START:
mov cx,5
mov si,cx
LOOP1:
MOV CX,SI
MOV BX,0
GET_CHAR0:MOV AH,1
INT 21H
CMP AL,0DH
JE T0
SUB AL,30H
JL T0
CMP AL,9
JG T0
CBW
XCHG AX,BX
MOV CX,10
MUL CX
XCHG AX,BX
ADD BX,AX
JMP GET_CHAR0
T0:ADD AL,30H
CMP AL,2BH
JE JIA
CMP AL,2DH
JE JIAN
CMP AL,2AH
JE CHENG
CMP AL,2FH
JE CHU
JMP EXIT0
JIA:MOV DI,BX
CALL JIAFA
JMP EXIT0
JIAN:MOV DI,BX
CALL JIANFA
JMP EXIT0
CHENG:MOV DI,BX
CALL CHENGFA
JMP EXIT0
CHU:MOV DI,BX
CALL CHUFA
EXIT0:CALL SHUCHU
MOV DL,0AH
MOV AH,2
INT 21H
DEC SI
MOV CX,SI
LOOP LOOP1
MOV AH,4CH
INT 21H
RET
MAIN ENDP
shuru PROC NEAR
MOV BX,0
GET_CHAR:MOV AH,1
INT 21H
CMP AL,0DH
JE EXIT
SUB AL,30H
JL EXIT
CMP AL,9
JG EXIT
CBW
XCHG AX,BX
MOV CX,10
MUL CX
XCHG AX,BX
ADD BX,AX
JMP GET_CHAR
EXIT:
RET
shuru ENDP
JIAFA PROC NEAR
CALL SHURU
ADD BX,DI
RET
JIAFA ENDP
JIANFA PROC NEAR
CALL SHURU
MOV AX,DI
SUB AX,BX
MOV BX,AX
RET
JIANFA ENDP
CHENGFA PROC NEAR
CALL SHURU
MOV AL,BL
MOV BX,DI
MUL BL
MOV BX,AX
RET
CHENGFA ENDP
CHUFA PROC NEAR
CALL SHURU
MOV AX,DI
SUB AH,AH
DIV BL
MOV BL,AL
RET
CHUFA ENDP
shuchu PROC NEAR
MOV CX,1000
CALL DEC_DIV
MOV CX,100
CALL DEC_DIV
MOV CX,10
CALL DEC_DIV
MOV CX,1
CALL DEC_DIV
RET
shuchu ENDP
DEC_DIV PROC NEAR
MOV AX,BX
MOV DX,0
DIV CX
MOV BX,DX
CMP AL,9
ADD AL,30H
MOV DL,AL
MOV AH,2
INT 21H
RET
DEC_DIV ENDP
CODE ENDS
END START
此程序会循环四次,输入四次后自动退出。
可以输入加减乘除。
楼主,你用是什么的汇编啊。是8088/8086,还是单片机的,是什么公司的产品,什么型号的,它们都是有一些差异的。我在这就说一下思路吧。用汇编做加减法比较容易,带进位不带进位的都可以,做乘除是比较难的,一般是不用它做的,必须时也最好转换成加减,这样在实现的时候才会方便。
我再说点MC51的汇编语言,也许你能用上。(都是一些语法)
带进位加法:addc a,#data (a)+#data+(c)-->(a)
addc a,data (a)+(data)+(c)-->(a)
addc a,@r(a)+((r))+(c)-->(a)
带进位的减法:subb a,#data
subb a,data
subb a,@r1
乘法:mul a b(a)*(b)
除法:div a b(a)/(b)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)