unsigned 和 signed 之间的赋值转化

unsigned 和 signed 之间的转化赋值非常容易被弄错,例如经典的 (-1)和 0xFFFFFFFF比较。如下:

      unsigned short i = -1;

      if (0xFFFFFFFF == i) {

    ..... ;  /* this will not be executed forever ! */

   }

鉴于经常被弄错,我现在总结一下,转化规则,有几个情形:

1.同位宽,同符号

2.同位宽,不同符号,这个情况,就是几条mov dword [xxxx],xxxx 语句,所以操作的必然就是机器数,-1 即为 0xFFFFFFFF;

  因此我们发现,不论是 :

   unsigned a = -1;

   int b = a;

    还是 

   int a = -1;

   unsigned b = a;

   结果都是机器数,这里都是 0xFFFFFFFF3. 不同位宽,但同符号:

   <1> 大转小,必然是 mov xxx,word [ .... ]这种,就是取低16位

   <2> 小转大,必然有符号扩展咯!,全补1,和全补0,比如

          short a = 1234;

          int b = a ; 

          b 就是 0x00001234 

          short a = -0x1234;

          int b = a; 

     b 就是 0xFFFF1234,就是 movsx 符号扩展了,参见杨季文《80x86...》

4. 不同位宽,不同符号;

 从前面的测试来看,可以直接从机器数推算出来,不同位宽的转化即为 dword 和 word 或者 byte 之间的相互 mov ,而不同符号之间的数据mov 即为补码的mov 操作。因此可以大胆推算出:

  <1>  unsigned short  ---> int :  直接将 unsigned short 拷贝到 int 的低16位即可,高16全为0,所以得到的值就是 unsigned short 的值。

  <2> int --> unsigned short : 将 int 以补码形式表示,低16位全部mov 给unsigned short 即可,得到的数值就是  以int以unsigned 表示的数值的低16位。

  <3> unsigned int --> long ;即为unsigned 数值

  <4> long ---> unsigned ;同<3>
  
  <5--n> ...........

 

 

我们不难得出结论,unsigned 和 signed 之间相互之间的相互转化,以汇编的眼光来看,只有一种处理:取补码,mov 操作。

posted @ 2013-10-12 01:11  moon_cat  Views(1746)  Comments(0Edit  收藏  举报