局部变量使用指针方式赋值可能会导致异常

从协议解析数据是为了提高效率,我常常使用指针直接操作内存地址来替代移位操作,如下 :

    *((u8*)&a+1) = *(pbuf + 0);
    *((u8*)&a+0) = *(pbuf + 1);

一般使用移位操作如下:
    a = *(pbuf + 0);
    a <<= 8;
    a |= *(pbuf + 1);

这样的代码我都会做单元测试,测试中没有发现问题,但是在实际运行时发现有异常。本来 a 赋值后应该为0x0258,是实际的结果为0x58。通过软件仿真发现,在使用 Medium 优化等级时,a 被分配在R8寄存器中(a 为局部变量)。我推测导致异常的原因是不能对分配在寄存器中的变量进行地址操作。IAR软件仿真中观察 &a 显示的是 :
Error(col 1):Can’t take address. 
但是这里使用指针进行赋值并没有错,也不是在所有局部变量时都不能使用,同样在这个函数中,另外1个与 a 相似的变量就被分配在内存中,可能是因为该变量进行了其他操作。
我对编译器的具体处理机制没有深入研究。这里只是得到一个结论:
对于函数内的局部变量,赋值是最好不要采用指针方式,或者强制指定局部变量到内存。

注:使用的平台是STM32F103VET6, IDE  IAR for ARM 6.10

发表评论

邮箱地址不会被公开。 必填项已用*标注