标题:GCC 数组 位域 问题 求大侠相助
取消只看楼主
r376203423
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-14
结帖率:0
已结贴  问题点数:20 回复次数:4 
GCC 数组 位域 问题 求大侠相助
GCC下我编写一下程序
typedef struct
{
     uint32_t  DIV:16;
      uint32_t  RESERVE0:8;
     uint32_t  DIVX:4;
     uint32_t  DIVX1:1;
     uint32_t  DIVX_EN:1;
     uint32_t  RESERVE1:2;
} UART_BAUD_T00;


UART_BAUD_T00 *Baud;
Baud-> DIVX1=1;.
Baud-> DIVX_EN =1;
Baud-> DIV =0x5566;

但是有个功能错误.这是反汇编程序

  baud->DIVX_EN = 1;              /* Try to Set Divider X = 1 (MODE#3)*/
0x00000ba2:   ldr r2, [r7, #4]
0x00000ba4:   ldr r1, [r2, #0]
0x00000ba6:   movs r3, #128   ; 0x80
0x00000ba8:   lsls r3, r3, #22
0x00000baa:   orrs r3, r1
0x00000bac:   str r3, [r2, #0]
108             baud->DIVX1   = 1;
0x00000bae:   ldr r2, [r7, #4]
0x00000bb0:   ldr r1, [r2, #0]
0x00000bb2:   movs r3, #128   ; 0x80
0x00000bb4:   lsls r3, r3, #21
0x00000bb6:   orrs r3, r1
0x00000bb8:   str r3, [r2, #0]
109             baud->DIV = 0x5566;
0x00000bba:   ldr r3, [r7, #16]
0x00000bbc:   uxth r2, r3
0x00000bbe:   ldr r3, [r7, #4]
0x00000bc0:   strh r2, [r3, #0]  ;错误在这里

在执行上述程序后对应的地址的值应该为 0x30005566;但实际值却是0x00005566;就是因为strh 指令的缘故。谁知道怎么设置GCC选项使得不优化为strh
谢谢各位大侠相助啊!

Xinyun
搜索更多相关主题的帖子: GCC 位域 
2010-09-14 10:01
r376203423
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-14
得分:0 
我只是省略了这些……
#define UART0_BASE           0x40050000
#define UART0               ((UART_T *) UART0_BASE)
typedef struct

    UART_BAUD_T     BAUD;
    UART_IRCR_T     IRCR;
    UART_LINCON_T   LINCON;   
    UART_FUNSEL_T   FUNSEL;   
} UART_T;

编译没问题
是在调试时功能出的错,也就是说是GCC在编译baud->DIV = 0x5566;这句时,没有按照读、修改、写的方式去做
2010-09-14 10:47
r376203423
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-14
得分:0 
#define UART0_BASE           0x40050000
#define UART0               ((UART_T *) UART0_BASE)
typedef struct
{
     uint32_t  DIV:16;
      uint32_t  RESERVE0:8;
     uint32_t  DIVX:4;
     uint32_t  DIVX1:1;
     uint32_t  DIVX_EN:1;
     uint32_t  RESERVE1:2;
} UART_BAUD_T00;
typedef struct

    UART_BAUD_T00     BAUD;
    UART_IRCR_T     IRCR;
    UART_LINCON_T   LINCON;   
    UART_FUNSEL_T   FUNSEL;   
} UART_T;


UART_BAUD_T00 *Baud;
int nain()
{
Baud-> DIVX1=1;//执行后值为ox20000000
Baud-> DIVX_EN =1;//执行后值为ox30000000
Baud-> DIV =0x5566;;//执行后值为ox00005566
}
执行后0x40050000地址的值应该为ox30005566,但实际值为但实际值却是0x00005566

这是个GCC的功能错误.这是反汇编程序

  baud->DIVX_EN = 1;              /* Try to Set Divider X = 1 (MODE#3)*/
0x00000ba2:   ldr r2, [r7, #4]
0x00000ba4:   ldr r1, [r2, #0]
0x00000ba6:   movs r3, #128   ; 0x80
0x00000ba8:   lsls r3, r3, #22
0x00000baa:   orrs r3, r1
0x00000bac:   str r3, [r2, #0]
108             baud->DIVX1   = 1;
0x00000bae:   ldr r2, [r7, #4]
0x00000bb0:   ldr r1, [r2, #0]
0x00000bb2:   movs r3, #128   ; 0x80
0x00000bb4:   lsls r3, r3, #21
0x00000bb6:   orrs r3, r1
0x00000bb8:   str r3, [r2, #0]
109             baud->DIV = 0x5566;
0x00000bba:   ldr r3, [r7, #16]
0x00000bbc:   uxth r2, r3
0x00000bbe:   ldr r3, [r7, #4]
0x00000bc0:   strh r2, [r3, #0]  ;错误在这里

在执行上述程序后对应的地址的值应该为 0x30005566;但实际值却是0x00005566;
从反汇编可以看出在执行baud->DIVX1   = 1;时,是读、修改、写的操作。
而baud->DIV = 0x5566;是直接的写操作。这是因为DIV 在定义时定义了刚好16位,于是GCC在编译时就用了strh指令
如果将DIV的定义改为其他的位数比如9、10、11、12、13、14、15都没问题
谁知道怎么设置GCC选项使得在16位时不优化为strh
感激不尽!
上面没有说清楚,望见谅
2010-09-14 11:11
r376203423
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-14
得分:0 
反过来是没有问题,
但是有些东西不能反着写比如有的寄存器要先使能再写如数值或者有逻辑顺序问题
2010-09-14 11:14
r376203423
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-14
得分:0 
我想解决的不是这个程序的问题,对这个程序的问题有很多种解决办法!!
我想弄明白的是GCC编译器的问题!
2010-09-14 11:52



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-320375-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017636 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved