• 算术移位和逻辑移位实现分析


    参考: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
    }
    请问:上面的变量i是采用逻辑移位还是算术移位呢?
    逻辑移位,简单理解就是物理上按位进行的左右移动,两头用0进行补充,不关心数值的符号问题。
    算术移位,同样也是物理上按位进行的左右移动,两头用0进行补充,但必须确保符号位不改变。

    算术移位指令

    算术移位指令有:算术左移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

    结论:说明只要是有符号数,不管值是正还是负,右移时采用的都是算术右移。

    疑问:按照移位补0的原则,为何左移都是逻辑移位呢?
    答疑:先看看“-8”和“8”在计算机内存中的值分别是:
    0xfffffff8
    0x8
    由于计算机均按补码保存数值,所以不管符号正负,左移对于符号位并不产生影响,而右移则就不同了,无符号数怎么右移都不影响符号位,但是有符号数逻辑右移时高位补0将改变符号位,所以只能采用算术右移。
     
    总结:只有有符号数右移才采用算术右移,否则其它情况都采用逻辑移位操作(逻辑左移或逻辑右移)。原来只要明白计算机是以补码方式保存数值的,就一切都清楚了。
  • 相关阅读:
    How can TCP ACKs be used to measure latency to a server?
    信息安全技术实用教程(第4版)
    java.util基础复习
    Java.IO基础复习
    vue3 打包插件后出现的带有slot的插件报 reading isCE问题
    vue3的一些基本常识(slot,ref)
    webpack常用配置说明(以webpack5为主)
    谷歌上不能在页面加载的时候播放音频解决办法
    vite vue插件打包配置
    Vue3中typescript编译遇到的问题(props的validator)
  • 原文地址:https://www.cnblogs.com/hpcpp/p/6291710.html
Copyright © 2020-2023  润新知