标题:GCC 数组 位域 问题 求大侠相助
只看楼主
r376203423
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-14
结帖率:0
已结贴  问题点数:20 回复次数:9 
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
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
得分:6 
你连申请了指针都不给他malloc个空间,就对成员进行赋值。

不报错,他妈才有鬼呢。
2010-09-14 10:22
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
hahayezhe
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖南张家界
等 级:贵宾
威 望:24
帖 子:1386
专家分:6999
注 册:2010-3-8
得分:6 
如果没有给指针初始化,赋值时就会报错

你取值时是怎么操作的

还是你在赋值完后 没有取的情况下 结构体的内存数据就被截断清零了?

uint32_t  DIVX:4;
     uint32_t  DIVX1:1;
这里面的数据一直都存在么!
2010-09-14 10:52
hahayezhe
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖南张家界
等 级:贵宾
威 望:24
帖 子:1386
专家分:6999
注 册:2010-3-8
得分:0 
Baud-> DIV =0x5566;
Baud-> DIVX1=1;.
Baud-> DIVX_EN =1;

你反过来写试下

2010-09-14 10:54
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
hahayezhe
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖南张家界
等 级:贵宾
威 望:24
帖 子:1386
专家分:6999
注 册:2010-3-8
得分:0 
你非得用uint32_t么

反正你只是为了那个结构体的内存数据

为什么不换其他写法

不就是调用32bits的内存空间数据

用其他实现方式不可以吗?

strh是字节对齐的优化么? 或者内嵌汇编,我只知道windows下机器码16位指令 提示是 66
2010-09-14 11:21
r376203423
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-14
得分:0 
我想解决的不是这个程序的问题,对这个程序的问题有很多种解决办法!!
我想弄明白的是GCC编译器的问题!
2010-09-14 11:52
Kabie
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:69
专家分:185
注 册:2009-8-21
得分:6 
...其实还是你解释得不够明白。。。看了半天才看懂。。。

但是我试了试。。。结果就是0x30005566……mingw4.4……
2010-09-15 03:51



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




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

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