-左移指令-
SHL指令:逻辑左移,将逻辑数据向左移动的命令。
- 将目的操作数的每位左移
- 最低位用 0 填充
- 最高位移入进位标志位(CF)
- 而进位标志位中原来的数值被丢弃。
一般格式:
SHL 目标操作数,1 ; 向左移1位
SHL 目标操作数,CL ; 向左移动N位
这里要注意:第二行里面的CL为什么是移动N位呢?
如果移动位数大于1,必须将移动位数放在cl中。
所以只要移动位数大于1,方法是:
MOV AL,01010001B
MOV CL,3 ;移动位数大于1必须先存放在CL里
SHL AL,CL ;左移CL位(3个位)
SHL指令,如下面的表格所示(移动之前)
CF | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
将每个位左移1格,并且最高位移入CF(进位标志位),最低位用0填充 那么结果是:
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ZR |
这里ZR代表0
每次左移动一位,等于数值乘2
SAL指令:算术左移,将算术数据向左移动的命令。
SAL 都将目的操作数中的每一位移动到下一个最高位上。最低位用 0 填充;最高位移入进位标志位CF,该标志位原来的值被丢弃。
- 最高位符号位移入CF
- 其余位顺序左移
- 次高位被舍弃。
一般格式:
SAL 目标操作数,1 ; 向左移1位
SAL 目标操作数,CL ; 向左移动N位
这里如果移动位数大于1,必须将移动位数存放到CL里
这样一看,似乎SHL和SAL指令是完全一样的
区别在于,SHL是逻辑左移,SAL是算术左移
SAL算术移位需要考虑最高位的符号位,要保证移到后的最高位,也就是符号位不变。用于带符号数的运算。
最高位符号位移入CF,但本身保持原值,其余位顺序左移,次高位被舍弃。
SHL逻辑移不用考虑直接移就ok。所有位顺序左移,最高位移入CF,最低位补0。用于无符号数的计算
-右移指令-
SHR指令:将逻辑数据向右移动的命令
- 使目的操作数逻辑右移一位
- 最高位用 0 填充
- 最低位复制到进位标志位
- 进位标志位中原来的数值被丢弃
和SHL指令刚好相反,一个向左一个向右
SHR里面的R就是right(右),SHL里面的L就是light(左)这样记
一般格式:
SHR 目标操作数,1 ; 向右移1位
SHR 目标操作数,CL ; 向右移动N位
这里如果移动位数大于1,必须将移动位数存放到CL里
SHR指令,如下面的表格所示(移动之前)
CF | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
移动之后:
0 | ZR | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
SAR指令:将算术数据向右移动的命令。
向右逐位移动,每次逐位移动后,最高位用符号位来补充,最低位移入CF。
一般格式:
SAR 目标操作数,1 ; 向右移1位
SAR 目标操作数,CL ; 向右移动N位
这里如果移动位数大于1,必须将移动位数存放到CL里
SAR指令,如下面的表格所示(移动之前)
CF | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
移动之后:
0 | 15 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
SHR指令和SAR指令的区别:
两者的区别在于SAR右移时保留操作数的符号,即用符号位来补足
而SHR右移时总是用0来补足
例如10000000算数右移(SAR)一位是11000000
而逻辑右移(SHR)一位是01000000
SAR功能是将操作数右移,符号位保持不变,可用于有符号数除法;
SHR功能是将操作数右移,原最低位移入进位标志CF,原最高位补0;可用于无符号数除法.