(1)逻辑移位指令。
①SHL——逻辑左移指令。
形式1:SHL 操作数,1。
功能:操作数的内容连同CF的内容一起左移1位,尾部空位补0,CF中的原有的内容丢弃,如图9-7所示。
图9-7 左移指令
相同功能:操作数左移1位,具有乘2的功能。
该指令有如下两种形式:
SHL R,1 ; 把通用寄存器的内容左移1位
SHL M,1 ; 把内存数的内容左移1位
形式2:SHL 操作数,CL。
功能:操作数的内容连同CF的内容一起左移CL中的数的位数。
相同功能:操作数左移N位,具有乘2N的功能。
②SHR——逻辑右移指令。
形式1:SHR 操作数,1。
形式2:SHR 操作数,CL。
功能:操作数的内容连同CF的内容一起右移1位或(CL)位,高位移空的位补0,如图9-8所示。
图9-8 右移指令
相同功能:操作数右移N位,具有无符号数除以2N的功能。
该指令有如下两种形式:
SHR R,I/CL ; 把通用寄存器的内容右移1位或(CL)位
SHR M,I/CL ; 把内存数的内容右移1位或(CL)位
(2)算术移位指令。
①SAL——算术左移指令。
形式1:SAL 操作数,1。
形式2:SAL 操作数,CL。
功能:完全与逻辑左移指令一样。
②SAR——算术右移指令。
形式1:SAR 操作数,1。
形式2:SAR 操作数,CL。
功能:操作数的内容连同CF的内容一起右移1位或(CL)位,高位移空的位补符号位,如图9-9所示。
图9-9 算术右移指令
相同功能:操作数右移N位,具有带符号数除以2N的功能。
该指令有如下两种形式:
SAR R,1/CL ; 把通用寄存器的内容右移1位或(CL)位
SAR M,1/CL ; 把内存数的内容右移1位或(CL)位
【例9-6】编程序实现一个字节数乘64。
注意:实现此功能的算法有很多,但是最巧妙的方法是通过该字节数×256/4来实现。
源程序:
.MODEL SMALL
.STACK 100H
.DATA
bNum DB 45
.CODE
start:MOV AX,@DATA
MOV DS,AX
MOV AH,bNum
MOV AL,0;(AX)=bNumX 256
SHR AX,1
SHR AX,1
.EXIT 0
END start
在调试环境下运行程序,可以看到AX寄存器的内容为0840H。
【例9-7】编写一程序实现将字变量w中的无符号数除以8,商和余数分别放入字变量wQuot和字节变量bRema中。
注意:我们可以通过取字变量低3位来得到余数,将字变量右移3位,实现除以8,得到商的结果。
源程序:
.MODEL SMALL
.STACK 100H
.DATA
W DW 1234H
wQuot DW ?
bRema DB ?
.CODE
start:MOV AX, @DATA
MOV DS, AX
MOV bRema,7
MOV AX,W
AND bRema,AL
MOV CL,3
SHR AX,CL
MOV wQuot,AX
.EXIT 0
END start
在调试环境下运行程序,可以看到wQuot的内容为0246H,bRema的内容为04H。
(1)小循环移位指令。
①ROL——不带进位循环左移。
形式1:ROL 操作数,1。
功能:把操作数的内容首尾连接起来循环左移1位,CF的内容为操作数最高位的原值,CF原值丢失,如图9-10所示。
图9-10 不带进位循环左移指令
形式2:ROL 操作数,CL。
功能:把操作数的内容首尾连接起来进行循环左移,移位的次数为CL中的值。
该指令有如下两种形式:
ROL R,1/CL ; 把通用寄存器的内容循环左移1位或(CL)位
ROL M.1/CL ; 把内存数的内容循环左移1位或(CL)位
②ROR——不带进位循环右移。
形式1:ROR 操作数,1。
形式2:ROR 操作数,CL。
功能:把操作数的内容首尾连接起来循环右移1位或(CL)位,如图9-11所示。
图9-11 不带进位循环右移指令
该指令有如下两种形式:
ROR R,1/CL ; 把通用寄存器的内容循环右移1位或(CL)位
ROR M,1/CL ; 把内存数的内容循环右移1位或(CL)位
(2)大循环移位指令。
①RCL——带进位的循环左移。
形式1:RCL 操作数,1。
功能:把操作数的内容与CF位一起循环左移1位,如图9-12所示。
图9-12 带进位循环左移指令
形式2:RCL 操作数,CL。
功能:把操作数的内容与CF位一起进行循环左移,移位的次数为CL寄存的值。
该指令有如下两种形式:
RCL R,1/CL ; 把通用寄存器的内容与CF位一起循环左移1位或(CL)位
RCL M,1/CL ; 把内存数的内容与CF位一起循环左移1位或(CL)位
②RCR——带进位的循环右移。
形式1:RCR 操作数,1。
形式2:RCR 操作数,CL。
功能:把操作数的内容与CF位一起循环右移1位或(CL)位,如图9-13所示。
图9-13 带进位循环右移指令
该指令有如下两种形式:
RCR R,1/CL ; 把通用寄存器的内容与CF位一起循环右移1位或(CL)位
RCR M,1/CL ; 把内存单元的内容与CF位一起循环右移1位或(CL)位
【例9-8】字变量wNum中有一个无符号数,编写计算(wNum)×16+30,并将结果送入wNum和wNum+2中的程序。
注意:我们知道(wNum)×16的结果不会超过32位,所以应用两个字来存放结果。实际上,结果的高位字就是wNum中的高4位,结果的低位字就是把wNum左移4位,然后再加30,即为最终结果。
源程序:
.MODEL SMALL
.STACK 200H
.DATA
wNum DW 1234H,7
.CODE
start:MOV AX,@DATA
MOV DS,AX
MOV CL,4
ROL wNum,CL
MOV AX,000FH
AND AX,wNum
AND wNum,0FFFOH
ADD wNum,30
ADC AX,0
MOV wNum+2,AX
.EXIT 0
END start
在调试环境下运行程序,可以看到wNum+2的内容为235EH,wNum的内容为0001H。