当前位置: 技术问答>linux和unix
请教ARM上的一个位域赋值问题
来源: 互联网 发布时间:2016-08-13
本文导语: 本帖最后由 sunling83417 于 2010-03-23 17:24:51 编辑 我写了如下一段代码: #include #include #include typedef struct { unsigned char TYPE:5; unsigned char NRI:2; unsigned char F:1; } FU_INDICATOR; typedef struct { u...
#include
#include
#include
typedef struct {
unsigned char TYPE:5;
unsigned char NRI:2;
unsigned char F:1;
} FU_INDICATOR;
typedef struct {
unsigned char TYPE:5;
unsigned char R:1;
unsigned char E:1;
unsigned char S:1;
} FU_HEADER;
int main()
{
static unsigned char buf[1000] = {0};
FU_INDICATOR *fu_ind;
FU_HEADER *fu_hdr;
printf("before fu_ind buf[12]=%xn", buf[12]);
fu_ind = (FU_INDICATOR *)&buf[12];
fu_ind->F = 0;
fu_ind->NRI = 0;
fu_ind->TYPE = 28;
printf("after fu_ind buf[12]=%xn", buf[12]);
printf("before fu_hdr buf[13]=%xn", buf[13]);
fu_hdr = (FU_HEADER *)&buf[13];
fu_hdr->S = 1;
fu_hdr->E = 0;
fu_hdr->R = 0;
fu_hdr->TYPE = 5;
printf("after fu_hdr->TYPE buf[10]=%xn", buf[10]);
printf("after fu_hdr->TYPE buf[11]=%xn", buf[11]);
printf("after fu_hdr->TYPE buf[12]=%xn", buf[12]);
printf("after fu_hdr->TYPE buf[13]=%xn", buf[13]);
printf("after fu_hdr->TYPE buf[14]=%xn", buf[14]);
return 0;
}
我在PC上gcc编译运行正常,buf[12]=1c, buf[13] = 85
可是交叉编译到ARM板上结果却出乎意料:
before fu_ind buf[12]=0
after fu_ind buf[12]=0
before fu_hdr buf[13]=0
after fu_hdr->TYPE buf[10]=0
after fu_hdr->TYPE buf[11]=85
after fu_hdr->TYPE buf[12]=0
after fu_hdr->TYPE buf[13]=1c
after fu_hdr->TYPE buf[14]=0
感觉很奇怪,不知道是怎么回事,请大家指点,谢谢!!
|
不好意思。。
LZ,在我的PC和板子上,得出的结果完全相同
我的PC上得出的结果也是这样的。
奇怪了。
LZ,在我的PC和板子上,得出的结果完全相同
before fu_ind buf[12]=0
after fu_ind buf[12]=1c
before fu_hdr buf[13]=0
after fu_hdr->TYPE buf[10]=0
after fu_hdr->TYPE buf[11]=0
after fu_hdr->TYPE buf[12]=1c
after fu_hdr->TYPE buf[13]=85
after fu_hdr->TYPE buf[14]=0
我的PC上得出的结果也是这样的。
奇怪了。
|
这是问题的关键所在。
在ARM上,FU_INDICATOR的8位保存在4个字节里面,你就不知道他哪一位对应在哪个字节了。
如果涉及到大小端的设置,就更复杂了。
当你这样转换的时候fu_ind = (FU_INDICATOR *)&buf[12];
fu_ind要用4个字节,有可能是buf[9]~buf[12],也有可能是buf[12]~buf[15],所以周围的字节可能会被覆盖。
楼主可以试试在程序的开始加一行 #pragma pack(1)
看看能不能强制把FU_INDICATOR挤进1个字节
|
很奇怪,想不明白为什么arm要把它编成4个字节。
楼主交叉编译也是用gcc吧,加个选项 -fpack-struct 试试?
总之要想办法把这个sizeof弄成1才行。
|
19楼的结果可以这么解释:
fu_ind = (FU_INDICATOR *)&buf[12]; 这个转换之后,*fu_ind占用buf[9]~buf[12],这其中的位域值都写到了buf[11]的位置。
fu_hdr = (FU_HEADER *)&buf[17]; 这个转换之后,*fu_hdr占用buf[14]~buf[17],这其中的位域值都写到了buf[15]的位置。
看来楼主的ARM是设置的big-endian。
同样的可以解释楼主最初的结果里面buf[11]=85,但是那个buf[13]=1c还是解释不通。
fu_ind = (FU_INDICATOR *)&buf[12]; 这个转换之后,*fu_ind占用buf[9]~buf[12],这其中的位域值都写到了buf[11]的位置。
fu_hdr = (FU_HEADER *)&buf[17]; 这个转换之后,*fu_hdr占用buf[14]~buf[17],这其中的位域值都写到了buf[15]的位置。
看来楼主的ARM是设置的big-endian。
同样的可以解释楼主最初的结果里面buf[11]=85,但是那个buf[13]=1c还是解释不通。