zoukankan      html  css  js  c++  java
  • 关于 unsigned 型变量在计算过程中发生的事情

    运行环境:CentOS release 5.8 (Final)

    #include<stdio.h>
    #include<iostream>
    using namespace std;
    int main()
    {
            unsigned short u = 10; 
            unsigned int n = 0;
                
            //Style left:
            // u = u - 11;
            // n = u;
    
            //Style right:
            n = u - 11 ;
    
            cout<<"n=="<<n<<endl;
            return 0;
    }

    运行结果:

    Style left :

    $ ./a.out

    n==65535

    Style right :

    $ ./a.out

    n==4294967295

    下面是分别对这两种方式的汇编:

    unsigned 变量先减(sub),后赋值给n                                                                      unsigned 变量先扩展,后进行减运算,最后赋值给非 unsigned 变量

    分析

    注:movzx,汇编语言数据传送指令MOV的变体。无符号扩展,并传送。

    movzx 主要作用是,把一个变量进行编译器扩展,放到寄存器eax

    1个二进制位称为1个bit(比特位)                   1 bit

    8个bit称为1个Byte(字节)                              1 Byte == 8 bit

    2个Byte就是1个 Word(机器字)                    1 Word == 2 Byte

    2个Word就是1个 DWord(机器双字)           1 DWord == 2 Word

    WORD 表示2个字节,即 sizeof(unsigned short)。unsigned short 表示的范围:[0, 65536)

    DWORD 表示4个字节,sizeof(unsigned int)。unsigned int 表示的范围:[0, 4294967296)

    (一)左侧的方式:先运算后赋值分两步进

    //Style left: 
    u = u - 11; 
    n = u;

    对应的汇编为:

    sub      WORD PTR [ ebp-0xc ], 0xb
    movzx    DOWRD PTR [ ebp-0x8 ], eax

    【解释】:

    因为第一步是对 unsigned 变量 u 进行自减,所以此时不需要进行编译器扩展

    10 – 11 得到值为 -1,即 0xffff (unsigned short 能表示的最大范围就是4个f)。

    第二步涉及到了赋值操作,

    编译器要会赋值之前,先对赋值操作符=右侧的表达式进行编译器扩展:

    将 0xffff 扩展为 0x0000ffff,然后接受赋值的变量是一个 DWORD,

    根据 DWORD 的长度对扩展的值进行截取,DWORD 长度刚好能接受 0x0000ffff,

    转换成 10 进制即为 65535

    【结论】:

    编译器先进行计算后,按 WORD 进行扩展,所以得到的是 WORD 范围的最大值(65535)

    (二)右侧的方式:运算和赋值合为一步进行

    //Style right:
    n = u - 11 ;

    对应的汇编为:

    movzx eax, WORD PTR [ ebp-0xc ]
    sub   eax, 0xb

    由于赋值符右侧的表示范围和传进去的变量不是一种类型,编译器先对赋值符=右侧的值进行扩展,

    10 – 11 == -1,编译器扩展为 0x0000ffffffff(只能扩展到DWORD?)

    右侧的 DWORD 接收后,转换为 10 进制即为 4294967295

    【结论】:

    编译器先进行计算后,按 DWORD 进行扩展,所以得到的是 DWORD 范围的最大值(4294967295)

  • 相关阅读:
    jquery proxy && delegate 的比较
    最近开发问题记录
    调研雅黑字体在各浏览器的显示
    我对浮动的认识(一)
    我对浮动的理解和认识(二)
    跨浏览器事件的其他问题(小记)
    web数据交互方式
    闪光字的处理
    IE hasLayout的问题总结
    文字内容溢出用点点点(...)省略号
  • 原文地址:https://www.cnblogs.com/sunrisezhang/p/4083394.html
Copyright © 2011-2022 走看看