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"会被汇编成如下两条语句:
r6是endpointNum变量的地址,这个没问题。问题就出在,r0的数值。在执行MOVS操作之前,r0为0x00000001,然后在这个地址上偏移2个byte地址所对应的数值赋值给r6!这很明显是不对的,因为r0的数值应该等于ep的地址,也就是0x20009D60才对!也难怪乎会出错了。
这个应该是MDK编译器的BUG。那么,我们有没有办法避开这个BUG呢?方法还是有的,只要在赋值语句之前随便初始化一个变量即可,比如增加这么一个语句:"int iDumy = 0",执行的结果如下图所示:
此时我们发现,赋值语句的汇编代码已经改变,变为:
改变的最直接结果就是,r0寄存器的数值刚好是ep指针的地址,不再是那个可恶的0x00000001,于是endpointNum就变成了正确的0x81,也就意味着我们成功绕开了MDK这个莫名其妙的bug!