[求助]GCC中有什么办法修改位段的对齐方式?
例如,有一个位端,typedef struct BYTE_BIT
{
unsigned BIT0:1;
unsigned BIT1:1;
unsigned BIT2:1;
unsigned BIT3:1;
unsigned BIT4:1;
unsigned BIT5:1;
unsigned BIT6:1;
unsigned BIT7:1;
}BYTEBIT;
GCC中,当我用这个位段来修改变量时
unsigned char chValue = 0x00;
(*(BYTEBIT *)(&chValue)).BIT0 = 1;
最后得到的结果却是0x80。
显然,说明GCC中,位段的对齐方式不是
Bitfields are packed right to left.
而是
Bitfields are packed left to right.
的。
GCC中有没有什么方法修改这种对齐方式呢?
谢谢指教。 应该不是GCC的问题。
http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_350851.jpg
(原文件名:CAP13.jpg) Gorgon Meducer 傻孩子 (印象中最顽固的ICC派)
终于是肯用GCC了。 因为 AVR32 目前只有GCC 可以用…… 代码例子:
#include <avr/io.h>
typedef struct BYTE_BIT
{
unsigned BIT0:1;
unsigned BIT1:1;
unsigned BIT2:1;
unsigned BIT3:1;
unsigned BIT4:1;
unsigned BIT5:1;
unsigned BIT6:1;
unsigned BIT7:1;
}BYTEBIT;
int main(void)
{
unsigned char chValue = 0x00;
unsigned char i=0;
DDRA=0xFF;
for(i=0;i<10;i++)
{
(*(BYTEBIT *)(&chValue)).BIT0 = 1;
chValue=chValue+PINA;
PORTA=chValue;
}
return(TRUE);
}
汇编成机器指令(部分代码):
17: unsigned char chValue = 0x00;
+00000053: 8219 STD Y+1,R1 Store indirect with displacement
20: DDRA=0xFF;
+00000054: EF8F SER R24 Set Register
+00000055: BB8A OUT 0x1A,R24 Out to I/O location
+00000056: E020 LDI R18,0x00 Load immediate
25: (*(BYTEBIT *)(&chValue)).BIT0 = 1;
+00000057: 8199 LDD R25,Y+1 Load indirect with displacement
+00000058: 6091 ORI R25,0x01 Logical OR with immediate
+00000059: 8399 STD Y+1,R25 Store indirect with displacement
27: chValue=chValue+PINA;
+0000005A: B389 IN R24,0x19 In from I/O location
+0000005B: 0F89 ADD R24,R25 Add without carry
+0000005C: 8389 STD Y+1,R24 Store indirect with displacement
29: PORTA=chValue;
+0000005D: BB8B OUT 0x1B,R24 Out to I/O location
22: for(i=0;i<10;i++)
+0000005E: 5F2F SUBI R18,0xFF Subtract immediate
+0000005F: 302A CPI R18,0x0A Compare with immediate
+00000060: F7B1 BRNE PC-0x09 Branch if not equal
32: }
+00000058使用了逻辑或,操作很正常啊! 5楼我回的帖子怎么没了。
强烈欢迎傻孩子大人进入GCC阵营。
GCC的最大优点就是标准,通用。
GCC使用者遍布全世界各个角落。
我测试也没问题,不过建议字节位域用:
typedef struct
{
unsigned char BIT0:1;
unsigned char BIT1:1;
unsigned char BIT2:1;
unsigned char BIT3:1;
unsigned char BIT4:1;
unsigned char BIT5:1;
unsigned char BIT6:1;
unsigned char BIT7:1;
}BYTEBIT; 强烈建议大家在AVR32 Studio中测试这个问题…… 楼上试试 sizeof(BYTE_BIT)等于多少?
在IAR里:
typedef struct
{
unsignedBIT0:1;
unsignedBIT1:1;
unsignedBIT2:1;
unsignedBIT3:1;
unsignedBIT4:1;
unsignedBIT5:1;
unsignedBIT6:1;
unsignedBIT7:1;
}BYTEBIT;
sizeof(BYTEBIT)=sizeof(int) to 【7楼】 ATmega32 上官金虹
那是字节对齐导致的,你把代码修改为以下方式再看看?
#pragma pack(1)
typedef struct
{
unsignedBIT0:1;
unsignedBIT1:1;
unsignedBIT2:1;
unsignedBIT3:1;
unsignedBIT4:1;
unsignedBIT5:1;
unsignedBIT6:1;
unsignedBIT7:1;
}BYTEBIT;
#pragma pack() 还是一样。
struct
{
unsignedBIT0:1;
}
可能是占用存储空间是int,也可能是char,与编译器有关。
个人认为显式指定unsigned char BIT0;1更好,这样确保只占用一个字节。
(以上可能有误,关于位域,标准C是如何规定的,还没仔细研究过)
如果BYTEBIT占用空间是int,那么
(*(BYTEBIT *)(&chValue)).BIT0 = 1;
有可能存在问题。
就如
unsigned charchValue;
*(unsigned int *)&chValue;
是有可能存在问题的。
http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_351310.JPG
(原文件名:Image0173.JPG)
哪位高人翻译一下? 嵌入式编程中不推荐使用bit fileds,因为标准里没严格规定,会给移植带来问题。 如果对齐
在 WINGCC 里
struct
{
unsignedBIT0:1;
.
.
.
} BYTEBIT;
sizeof(BYTEBIT)是2字节;
在AVR32GCC里
sizeof(BYTEBIT)是4字节;
#pragma pack(1)
typedef struct BYTE_BIT
{
unsignedBIT0:1;
.
.
.
}BYTEBIT;
#pragma pack()
都为1字节;
avr32 GCC 汇编出来的机器指令为:
(*(BYTEBIT *)(&chValue)).BIT0 = 1;
0x80000130 <main+28>: sub r10,r7,2
0x80000134 <main+32>: ld.ub r8,r10
0x80000136 <main+34>: mov r9,1
0x80000138 <main+36>: bfins r8,r9,0x7,0x1
0x8000013c <main+40>: st.b r10,r8
bfins我就看不懂了。
如图:
http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_351350.JPG
(原文件名:1.JPG) AVR32STUDDIO=Eclipse+GCC
流口水啊。
avr_studio太破烂了,ATMEL什么时候也把AVR_STUDIO换成Eclipse就好了。 傻孩子,问题解决了吗?
bfins Rd, Rs, o5, w5 Insert the lower w5 bits of Rs in Rd at bit-offset
bfins r8, r9,0x7,0x1 将r9的低1位插入到r8的第7位,是这样理解的吗? 问题解决了。和GCC版本有关系,对于较高版本,可以通过
#pragma reverse_bitfield或者-mreverse_bitfield来实现
对于低版本,就只能用宏的方法,重新编写一个逆序的位段
来解决了。 整理帖子,自己顶一下…… 以下蓝色文字由版主:Gorgon Meducer 于:2008-09-02,12:18:21 加入。<font color=black>请发贴人注意:本贴放在这分区不合适,即将移走
原来分区:AVR (原ourAVR.com) 技术论坛
即将移去的分区:傻孩子(Gorgon Meducer)专栏
移动执行时间:自本贴发表0小时后
任何的疑问或咨询,请可随时联系站长。谢谢你的支持!</font> 胡乱写的,不要照抄,按这个意思写就行了.
你的struct里全是位,编译器当然没必要帮你按字节对齐.借助union用一个unsigned char来限制它就行了.
typedef struct BYTE_BIT
{
union{
unsigned char byte_data;
struct bit_data_s{
unsigned BIT0:1;
unsigned BIT1:1;
unsigned BIT2:1;
unsigned BIT3:1;
unsigned BIT4:1;
unsigned BIT5:1;
unsigned BIT6:1;
unsigned BIT7:1;
}bit_data;
}BYTEBIT;
...
BYTEBIT test;
test.bit_data.BIT0 = 1; 学习
页:
[1]