第四周 算术运算、逻辑运算与移位操作指令
大家好,又是我,沉迷学习无法自拔的小笨蛋康sir。 这个文集将会同步更新我观看吴宁老师的《微机原理与接口技术》教学视频写的笔记,学习笔记,大概每周一章。 有问题大家可以在评论下面留言讨论,欢迎纠错! 欢迎收藏阅读,动动小手给个硬币点个赞。 ——@正能量的康sir
也可移步我的博客(https://blog.csdn.net/qq_33956508)获得更好的阅读体验(暂不更新),也会更新一些其它技术类文章。

第19讲 加法运算类指令
算术运算类指令:
加法运算指令
减法运算指令
乘法指令
除法指令
算术运算指令的执行大多对状态标志位会产生影响。
加法运算指令
加法指令
普通加法指令ADD
带进位位的加法指令ADC
加1指令INC
前面两种双操作数的加法指令对操作数的要求与MOV相同.
回顾MOV的要求:
两操作数字长必须相同;
两操作数不允许同时为存储器操作数;
两操作数不允许同时为段寄存器;
在源操作数时立即数时,目标操作数不能是段寄存器;
IP和CS不作为目标操作数,FLAGS一般也不作为操作数在指令中出现。
ADD指令
格式:ADD OPRD1,OPRD2
操作:OPRD1+OPRD2——>OPRD1
ADD指令的执行对全部6个状态标志位都产生影响
例子:
MOV AL,78H
ADD AL,99H
指令执行后6个状态标志位的状态
01111000+10011001=100010001
标志位:CF=1,SF=0,AF=1,ZF=0,PF=1,OF=0
2.ADC指令
指令格式、对操作数的要求、对标志位的影响与ADD指令完全一样
指令的操作:OPRD1+OPRD2+CF——>OPRD1
ADC指令多用于多字节数相加,使用前要先将CF清零
3.INC指令
格式:INC OPRD (OPRD不能是段寄存器,不能是立即数)
操作: OPRD+1——>OPRD
INC指令的执行不影响CF,但会影响其余5个状态标志位。
(即使是FFH再加1,也不会影响CF。INC后面不能跟基于CF状态转移的条件转移指令)
常用于在程序中修改地址指针。
例子:
求内存数据段中M1为首和M2为首的两个20字节数之和,并将结果写入M2为首的区域中。
LEA SI,M1
LEA DI,M2
MOV CX,20
CLC ;使CF=0
NEXT:MOV AL,[SI]
ADC [DI],AL;因为ADC的结果就是OPRD1+OPRD2+CF,所以上一次运算如果进位使CF=1,这次会被加上
INC SI
INC DI
DEC CX
JNZ NEXT
HLT

按“字“运算
LEA SI,M1
LEA DI,M2
MOV CX,10
CLC
NEXT:MOV AX,[SI]
ADC [DI],AX
ADD SI,2
ADD DI,2
DEC CX
JNZ NEXT
HLT

第20讲 减法运算类指令
减法指令:
普通减法指令SUB
考虑借位的减法指令SBB
减1指令DEC
比较指令CMP
求补指令NEG
减法指令对操作数的要求与对应的加法指令相同
SUB指令
格式:SUB OPRD1,OPRD2
操作:OPRD1-OPRD2——>OPRD1
对标志位的影响与ADD指令同
SBB指令
指令格式、对操作数的要求、对标志位的影响与SUB指令完全一样
指令的操作:OPRD1-OPRD2-CF——>OPRD1
DEC指令
格式:DEC OPRD
操作:OPRD-1——>OPRD
指令对操作数的要求与INC相同
指令常用于在程序中修改数值
应用程序例
程序功能:延时(定时)
MOV BL,2
NEXT1:MOV CX,0FFFFH;关于前面的0:指令中,立即数16位最高位是A-F的符号时,前面必须加0,为了编译器识别。
NEXT2:DEC CX
JNZ NEXT2;ZF=0转NEXT2
DEC BL
JNZ NEXT1;ZF=0转NEXT1
HLT;暂停执行
NEG指令(这条命令用得少)
格式:NEG OPRD ;OPRD指8/16位寄存器或存储器操作数
操作:0-OPRD——>OPRD
对一个负数取补码就相当于用零减去此数
说明:执行NEG指令后,一般情况下都会使CF为1,除非给定的操作数为零才会使CF为0.
当指令的操作数的值为80H(-128)或为8000H(-32768),则执行NEG指令后,结果不变,但0F置1,其它情况下OF均置0.
用0减去操作数,可以得到负数的绝对值。
CMP指令
格式:CMP OPRD1,OPRD2
操作:OPRD1-OPRD2
指令执行的结果不影响目标操作数,仅影响标志位
用途:用于比较两个数的大小,可作为条件转移指令转移的条件
指令对操作数的要求及对标志位的影响与SUB指令相同
CMP指令
两个无符号数的比较:CMP AX,BX
若AX>=BX ——>CF=0
若AX<BX——>CF=1
若AX=BX——>CF=0,ZF=1
CMP指令
两个带符号数的比较
CMP AX,BX
两个数的大小由OF和SF共同决定
OF和SF状态相同 AX>=BX
OF和SF状态不同 AX<BX
CMP指令例:
程序功能 在20个数中找到最大的数,并将其存放在MAX单元中。
LEA BX,MAX
LEA SI,BUF
MOV CL,20
MOV AL,[SI]
NEXT:INC SI
CMP AL,[SI]
JNC GOON ;CF=0转移
XCHS [SI],AL
GOON:DEC CL
JNZ NEXT
MOV [BX],AL
HLT

第21讲 乘除运算指令
乘法指令
无符号的乘法指令MUL
带符号的乘法指令IMUL
注意:乘法指令采用隐含寻址,隐含的是存放被乘数的累加器AL或AX及存放结果的AX,DX;
无符号数的乘法指令
格式: MUL OPRD ;OPRD不能是立即数
操作:OPRD为字节数 AL x OPRD——>AX
OPRD为16位数AXxOPRD——>DXAX
举例:MUL BYTE PTR[BX];BYTE PTR说明后面的偏移地址指向的内存单元是字节长(8位)。WORD PTR是字长(8086来说就是16位)。
ALxXXH——>AX

有符号数乘法指令
格式:IMUL OPRD
指令格式及对操作数的要求与MUL指令相同。
指令执行原理:
将两个操作数取补码(对负数按位取反加1,正数不变);
做乘法运算
将乘积取补码(按位取反加1)
2、除法指令
无符号除法指令
格式:DIV OPRD
有符号除法指令
格式:IDIV OPRD
操作
指令要求被除数是除数的双倍字长
若OPRD是字节数
执行AX/OPRD
结果AL=商 AH=余数
若OPRD是双字节数
执行:DXAX/OPRD
结果:AX=商 DX=余数
算术运算指令小结
算术运算指令执行影响状态标志位
乘法指令执行结果为相乘的双倍字长;除法指令要求被除数是除数的双倍字长
例:
MOV SI,1200H
MOV WORD PTR[SI],8765H
MOV AL,[SI]
INC SI;指向高八位 也就是87H
MUL BYTE PTR[SI];计算ALx[SI]=65H x 87H——>AX=3543H
修改一下
MOV SI,1200H
MOV WORD PTR[SI],8765H
MOV AX,[SI];所以AX=8765H
MUL WORD PTR[SI];计算AXx[SI]——>DX AX
第22讲 逻辑运算指令
逻辑运算
基本逻辑运算
与或非
异或
逻辑运算指令——实现逻辑操作的指令
与、或、非、异或
逻辑运算指令
对操作数的要求:
大多(与 或 异或)与MOV指令相同。特例:
非”运算指令要求操作数不能是立即数;需要说明字长(PTR)
对标志位的影响
除“非”运算指令,其余指令的执行都会影响除AF外的5个状态标志(CF、OF、ZF、SF、PF),如何影响:无论执行结果如何,都会使标志位CF=OF=0。ZF、SF、PF正常影响。
“非”运算指令的执行不影响标志位。
1、“与”指令
格式:AND OPRD1,OPRE2
操作:两操作数相“与”,结果送目标地址
应用:
实现两操作数按位相与的运算AND BL,[SI]
使目标操作数的某些位不变,某些位清零AND AL,0FH (AL的高四位变0,低四位不变)
在操作数不变的情况下使CF和OF清零AND AX,AX
举例:
从地址为3F8H端口中读入一个字节数(状态字),如果该数bit1位为1,则可从38FH端口将DATA为首地址的1个字输出,否则就不能进行数据传送。
要求:编写相应的程序段

MOV DX,3F8H
WATT:IN AL,DX
AND AL,02H ;把AL和00000010相与,然后判断结果是0还是非0,由此判断bit1位不是1还是1
JZ WATT ;ZF=1转移
MOV DX,38FH
MOV AX,DATA
OUT DX,AX
2、“或”运算指令
格式:OR OPRD1,OPRD2
操作:两操作数相“或”,结果送目标地址
应用:
实现两操作数相“或”的运算OR AX,[DI]
使某些位不变,某些位置“1”: OR CL,0FH
在不改变操作数的情况下使OF=CF=0 : OR AX,AX
例子:
OR AL,AL
JPE GOON ;PF=1转移
OR AL,80H
GOON:…
“或”指令的应用
将一个二进制数9变为字符‘9’
二进制9 00001001 09H
字符9 ASCII码00111001 39H
MOV AL,9
OR AL,30H
也可以用ADD AL,30H,只是运算速度和标志位影响上的差别
3、“非”运算指令
格式:NOT OPRD
操作:操作数按位取反再送回原地址
注:指令的执行对标志位无影响
例:NOT BYTE PTR[BX]
4、“异或”运算指令
格式:XOR OPRD1,OPRD2
操作:两操作数“异或”,结果送目标地址
例子
XOR BL,80H;最高位取反,低7位不变
异或:不同为1,相同为0.所以:和0异或,状态不变;和1异或,状态取反。
XOR AX,AX;使AX清零(用异或的方法效率最高)
其它清零AX的方法:
AND AX,0
SUB AX,AX
MOV AX,0000H
5、“测试“指令
格式:TEST OPRD1,OPRD2
操作:执行“与”运算,但运算的结果不送回目标地址
应用:常用于测试某些位的状态
例:从地址位3F8H的端口中读入一个字节数,当该数的bit1,bit3,bit5位同时为1时,可从38FH端口将DATA为首地址的一个字输出,否则就不能进行数据传送
编写相应的程序段。
源程序代码:
LEA SI,DATA
MOV DX,3F8H
WATT:IN AL,DX
TEST AL,02H
JZ WATT ;ZF=1转移
TEST AL,08H
JZ WATT
TEST AL,20H
JZ WATT
MOV DX,38FH
MOV AX,[SI]
OUT DX,AX
优化后:
LEA SI,DATA
MOV DX,3F8H
WATT:IN AL,DX
AND AL,2AH
CMP AL,2AH
JNZ WATT
MOV DX,38FH
MOV AX,[SI]
OUT DX,AX
再优化:
优化后:
LEA SI,DATA
MOV DX,3F8H
WATT:IN AL,DX
AND AL,2AH
XOR AL,2AH
JNZ WATT
MOV DX,38FH
MOV AX,[SI]
OUT DX,AX
第23讲 移位操作指令
控制二进制位向左或向右移动的指令
分类:非循环移位指令、循环移位指令
移位操作指令说明
指令格式在形式上为双操作数,本质上为单操作数;
指令的目标操作数为被移动对象,源操作数为移动次数
当目标为存储器操作数时,需要说明其字长
移动移动1位时由指令直接给出;移动两位及以上时,移位次数必须由CL指定。
指令源操作数 只能是1或CL
1.非循环移位指令
逻辑左移
算术左移
逻辑右移
算术右移
左移和右移的原理不一样,
逻辑左移和算数左移原理相同:左移最高位移入CF,最低位补零;
逻辑右移和算数右移原理不同:逻辑右移最低位移入CF,最高位补零;算术右移最低位移入CF,符号位会复制到最高位。(所以如果一个8位数算术右移8次会每一位都是原来符号位的数。)
左移一位乘2,右移一位除以2
算术左移和逻辑左移
(算术移位指令针对有符号数,逻辑移位指令针对无符号数)
算术左移指令:(有符号数)
SAL OPRD,1
SAL OPRD,CL
逻辑左移指令:(无符号数)
SHL OPRD,1
SHL OPRD,CL
逻辑右移:(无符号数)
SHR OPRD,1
SHR OPRD,CL
逻辑右移例:
MOV AL,68H
MOV CL,2
SHR AL,CL

算术右移:(有符号数)
格式:
SAR OPRD,1
SAR OPRD,CL

非循环移位指令的应用:
左移可实现乘法运算(左移1位 乘以2)
右移可实现除法运算(右移1位 除以2)
2.循环移位指令
不带进位位的循环指令:左移ROL、右移ROR
带进位位的循环移位:左移RCL、右移RCR
指令格式、对操作数的要求与非循环移位指令相同
不带进位位的循环移位
左移:最高位移动到CF,同时移动到最低位
右移:最低位移动到CF,同时移动到最高位

带进位位的循环移位
左移:CF移动到最低位,最高位移动到CF
右移:CF移动到最高位,最低位移动到CF

循环移位指令的应用:
用于对某些位状态的测试;
高位部分和低位部分的交换;
与非循环移位指令一起组成32位或更长字长数的移位。
例:
在内存数据段 M 1为首地 址的 4个单元中存放了 4个压缩 BCD 码 。
要求:将这4个压缩BCD码分别转换为ASCII码,并将转换结果存放在同一逻辑段、M2为首的单元中。

例:
题目分析:
压缩BCD码是用4位二进制码表示1位十进制数
转换ASCII码时需要分别转换高4位(十位数)和低4位(个位数)
0~9的ASCII码的高4位均为0011(30H)
转换低4位应先使高4位清零,转换高4位时须先将高4位移动到低4位的位置
程序例
LEA SI,M1
LEA DI,M2
MOV CH,4
Next:MOV AL,[SI]
MOV BL,AL
AND AL,0FH;高四位清零
OR AL,30H;高四位变0011,转化为ASCII
MOV [DI],AL;表示个位的8位ASCII存入[DI]
INC DI
MOV AL,BL
MOV CL,4
SHR AL,CL;逻辑右移4次。高四位移动到低四位
OR AL,30H;高四位变0011,转化为ASCII
MOV [DI],AL;十位的8位ASCII存入上个[DI]加一的地方
INC DI
INC SI
DEC CH
JNZ NExt;如果CH不为0,则跳转到Next
HLT