x86移位SHL、SHR、SAL、ROL、RCR等指令简介
指令 | 语法 | 说明 |
---|---|---|
SHL | SHL dest, count | (逻辑)左移 |
SHR | SHL dest, count | (逻辑)右移 |
SAL | SHL dest, count | 算术左移 |
SAR | SHL dest, count | 算术右移 |
ROL | SHL dest, count | 循环左移 |
ROR | SHL dest, count | 循环右移 |
RCL | SHL dest, count | 带进位的循环左移 |
RCR | SHL dest, count | 带进位的循环右移 |
SHL指令
-
SHL指令使dest左移count位,低位用0补充,高位的值移位到CF位(覆盖原CF位)
-
SHL指令的可用操作类型如下
- SHL reg, imm8
- SHL mem, imm8
- SHL reg, CL
- SHL mem, CL
-
代码示例如下
; 代码示例 .386 .model flat, stdcall .stack 4096 ExitProcess PROTO, dwExitCode:DWORD Include Irvine32.inc ; .data .code main PROC mov al, 01101110b mov cl, 1 shl al, cl ; 左移1位, 把MSB移入CF位, CF = 0, 低位补0, 此时al的值为 1101 1100, exit main ENDP END main
; 代码示例 .386 .model flat, stdcall .stack 4096 ExitProcess PROTO, dwExitCode:DWORD Include Irvine32.inc ; .data .code main PROC mov al, 01101110b shl al, 2 ; 左移2位, 把从左往右移入第二位1移入CF位, CF = 1, 低位补0, 此时al的值为 1011 1000, exit main ENDP END main
-
关于OF位的实验数据
; 代码示例 .386 .model flat, stdcall .stack 4096 ExitProcess PROTO, dwExitCode:DWORD Include Irvine32.inc ; .data .code main PROC ;mov al, 01101110b ;shl al, 1 ; 左移1位,相当于al * 2,并把msb移入cf位。假设此时al的值为有符号位数, ; 有符号整数(正数) * 2乘以2,理论上只要不存在溢出,结果还是正数,、 ; 但此时得到的结果是 1101 1100,最高位为1是负数,所以 OF = 1 mov al, 01101110b ; 左移三位,相当于al * 2 * 2 * 2,并把从左往右的第三位1移入cf位。 shl al, 3 ; 此时得到的结果是 0111 0000, 此时的溢出位OF = 1。 原因是在第二次 ; 移位的时候al的值时10111000最高位是1代表的是负数, 而负数*2(再次左移1位)结果应该还是负数 ; 但是此时al的是01110000最高位为0,所以溢出OF=1 exit main ENDP END main
SHR指令
-
SHR指令使dest右移count位,高位用0补充,低位的值移位到CF位(覆盖原CF位)
-
SHR指令的操作类型和SHL一致
-
代码示例如下
; vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 01101111b shr al, 1 ; 右移1位,相当于al / 2(舍弃最低位),并把lsb移入cf位,CF = 1。高位补0, 此时结果是00110111 exit main ENDP END main
;vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 01101111b shr al, 2 ; 右移2位,相当于al/2/2(舍弃最低的两位位),并把(从右到左)第二位移入cf位,CF = 1。高位补0, 此时结果是 ; 00011011 exit main ENDP END main
-
关于OF位的实验数据
; vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 11101111b shr al, 1 ; 右移1位,相当于al/2(舍弃lsb),并把(从右到左)第1位移入cf位,CF = 1。高位补0, 此时结果是01110111 ; 因为最高位是1代表负数,除以2还是负数,但是结果是01110111, MSB是0,所以OF = 1 exit main ENDP END main
SAL指令(算术左移)的操作和SHL一致
SAR指令(算术右移)
-
SAR指令使dest右移count位,高位用dest的最高位补充,低位的值移位到CF位(覆盖原CF位)
-
SAR指令的操作类型和SHL一致
-
代码示例如下
; vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 11101111b sar al, 1 ; 右移1位,相当于al/2(舍弃lsb),并把(从右到左)第1位移入cf位,CF = 1。高位补al的符号位, 此时结果是 ; 11110111 mov al, 01101101b sar al, 2 ; 右移2位,相当于al/2/2(舍弃最低的两位),并把(从右到左)第2位移入cf位,CF = 0。高位补al的符号位, 此时结果是0011011 exit main ENDP END main
ROL循环左移指令
-
ROL指令使dest左移count位,把所有位都向左移,最高位复制到进位标志位和最低位(移动一位的情况)
-
指令的操作格式和SHL一致
-
代码示例
; vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 00101111b rol al, 3 ; 循环左移3位, 将(从左往右)第三位移入CF位,CF位置为1, 低5位左移三位,并且将高三位001移入低三位, ; 结果是01111 001 exit main ENDP END main
; vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 7fh rol al, 4 ; 对调7F为F7,将al循环左移4位, exit main ENDP END main
ROR指令循环右移指令
-
ROR指令使dest右移count位,把所有位都向右移,最低位复制到进位标志位和最高位(移动一位的情况)
-
指令的操作格式和SHL一致
-
代码示例如下
; vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 01110100b ror al, 3 ; 右移三位, 将低三位100移入高位,并且将(从右到左)第三位1移入CF位, ; 将CF位置为1, 结果为100 01110 exit main ENDP END main
RCL指令带进位循环左移
-
RCL指令把每一位都向左移, 进位标志位复制到LSB, MSB复制到进位标志位
-
指令的操作格式和SHL一致
-
代码示例如下
; vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 01110100b rcl al, 2 ; 将 01110100左移2位, rcl al, 2相当于rcl al, 1执行两次。 ; 第一次执行时, CF=0, al的MSB=0,把MSB移入CF,CF移入LSB=0,所以执行之后的结果是CF=0, al的值是 ; 11101000。 ; 第二次执行时, CF=0, al的MSB=1,把MSB移入CF,CF移入LSB=0,所以执行之后的结果是CF=1,AL的值是 ; 11010000 rcl al, 1 ; 执行时,CF=1,AL的MSB=1,把MSB移入CF,CF移入LSB=1,所以执行之后的结果是CF=1,AL的值是10100001 exit main ENDP END main
RCR指令带进位的循环右移
-
RCL指令把每一位都向左移, 进位标志位复制到MSB, LSB复制到进位标志位
-
指令的操作格式和SHL一致
-
代码示例如下
; vs2022 MASM环境代码示例 .386 .model flat, stdcall .stack 4096 Include Irvine32.inc ; .data .code main PROC mov al, 01110101b rcr al, 2 ; 将 01110100右移2位, rcr al, 2相当于rcr al, 1执行两次。 ; 第一次执行时, CF=0, al的LSB=1,把LSB移入CF,CF移入MSB=0 ,所以执行之后的结果是CF=1, al的值是00111010。 ; 第二次执行时, CF=1, al的LSB=0,把LSB移入CF,CF移入MSB=0,所以执行之后的结果是CF=0,AL的值是10011101 rcr al, 1 ; 执行时,CF=0,AL的LSB=1,把LSB移入CF,CF移入MSB=0,所以执行之后的结果是CF=1,AL的值是01001110 exit main ENDP END main