(C 语言)类型提升的问题

(C 语言)类型提升的问题

 

今天在工作中发现了一个和类型相关的问题 .

代码如下:

Declaration:

                     uint32 cursor;

                     uint16 i;

                      uint16 old_str_len = 0;

                      uint16 new_str_len = 0;

Code:

                if (cursor >= i + old_str_len)       

                          cursor += new_str_len - old_str_len;    

                else if (cursor > i)       

                          cursor = i + new_str_len;

 

在使用中,我无意中把 cursor 类型从 uint16 提升到 uint32 位。编译通过后把 target flash 到手机中。当运行到这段代码时,手机总是会重启。当时百思不得其解。后来发现只要把 cursor 类型从 uint32 改回 uint16 就可以了。

经过分析,原因如下:

代码 cursor += new_str_len - old_str_len;     new_str_len - old_str_len 的结果是个负数,假定 new_str_len = 1 old_str_len = 2. 那么 new_str_len - old_str_len = 0XFFFF.

Cursor 32 位的,再和 cusor 做计算的时候,需要把 new_str_len - old_str_len 的值提升到 32 位,那么这个值就是 0X0000FFFF, 这时 Cursor + 0X0000FFFF 显然不是我们想要的结果。

 

如果把 cursor 改回 16 位,那么 Cursor + 0XFFFF 就相当于 Cursor – 1 ;此时得到的结果才是我们要的结果。

 

同样的问题在 VC 上确并不会发生,这是和芯片位数相关的一个问题。在 VC 上,芯片是 32 位的,在计算的时候

cursor += new_str_len - old_str_len;  

new_str_len - old_str_len  是按照 32 位来计算的,得到的结果先存在寄存器中也是 32 位的。这样计算结果就不会出错。

 

而在我使用的平台中,芯片是 16 位, new_str_len - old_str_len 得到的临时结果也是 16 位的,再和 cursor 计算的时候,就存在了一个位提升的问题。

 

我们来看看 VC 中的一个例子

 

        uint16 i = 2;

00458DB8 66 C7 45 EC 02 00 mov         word ptr [i],2

        uint16 j = 1;

00458DBE 66 C7 45 E0 01 00 mov          word ptr [j],1

        uint16 x ;

        uint32 y;

        y = 3;

00458DC4 C7 45 C8 03 00 00 00 mov         dword ptr [y],3

        x = j - i;

00458DCB 0F B7 45 E0      movzx       eax,word ptr [j]

00458DCF 0F B7 4D EC      movzx       ecx,word ptr [i]

00458DD3 2B C1            sub         eax,ecx

00458DD5 66 89 45 D4      mov         word ptr [x],ax //在实际的运算是 32位的,只是在把运算结果赋给目标变量的时候才裁剪为 16位的值。

        y +=  j - i;

00458DD9 0F B7 45 E0      movzx       eax,word ptr [j]

00458DDD 0F B7 4D EC      movzx       ecx,word ptr [i]

00458DE1 2B C1            sub         eax,ecx

00458DE3 03 45 C8         add         eax,dword ptr [y]

00458DE6 89 45 C8         mov         dword ptr [y],eax

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值