MDK赋值出错的BUG

//=====================================================================
//TITLE:
// MDK赋值出错的BUG
//AUTHOR:
// norains
//DATE:
// Friday 15-April-2011
//Environment:
// MDK 4.02
//=====================================================================

在我们看这BUG之前,先看一个很简单的算式:0x81 & 0x7F = ? 估计很多人都会知道,结果等于1。如果对此还有点懵懂的朋友,可以用windows自带的计算器试试,结果也是1。但这算式,如果是在MDK,那么可能就不同了,结果很可能不是1,如图:


从图中可以看到,ep->bEndpointAddress数值为0x81,和0x7F进行与操作后,结果保存到endpointNum,却发现结果变成了0x68!这究竟是怎么一回事呢?

在详细说明这问题之前,我们将"endpointNum = ep->bEndpointAddress & 0x7F"这行代码分解为两个步骤,如下所示:
endpointNum = ep->bEndpointAddress; endpointNum &= 0x7F;

接着我们重新编译,在编译器中查看相应的结果,如图所示:


我们可以很明显看到,"endpointNum = ep->bEndpointAddress"会被汇编成如下两条语句:
MOVS r0,r0 LDRB r6,{r0,#0x02}

r6是endpointNum变量的地址,这个没问题。问题就出在,r0的数值。在执行MOVS操作之前,r0为0x00000001,然后在这个地址上偏移2个byte地址所对应的数值赋值给r6!这很明显是不对的,因为r0的数值应该等于ep的地址,也就是0x20009D60才对!也难怪乎会出错了。

这个应该是MDK编译器的BUG。那么,我们有没有办法避开这个BUG呢?方法还是有的,只要在赋值语句之前随便初始化一个变量即可,比如增加这么一个语句:"int iDumy = 0",执行的结果如下图所示:


此时我们发现,赋值语句的汇编代码已经改变,变为:
LDR r0,{sp,#0x04} LDRB r6,{r0,#0x02}

改变的最直接结果就是,r0寄存器的数值刚好是ep指针的地址,不再是那个可恶的0x00000001,于是endpointNum就变成了正确的0x81,也就意味着我们成功绕开了MDK这个莫名其妙的bug!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值