|
发表于 2009-12-30 20:29:38
|显示全部楼层
移位操作指令
移位操作指令是一组经常使用的指令,它包括 算术移位 、 逻辑移位 、 双精度移位 、 循环移位 和 带进位的循环移位 等五大类。
移位指令都有指定移动二进制位数的操作数,该操作数可以是立即数或CL的值。在8086中,该立即数只能为 1 ,但在其后的 CPU 中,该立即数可以是 1··31 之内的数。
1 、算术移位指令
算术移位指令有:算术左移 SAL (Shift Algebraic Left)和算术右移 SAR (Shift Algebraic Right)。它们的指令格式如下:
SAL/SAR 寄存器/内存地址, CL/立即数
受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)。
算术移位指令的功能描述如下,具体功能下图(a)、(b)所示。
算术左移 SAL 把目的操作数的低位向高位移,空出的低位补0;
算术右移 SAR 把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补。
(a)、SAL (b)、SAR
例已知(AH)=12H,(BL)=0A9H,试给出分别用算术左移和右移指令移动1位后,寄存器AH和BL的内容。
解:用算术左移和右移指令移动1位后,寄存器AH和BL的结果如下表所示。
操作数的初值
执行的指令
执行后操作数的内容
(AH)=12H=10010B
SAL AH, 1
(AH)=24H=100100B
(BL)=0A9H=10101001B
SAL BL, 1
(BL)=52H=1010010B
(AH)=12H=10010B
SAR AH, 1
(AH)=09H=1001B
(BL)=0A9H=10101001B
SAR BL, 1
(BL)=0D4H=11010100B
汇编指令 SAL 指令等于易语言里的 左移() 和 模块里的 SAL_() SHL_().
汇编指令 SAR 指令在易语言里无对应函数 等于模块里的 SAR_() 函数.
但要注意模块里的 SAR_() 是以32位整数型来运算的,只等于汇编里的 SAR eax,1 这类的32位寄存器的运行结果.
若想以16位或8位来运算,需要先把符号位扩展到32位后再处理.
逻辑移位指令
此组指令有:逻辑左移 SHL (Shift Logical Left)和逻辑右移 SHR (Shift Logical Right)。它们的指令格式如下:
SHL/SHR 寄存器/内存地址, CL/立即数
受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)。
逻辑左移/右移指令只有它们的移位方向不同,移位后空出的位都补 0 。它们的具体功能下图(a)、(b)所示。
(a)、SHL (b)、SHR
例已知(AH)=12H,(BL)=0A9H,试给出分别用逻辑左移和右移指令移动1位后,寄存器AH和BL的内容。
解:用算术左移和右移指令移动1位后,寄存器AH和BL的结果如下表所示。
操作数的初值
执行的指令
执行后操作数的内容
(AH)=12H=10010B
SHL AH, 1
(AH)=24H=100100B
(BL)=0A9H=10101001B
SHL BL, 1
(BL)=52H=1010010B
(AH)=12H=10010B
SHR AH, 1
(AH)=09H=1001B
(BL)=0A9H=10101001B
SHR BL, 1
(BL)=54H=1010100B
汇编 SHL 指令等于易语言里的 左移() 和模块里的 SHL_() SAL_().
汇编 SHR 指令等于易语言里的 右移() 和模块里的 SHR_().
双精度移位指令
此组指令有:双精度左移SHLD(Shift Left Double)和双精度右移SHRD(Shift Right Double)。它们都是具有三个操作数的指令,其指令的格式如下:
SHLD/SHRD 寄存器/内存地址, 寄存器, CL/立即数 ;80386+
其中:第一操作数是一个16位/32位的寄存器或存储单元;第二操作数(与前者具有相同位数)一定是寄存器;第三操作数是移动的位数,它可由CL或一个立即数来确定。
在执行SHLD指令时,第一操作数向左移n位,其“空出”的低位由第二操作数的高n位来填补,但第二操作数自己不移动、不改变。
在执行SHRD指令时,第一操作数向右移n位,其“空出”的高位由第二操作数的低n位来填补,但第二操作数自己也不移动、不改变。
SHLD和SHRD指令的移位功能示意图如下图所示。
受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)
(a)、SHLD (b)、SHRD
双精度移位指令操作示意图
下面是几个双精度移位的例子及其执行结果。
双精度移位指令
指令操作数的初值
指令执行后的结果
SHLD AX, BX, 1
(AX)=1234H,(BX)=8765H
(AX)=2469H
SHLD AX, BX, 3
(AX)=1234H,(BX)=8765H
(AX)=91A4H
SHRD AX, BX, 2
(AX)=1234H,(BX)=8765H
(AX)=448DH
SHRD AX, BX, 4
(AX)=1234H,(BX)=8765H
(AX)=5123H
汇编 SHLD 与 SHRD 在易语言里暂无对应的函数,2.5模块里也没加上这两个函数.
循环移位指令
循环移位指令有:循环左移 ROL (Rotate Left)和循环右移 ROR (Rotate Right)。
指令的格式:ROL/ROR 寄存器/内存地址, CL/立即数
受影响的标志位:CF和OF
循环左移/右移指令只是移位方向不同,它们移出的位不仅要进入CF,而且还要填补空出的位。具体功能如下图(a)、(b)所示。
(a)、ROL
(b)、ROR
下面是几个循环移位的例子及其执行结果。
循环移位指令
指令操作数的初值
指令执行后的结果
ROL AX, 1
(AX)=6789H=110011110001001B
(AX)=0CF12H=1100111100010010B
ROL AX, 3
(AX)=6789H=110011110001001B
(AX)=3C4BH=11110001001011B
ROR AX, 2
(AX)=6789H=110011110001001B
(AX)=59E2H=101100111100010B
ROR AX, 4
(AX)=6789H=110011110001001B
(AX)=9678H=1001011001111000B
汇编 ROL 在易语言里无对应函数,模块里提供了 ROL_().
汇编 ROR 在易语言里无对应函数,模块里提供了 ROR_().
带进位的循环移位指令
带进位的循环移位指令有:带进位的循环左移 RCL (Rotate Left Through Carry)和带进位的循环右移 RCR (Rotate Right)。
指令的格式:RCL/RCR 寄存器/内存地址, CL/立即数
受影响的标志位:CF和OF
带进位的循环左移/右移指令只有移位的方向不同,它们都用原CF的值填补空出的位,移出的位再进入CF。具体功能如下图(a)、(b)所示。
(a)、RCL (b)、RCR
下面是几个带进位循环移位的例子及其执行结果。
双精度移动指令
指令操作数的初值
指令执行后的结果
RCL AX, 1
CF=0,(AX)=0ABCDH=1010101111001101B
(AX)=579AH=101011110011010B
RCL AX, 1
CF=1,(AX)=0ABCDH=1010101111001101B
(AX)=579BH=101011110011011B
RCR AX, 2
CF=0,(AX)=0ABCDH=1010101111001101B
(AX)=AAF3H=1010101011110011B
RCR AX, 2
CF=1,(AX)=0ABCDH=1010101111001101B
(AX)=EAF3H=1110101011110011B
汇编 RCL 在易语言里无对应函数,模块里提供了 RCL_().
汇编 RCR 在易语言里无对应函数,模块里提供了 RCR_().
本文重新介绍了这些将在封包算法里将常用到的汇编指令..大家要尽量记住这些指令的运算方式.
最多被用到的指令主要有 XOR-位异或 ,ROL-左循环移位 ,ROR-右循环移位 ,AND-位与 ,OR-位或 ,SHL-左移 ,SHR-右移 ,NOT-位取反.其它加减乘除,算术移位等用到的机率很少..
有些算法指令在易语言里也有对应的函数,或者模块里也有提供了这些功能,不过需要注意的是目前2.5模块里提供的这几个功能是按32位运算的.大家在使用时要注意.有关相应的8位与16位运算的函数下版时会增加上去. |
|