向各位大神请教个问题,我是菜鸟轻拍砖

[复制链接]
2229|4
 楼主| chenhao8060 发表于 2012-7-18 16:27 | 显示全部楼层 |阅读模式
#include <REG52.H>

typedef unsigned char u8;
typedef unsigned int  u16;

main()
{
        u8 a[2]={0x12, 0x34};
        u16 b = 0;
       
        b = (a[0]<<8) | a[1];
       
        while (1);
}


当我运行这段程序时,b变量的结果是0x0000而不是0x1234,于是我去查看KEIL下的汇编,发现了这段,原因是第11行的程序未进行编译

C:0x0109    1200D3   LCALL    C?COPY(C:00D3)
     9:         u16 b = 0;
     10:
   11:    b = (a[0]<<8) | a[1];
     12:
     13:       while (1);
C:0x010C    80FE     SJMP     C:010C
   133:                 MOV     R0,#IDATALEN - 1
C:0x010E    787F     MOV      R0,#0x7F
   134:                 CLR     A
C:0x0110    E4       CLR      A
   135: IDATALOOP:      MOV     @R0,A
C:0x0111    F6       MOV      @R0,A
   136:                 DJNZ    R0,IDATALOOP
C:0x0112    D8FD     DJNZ     R0,IDATALOOP(C:0111)
   185:                 MOV     SP,#?STACK-1

而后我以为是编译器将b进行了优化,于是将u16 b = 0;改成volatile u16 b = 0;结果第
11行还是没编译,但是我改成u16 b;不对b进行初始化,第11行却被编译了而b的结果也是0x1234了,这是为什么?对于这点我一个大二菜鸟实在想不通了,特来向二姨上的大神求教
ayb_ice 发表于 2012-7-18 16:39 | 显示全部楼层
a是8位变量,<<8位是什么结果,当然是0了,

程序其实没有意义,被KEIL优化了

需要将变量定义为全局变量,或加volatile修饰
ZRL700424 发表于 2012-7-18 17:04 | 显示全部楼层
b = (u16)(a[0]<<8) | a[1];
 楼主| chenhao8060 发表于 2012-7-18 17:11 | 显示全部楼层
3# ZRL700424
用这种强制转换的方法还是不行
 楼主| chenhao8060 发表于 2012-7-18 17:14 | 显示全部楼层
2# ayb_ice
#include <REG52.H>

typedef unsigned char u8;
typedef unsigned int  u16;

main()
{
u8 a[2]={0x12, 0x34};
u16 b;

b = (a[0]<<8) | a[1];

while (1);
}

最后我改成这样就行了,数组还是u8的,这说明应该没溢出吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

16

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部