一,算术运算的数据类型
二,算术运算指令对标志位的影响
三,二进制运算指令
1,加法指令
1)不带进位加法指令ADD(ADDition)
格式:ADD DST,SRC
操作:
将目的操作数和与源操作数相加,将结果送给目的操作数//DST <= DST+SRC
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
全部影响
b,带进位加法指令ADC(ADdiion with Carry)
格式:ADC DST,SRC
操作:将目的操作数和与源操作数相加,再加上进位标志CF,将结果送给目的操作数 //DST <= DST+SRC+CF
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
全部影响
c,加1指令(INCrement by 1)
格式:INC DST
操作:将目的操作数加1,结果送回目的操作数 //DST <= DST +1
寻址方式:
DST可以是MEM/REG
不可以是data/SEG
对状态位的影响:
除了CF,其他全部影响
例, 计算两个多字节十六进制数之和:3B74AC60F8H+20D59E36C1H=?
式中被加数和加数均有5个字节,可以编一个循环程序实现以上运算。假设已将被加数和加数分别存入从DATA1和DATA2开始的两个内存区,且均为低位字节在前,高位字节在后,如图4.15所示。要求相加所得结果仍存回以DATA1为首址的内存区。
程序流程图如下图,程序如下:
MOV CX,5 ;设置循环次数
MOV SI,0 ;置位移量初值
CLC ;清进位CF
LOOPER:MOV AL,DATA2[SI] ;取一个加数
ADC DATA1[SI],AL ;和一个被加数相加
INC SI ;位移量加1
DEC CX ;循环次数减1
JNZ LOOPER ;加完否,若没完,转LOOPER,继续相加
HLT ;程序暂停
2)减法指令
a,不带进位减法指令SUB(subtract)
格式:SUB DST,SRC
操作:
将目的操作数减去源操作数,结果送回目的操作数 //DST <= DST-SRC
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
全部影响
b,带进位减法指令SBB(subtract with borrow)
格式:SBB DST,SRC
操作:将目的操作数减去源操作数,再减去标志位CF,结果送回目的操作数
//DST <= DST-SRC-CF
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
全部影响
c,减1指令DEC(Decrement)
格式:DEC DST
操作: 将目的操作数减1,结果送回目的操作数 //DST <= DST -1
寻址方式:
DST可以是MEM/REG
不可以是data/SEG
对状态位的影响:
除了CF,其他全部影响
d,求补指令NEG(Negate)
格式:NEG DST
操作:将0减去目的操作数,结果送给目的操作数 // DST <= 0-DST
寻址方式:
DST可以是MEM/REG
对状态位的影响:
全部影响
注:利用NEG指令可以得到负数的绝对值
e,比较指令CMP(Compare)
格式:CMP DST,SRC
操作:目的操作数减去源操作数,结果并不送到目的操作数中,因此,执行后,二者内容均保持不变,结果反映在状态标志位上 //DST-SRC
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
相当于减法,但不保存结果,仅影响标志。
例1:
内存数据段存放了200个带符号数,首地址为TAB1,要求将各数取绝对值后存入以TAB2为首址的内存区。
由于200个带符号数中可能既有正数,又有负数,因此先要判断正负。如为正数,可以原封不动地传送到另一内存区;如为负数,则需先求补即可得到负数的绝对值,然后再传送。程序如下:
LEA SI,TAB1 ;(SI)←源地址指针
LEA DI,TAB2 ;(DI)←目标地址指针
MOV CX,200 ;(CX)←循环次数
CHECK: MOV AL,[SI] ;取一个带符号数到AL
OR AL,AL ;AL内容不变,只影响标志位
JNS NEXT ;若(SF)=0,则转NEXT
NEG AL ;否则求补
NEXT: MOV [DI],AL ;传送到目标地址
INC SI ;源地址加1
INC DI ;目标地址加1
DEC CX ;循环次数减1
JNZ CHECK ;如不等于零,则转CHECK
HLT ;停止
例2:
在数据段从myoata开始的存储单元中分别存放两个8位无符号数,试比较他们的大小,并将大者传送到max单元。
LEA BX ,MYDATA ;MYDATA偏移地址送BX
MOV AL ,[BX] ;第一个无符号数送AL
INC BX ;BX指向第二个无符号数
CMP AL,[BX] ;两个数比较
JNC DONE ;若CF=0,则转DONE
MOV AL ,[BX] ;否则,第二个无符号数送AL
DONE MOV MAX ,AL ;较大的无符号数送MAX单元
HLT ;停止
3)乘法指令
乘法指令具有两个操作数,一个是源操作数,另一个目的操作数是隐含的操作数。
a,无符号乘法指令MUL(Unsigned Multiple)
格式:MUL SRC
操作:两个操作数均按无符号数来处理。
当SRC为8位时,隐含的目的操作数从AL中获得,乘积为16位,放在AX中。
当SRC为16位时,隐含的目的操作数从AX中获得,乘积为32位,放在DX:AX中。
例:
MUL AL ;AL乘AL,结果放在AX中
MUL BX ;AX乘BX,结果在DX:AX中
MUL BYTE PTR[DI+6] ;AL乘存储器(8位),结果放在AX中
MUL WORD PTR ALPHA ;AX乘存储器(16位)结果放在DX:AX中
寻址方式:SRC可以是REG/MEM
对状态位的影响:MUL指令对CF和OF有影响,SF,ZF,AF和PF不确定。
如果运算结果的高半部分(AH或DX中)为0,则(CF)=(DF)=0,若(CF)=(DF)=1,则说明AH或DX中包含着乘积的有效数字。
例:
MOV AL, 14H ;(AL)=14H
MOV CL, 05H ;(CL)=05H
MUL CL ;(AX)=0064H, (CF)=(OF)=0
本例中的高半部分AH为0,因此(CF)=(DF)=0。
b,带符号数的乘法指令IMUL(Signed Multiple)
格式:IMUL SRC
操作:两个操作数均按有符号数来处理。
当SRC为8位时,隐含的目的操作数从AL中获得,乘积为16位,放在AX中。
当SRC为16位时,隐含的目的操作数从AX中获得,乘积为32位,放在DX:AX中。
寻址方式:SRC可以是REG/MEM
对状态位的影响:MUL指令对CF和OF有影响,SF,ZF,AF和PF不确定。
若乘积的高半部分仅仅是低半部分符号位的扩展,则状态标志位(CF)=(DF)=0,若(CF)=(DF)=1,说明高半部分包含有效数字。
4)除法指令
a,无符号数除法指令DIV(Unsigned divide)
格式:DIV SRC
操作:
1、字节除法:AX/SRC, 商=>AL, 余数=>AH
2、字除法:DX,AX/SRC, 商=>AX, 余数=>DX
b,带符号数除法指令IDIV(Signed divide)
格式:IDIV SRC
操作:类似DIV。
说明:
1、SRC 为 REG/MEM。
2、除法指令影响状态标志但对所有标志无定义。
3、商可能出现溢出,会立即产生除法溢出中断。
5)符号扩展指令
a,字节扩展指令
CBW(Convert byte to word)字节扩展到字
格式:CBW ;如果(AL)<80H,则(AH)00H,否则(AH)0FFH
操作:把AL扩展到AX。
b,字扩展指令
CWD(Convert word to double word)字扩展到双字
格式:CWD ;如果(AX)<8000H,则(DX)0000H,否则(DX)0FFFFH
操作:把AX扩展到DX,AX 。
说明:
1、CBW和CWD对标志位无影响
2、扩展方法
由符号扩展指令实现,正数补0,负数补1。
(无符号数的扩展:将高位补0)
例:若(AL)=0F2H,执行 CBW 后,(AX)=0FFF2H
4,十进制数(BCD码)运算指令
在微处理器中,没有专用的BCD码运算指令,使用二进制运算指令进行BCD码数的运算后,要用BCD码运算调整指令进行调整,重新得到BCD码的结果。举例如下:
1、34H+29H 按照二进制加法得到的结果是 5DH
2、用调整指令DAA调整成BCD码,规则是
- 低4位>9或AF=1结果加06H;
- 高4位>9或CF=1结果加60H;
3、调整以后得到:5DH + 06H = 63H,这是BCD码运算的结果。
压缩型BCD码的调整指令:
DAA加法调整
DAS减法调整
非压缩格型BCD码的调整指令:
AAA加法调整
AAS减法调整
AAM乘法调整
AAD除法调整
这类指令的操作数隐含为AL或AX
AAA指令的操作为:
如果 (AL) ∧0FH>9 或 (AF)=1
则 (AL) ←(AL)+06H
(AH) ←(AH)+1
(AF) ← 1
(CF) ←(AF)
(AL) ←((AL) ∧ 0FH)
否则 (AL) ←((AL) ∧ 0FH)
DAA指令的操作为:
如果 (AL) ∧0FH>9, (AF)=1
则 (AL) ←(AL)+06H
(AF) ← 1
如果 (AL) > 9FH 或 (CF)=1
则 (AL) ←(AL)+60H
(CF) ← 1
例]要求计算两个十进制数之和,7+8=?。可用以下指令实现:
MOV AX, 0007H ;(AL)=07H,(AH)=00H
MOV BL, 08H ;(BL)=08H
ADD AL, BL ;(AL)=0FH
AAA ;(AL)=05H,(AH)=01H
;(CF)=(AF)=1
MOV AX, 0007H ;(AL)=07H,(AH)=00H
MOV BL, 08H ;(BL)=08H
ADD AL, BL ;(AL)=0FH
DAA ;(AL)=15H,(AH)=00H
;(CF)=0,(AF)=1
AAS指令的操作为: (非压缩型BCD码调整)
如果 (AL) ∧0FH>9 或 (AF)=1
则 (AL) ←(AL)-06H
(AH) ←(AH)-1
(AF) ← 1
(CF) ←(AF)
(AL) ←((AL) ∧ 0FH)
否则 (AL) ←((AL) ∧ 0FH)
DAS指令的操作为: (压缩型BCD码调整)
如果 (AL) ∧0FH>9, (AF)=1
则 (AL) ←(AL)-06H
(AF) ← 1
如果 (AL) > 9FH 或 (CF)=1
则 (AL) ←(AL)-60H
(CF) ← 1
AAM指令的操作为:(将二进制数转换成十进制数)
(AH)←(AL)/0AH的商;即AL除以10,商送AH
(AL)←(AL)/0AH的余数;即AL除以10,余数送AL
例:要求进行以下十进制乘法运算:7*9=?
解:可编程序段如下
MOV AL,07H ;(AL)=07H
MOV BL,09H ;(BL)=09H
MUL BL ;(AX)=07H09H=003FH
AAM ;(AH)=06H,(AL)=03H
AAD指令的操作为:(将十进制数转换成二进制数)
(AL)←(AH)0AH+(AL)
(AH)←0
例:要进行以下十进制除法运算:73÷2=?
解:可编程序段如下:
MOV AH,07H ;(AH)=07H,(AL)=03H
MOV AL,03H ;(AH)=07H,(AL)=03H
MOV BL,02H ;(BL)=02H
AAD ;(AL)=49H(即十进制数73)
DIV BL ;(AL)=24H(商),(AH)=01H(余数)
AAM ;(AH)=03H,(AL)=06H