首页 > 代码库 > 算术移位和逻辑移位实现分析
算术移位和逻辑移位实现分析
参考:http://blog.sina.com.cn/s/blog_944790400101bsi8.html
http://www.feiesoft.com/asm/05-2-05.html
unsigned int i = 8; int main() { i = i<<3;//输出结果i = 64 }
算术移位指令
算术移位指令有:算术左移SAL(ShiftAlgebraic Left)和算术右移SAR(ShiftAlgebraic Right)。它们的指令格式如下:SAL/SAR Reg/Mem, CL/Imm,受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)。算术移位指令的功能描述如下:
(1)算术左移SAL把目的操作数的低位向高位移,空出的低位补0;
(2)算术右移SAR把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补。
逻辑移位指令
此组指令有:逻辑左移SHL(ShiftLogical Left)和逻辑右移SHR(ShiftLogical Right)。它们的指令格式如下:SHL/SHR Reg/Mem, CL/Imm,受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)。逻辑左移/右移指令只有它们的移位方向不同,移位后空出的位都补0。
(1)逻辑左移SHL
(2)逻辑右移SHR
但我们好奇的是“i<<3”和“i>>3”到底采用的是算术还是逻辑移位呢?其实单从C语言本身来看可能没有太多突破,
因为C最终会被编译器编译成目标平台的汇编代码,所以必须要结合编译器和汇编程序来分析以上代码。
在vc6.0中,按F9可以设置一个断点,然后调试运行,点击Disassembly
也可以,直接调试运行时,在断点处右键,点击Go to Disassembly,显示汇编代码。
即可显示汇编代码
以下几种情况:
(1)当i是无符号整形时,向左移动3位,采用的是逻辑左移。
unsigned int i = 8;
i = i<<3;//输出结果i = 64
(2)当i是有符号整形时,向左移动3位,采用的也是是逻辑左移。
int i = 8; i = i<<3;//输出结果i = 64
结论:不管是否有无符号类型,也不管值的正负,均采用的是逻辑左移。
(3)当i是无符号整形时,向右移动3位,采用的也是是逻辑右移。
unsigned int i = 8; int main() { i = i>>3;//输出结果i = 1 }
(4)当i是有符号整形时,向右移动3位,采用的是算术右移。
int i = 8; int main() { i = i>>3;//输出结果i = 1 return 0; }
(5)负数时,当把unsigned int i = -8时(在32位window系统下),右移动三位:
(6)当int i=-8时,右移动三位,结果多少呢?结果是-1
结论:说明只要是有符号数,不管值是正还是负,右移时采用的都是算术右移。
算术移位和逻辑移位实现分析