博主联系方式:
QQ:1540984562
QQ交流群:892023501
群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。
算数运算指令
- 1、加减法指令ADD、ADC 、SUB 、SBB 和增量减量指令INC、DEC、NEG
- ADD ADC例题讲解
- SUB SBB例题讲解
 
- 2、比较指令CMP
- CMP例题讲解
 
- 3、乘除指令MUL IMUL DIV IDIV
- DIV、IDIV例题讲解
 
- 4、符号扩展指令CBW CWD
- 5、BCD数运算调整指令(十进制调整指令)
 
 

1、加减法指令ADD、ADC 、SUB 、SBB 和增量减量指令INC、DEC、NEG
(1)不带进位位加法指令
 指令格式:ADD DST,SRC ; DST←DST+SRC
 语法格式:ADD reg / mem ,reg/mem /imm8/imm16
 指令功能:完成两个操作数相加,结果送目的操作数DST。
 该指令要求DST、SRC 不能同时为存储器,DST不能为立即数,运算结果对标志位有影响。
 例子:
 
 (2)ADC 带进位位加法指令
 指令格式: ADC DST,SRC
 功能:与ADD指令相同,只是相加时要加上进位位的当前值。
 完成的操作为:== (DST) ← (SRC)+(DST)+ CF ==
 DST、SRC 不能同时为存储器, SRC可为立即数,运算结果对标志位有影响。
 对状态标志位的具体影响:
CF=1 二进制加法中最高有效位向高位有进位。
CF=0 二进制加法中最高有效位向高位无进位。
ZF=1 加法结果为0
ZF=0 加法结果不为0 。
OF=1 两同符号数相加(正数+正数、或负数+负数),而结果符号与其相反。
OF=0 不同符号数相加。注意: (不同符号数相加不会产生溢出)
SF=1 加法结果为负(符号位为1)
SF=0 加法结果为正(符号位为0)。
ADD ADC例题讲解
问:设在DVAR开始的连续8字节中分别存放着两个数A(00127654H)和B(00049821H)(每个数为32位),求C=A+B,并将结果C放到DVARC开始的内存中
 思路分析:完成双字(32位)相加:先用ADD把低位字相加,再用ADC完成高位字的带进位加法
data segmentDVAR DD 00127654H;DVAR DD 00049821H;DVARC DD ?	;存储相加后的值
ends
;在数据段定义数据
LEA DI,DVAR;获取DVAR地址
MOV AX,4[DI];第二个数的低位字的起始地址=DI+4,将其中内容送入AX
ADD AX,[DI];第一个数的低位字
MOV WORD PTR DVARC,AX;保存结果的低位字
MOV AX,6[DI];
ADC AX,2[DI];	带进位		
MOV DVARC+2,AX;保存结果的高位字
语法知识点:
 汇编中何时使用WORD/BYTE PTR
 伪指令DD DW DB
 (3) SUB DST,SRC 不带借位减法指令
 功能:进行两个操作数的相减操作,结果送回DST。
 完成的操作: DST←DST-SRC
 (4) SBB DST,SRC 带借位减法指令
 功能:与SUB相类似,但相减时还应减去标志CF的当前值。
 完成的操作: DST←DST-SRC-CF
 语法格式:SUB(SBB) reg/mem ,reg/mem/imm
 DST、SRC可以是存储器或寄存器, 但不能同时为存储器。运算结果对标志位有影响。
 
SUB SBB例题讲解
问:设DVAR1和DVAR2保存有双字数,求(DVAR1)- (DVAR2),并将结果保存在双字变量DVARR中。
data segmentDVAR1 DD 00127654H;DVAR2 DD 00049821H;DVARR DD ?	;存储相减后的值
ends
;在数据段定义数据
MOV AX,WORD PTR DVAR1;
SUB AX,WORD PTR DVAR2;
MOV WORD PTR DVARR,AX;保存结果的低位字
MOV AX,WORD PTR DVAR1+2;
SBB AX,WORD PTR DVAR2+2;	带借位		
MOV WORD PTR DVARR+2,AX;保存结果的高位字
(5) INC OPR 加1指令
 对指定的操作数进行加1操作,其操作数OPRD可以是任意一个通用寄存器,也可以在内存单元中。
 该指令影响标志位,但不影响CF标志位。
 完成的操作: OPR OPR+1
INC AL ; AL←AL+1
INC (SI); (SI) (SI)+1
(6) DEC OPR 减1指令
 功能:实现对操作数的减1操作,操作数可以是通用寄存器,也可以在内存单元中。减1操作时,把操作数看作为无符号的二进制数。
 完成的操作: OPRD OPRD-1
 语法格式:DEC reg/mem
DEC BX ; BX BX-1
DEC(DI);(DI) (DI)-1
(7) NEG (取负指令)
 格式: NEG DST;
 
 转换成二进制算法:
OPR OPRD ‘+1
或: OPR FFFFH -(OPR)’+1
2、比较指令CMP
指令格式: CMP OPR1,OPR2;OPR1-OPR2 结果影响标志位。
 语法格式:CMP reg/mem ,reg/mem/imm
 功能:做两个数的比较,与减法指令一样执行OPR1-OPR2操作,但相减后不回送结果,只是根据相减结果修改标志位。
 OPR1、OPR2可以是存储器或寄存器,不能同时为存储器,OPR2还可为立即数,运算结果对标志位有影响。
 比较结果有三种可能:AX>BX 、 AX<BX 、 AX=BX
 对标志位的影响:
CF=1 减法中最高有效位向高位有借位( AX<BX )
CF=0 减法中最高有效位向高位无借位( AX≥BX )
ZF=1 结果为0(AX=BX);
ZF=0 ,结果不为0(AX≠BX)
OF=1 两数符号相反(正数-负数、或负数-正数),而结果符号与减数(BX)相同。
OF=0 同符号数相减。
CMP例题讲解
问:若自BLOCK开始的内存缓冲区中,有100个带符号的数,希望找到其中最大的一个值,并将它放到MAX单元中。
 分析思路:循环语句 加一减一指令、找到最大值:需要比较语句CMP
 带符号的数:一个字大小
data segmentBLOCK DD 00127654H;......BLOCK DD 00049821H;MAX DD ?;
ends
;在数据段定义数据
MOV BX,OFFSETBLOCK;		==LEA BX,BLOCK;	获取地址
MOV AX,[BX];	将第一个数存入AX
INC BX;
INC BX;	地址转到下一个数:BX+2
MOV CX,99;计数器置数
AGAIN:CMP AX,[BX];	AX中的数和BX指向的数
JG   NEXT     ;大于则转,AX>[BX]
MOV AX,[BI];	否则把[BX]送入AX
NEXT:DEC CX;
INC BX;
INC BX;计数减1,bi指向下一个数
JNZ AGAIN;所有的数比较完了吗?没完转AGAIN继续
MOV [MAX],AX;	将AX内容送入存储单元MAX
3、乘除指令MUL IMUL DIV IDIV
(1)无符号数乘法指令MUL
 格式:MUL SRC ;(AX)(AL)×(SRC)字节乘法
 (DX,AX)(AX)×(SRC)字乘法
 语法格式:MUL reg/mem
 要求:字节运算时,目的操作数(被乘数)(隐含指令)必须是累加器AL,在做乘法运算时要先把被乘数设置好,即被乘数和乘积是隐含的形式,被乘数和乘数都是无符号数,乘积存放在寄存器AX中。进行字运算时,目的操作数必须是累加器AX,乘积在寄存器DX,AX中。源操作数不允许使用立即数。
 示意图:
 
 (2) 带符号数乘法指令IMUL
 格式:IMUL SRC ;(AX) (AL)×(SRC)字节
 ;(DX,AX) (AX)×(SRC)字
 语法格式:IMUL reg/mem
 注意:操作同无符号数乘法相同
 对标志位的影响也可相类比。
例: MOV AL 66H;被乘数送AL
MOV BL 88H;乘数送BL
MUL BL ;无符号乘法,AL×BL结果存于AX中
MOV AX,6666H ;被乘数(字)送AX
MOV BX,4567H ;乘数(字)送BX
MUL BX ;结果的高字在DX中,低字在AX中
何时使用带符号和不带符号?
 MUL和IMUL指令的使用条件是由数的属性决定(由程序设计者自己确定)。
 如(11111111B)× (11111111B)为无符号数时为255×255=65025,
 而为有符号数时为(-1)×(-1)=1,因此根据要相乘数的格式决定选用那一种指令。
 对标志位的影响:
 乘法指令运算结果影响状态标志,但对CF、OF有特殊的定义。
 
 字与字节相乘:
MOV AL,15H;
CBW; CBW = convert byte to word逻辑意义就是al的符号扩展到ah
节扩展CBW的基本功能是(AH)=00H,当(AL)的最高有效位为0时。AH)=FFH,当(AL)的最高有效位为1时
MOV BX,0FB78H;
IMUL BX;
(3)无符号数除法指令DIV (被除数和结果隐含)
 格式:DIV SRC ;(AL) (AX)/(SRC)除法的商
 字节操作 (AH) (AX)/(SRC)除法余数
 字操作 (AX) (DX,AX)/(SRC)除法的商
 (DX) (DX,AX)/(SRC)除法余数
 (4)带符号除法指令IDIV (被除数和结果隐含)
 格式:IDIV SRC ;(AL) (AX)/(SRC)除法的商
 字节操作 (AH) (AX)/(SRC)除法余数
 字操作 (AX)(DX,AX)/(SRC)除法的商
 (DX)(DX,AX)/(SRC)除法余数
 形象表示:
 == 需要注意点:==
 1) 如果除数为0,则产生0型中断。
 2) 除法指令运算结果对状态标志无定义。
 3) 除法指令要求字操作时,被除数必须为32位,除数是16位,商和余数是16位;字节操作时,被除数必须为16位,除数是8位,商和余数是8位。(被除数必须大于除数)。
 4)有符号与无符号除法完成的操作相同,只是做有符号除法时,操作数是有符号的,得到的商和余数也是有符号的,余数的符号同被除数符号相同。
DIV、IDIV例题讲解
问:***分别实现下列数据的无符号和有符号除法
 DATA7 DW 9400H ;被除数
 DATA8 DW 0060H ;除数
 QUOT DW ? ;商
 REMAIN DW ? ;余数 ***
;无符号
MOV AX,DATA7;
MOV DX,0;
DIV DATA8;
MOV QUOT,AX;
MOV REMAN,DX;
;有符号
MOV AX,DATA7;
;CWD可将AX内容扩展到DX、AX。规则是若AX最高位=1,则执行后DX=FFFFH;若AX最高位=0,则执行后DX=0000H
IDIV DATA8;
MOV QUOT,AX;
MOV REMAN,DX;
符号扩展指令CBW,CWD是什么意思?
4、符号扩展指令CBW CWD

5、BCD数运算调整指令(十进制调整指令)
开始写这一类指令时感觉有点蒙,看了这篇文章感觉稍微好了点,建议先看这篇文章再往下了解具体指令。
 http://www.elecfans.com/dianzichangshi/20171124586013.html
 BCD码:用4位二进制码表示1位10进制数。
 它和二进制码并不相同,为了得到正确结果我们需要进行修正。
 BCD分为两类:
 1)、分离BCD码:8位寄存器包含一位BCD码 (非压缩BCD)
 2)、组合BCD码:8位寄存器包含2位BCD码 (压缩BCD)
 1、加法调整指令AAA DAA
 AAA——对AL中非压缩的BCD数的加法结果进行调整;
 具体操作:
 1、对相加结果AL的低四位+6修正
 2、观察AF
 AF有进位,则AH=1,CF=1,AF=l;
 AF无进位,则AH=0,CF=0,AF=0。
 3、清AL的高4位
DAA——对AL中的两个压缩十进制数相加之和进行调整,得到压缩十进制和;
 具体操作:
 对相加结果AL的低4位和高4位分别进行+6修正。对标志位的影响等同于ADD指令
 压缩BCD和非压缩BCD的区别
 压缩BCD码
 用一个字节表示两位BCD码,高位表示十位数BCD码,低位表示个位数BCD码,称为压缩型BCD码。
 例如:十进制数56用压缩8421BCD码表示为0101 0110
 非压缩BCD码
 用一个字节表示一位BCD码,高位为0,低位为BCD码。
 例如:十进制数5用非压缩8421BCD码表示为0000 0101
 参考链接
 问:计算十进制数的运算:4+8
;通过键盘输入得到的是ASCII码,将其看做分离BCD码,则高4位为无效部分,因此不需要清除.
MOV AL,34H;		BCD表示十进制数34
MOV BL,28H;		BCD表示十进制数28
ADD AL.BL;
;在此之前(AL)=5CH,(按照二进制相加)
DAA;
;在此之后,(AL)=62H(转化成BCD码)
2、减法调整指令AAS DAS
 AAS——对AL中非压缩的BCD数的减法结果进行调整;
 对非压缩BCD码的低位AL进行减6处理,观察AF有无借位
 AF有借位,则CF=1,AF=l;
 AF无借位,则CF=0,AF=0。
 DAS——对AL中的两个压缩十进制数相减之差进行调整,得到压缩十进制差;
 对压缩BCD码的高位AH和低位AL都进行减6处理。对标志位的影响等同于SUB指令。
 问:计算十进制数的运算:5-9
;通过键盘输入得到的是ASCII码,将其看做分离BCD码,则高4位为无效部分,因此不需要清除.
MOV AL,05H;		BCD表示十进制数5
MOV BL,09H;		BCD表示十进制数9
SUB AL.BL;
AAS
问:计算十进制数的运算:31-87
;通过键盘输入得到的是ASCII码,将其看做分离BCD码,则高4位为无效部分,因此不需要清除.
MOV AL,31H;		BCD表示十进制数5
MOV BL,87H;		BCD表示十进制数9
SUB AL.BL;
DAS
3、乘法调整指令AAM
 AAM——对AX中两个ASCII未压缩十进制相乘结果进行调整;
 调整方法:将结果(AL)除以10,商为(AH)的低4位,余数为(AL)的低4位
 问:计算十进制数的运算:78*
;通过键盘输入得到的是ASCII码,将其看做分离BCD码,则高4位为无效部分,因此不需要清除.
MOV AL,7;		
MOV BL,8;	
MUL BL;
AAM
4、除法调整指令AAM
 AAD——在除法指令前对AX中ASCII未压缩的十进制数进行调整;
 调整方法:(AL)=(AH)*10+(AL);使(AH)=0,接下来操作是正常的除法操作。
问:计算十进制数的运算:274*
;通过键盘输入得到的是ASCII码,将其看做分离BCD码,则高4位为无效部分,因此不需要清除.
MOV AX,0207H;		
MOV BL,4;	
AAD ;(AX)<-001BH
DIV BL;
总结,因为BCD的类型而总分为两类的指令其实本质相同,其中,
 加减乘都是通过一些操作从而将结果进行修正,从二进制转为BCD形式。
 除法却是对被除数进行操作,这点需要特别注意*
【没事儿可以到我主页看看】https://blog.csdn.net/qq_42604176
