程序中定义了如下数据结构:
/* Word accessible 32bit struct type define */
typedef struct
{
Uint16_t low16;
Uint16_t high16;
} Uword32_W2B0_t;
typedef struct
{
Uint8_t byte0;
Uint8_t byte1;
Uint8_t byte2;
Uint8_t byte3;
} Uword32_W0B4_t;
typedef struct
{
Uint8_t LSbyte : 8 ;
Uint16_t mid16 : 16 ;
Uint8_t MSbyte : 8 ;
} Uword32_W1B2_t;
/* Word accessible 32bit union type define */
typedef union
{
Uint32_t all;
Uword32_W2B0_t word;
Uword32_W0B4_t bytes;
Uword32_W1B2_t combo;
} WrdAccUint32_t;
WrdAccUint32_t abc;
Uint16_t temp16;
void main()
{
abc.all = 0x12345678;
temp16 = abc.mid16;
}
最后由于16位空间对齐的缘故 , temp16 得到 0x1234;
如果更改数据结构才能获得 0x3456 呢?
谢谢!
Peter_Zheng:
加一句#pragma pack(1)
David Liu1:
回复 Peter_Zheng:
Hi Peter, 能否给出参考的文献?
Peter_Zheng:
回复 David Liu1:
这是一个字节对齐问题,没有什么参考文献。
David Liu1:
回复 Peter_Zheng:
Hi, Peter
430 不支持 #pragma pack(1) 和 #pragma pack() 预编译指令,你有在430上面实现过吗? 是使用CCSv4吗?
warning: unrecognized #pragma
Peter_Zheng:
回复 David Liu1:
这是一个C99常见的warning,不影响
不是430的问题
David Liu1:
回复 Peter_Zheng:
这个不是C99的warning,是编译器无法识别 #pragma 预编译指令, 也就是说 #pragma pack(1) 是不起作用的。
Peter_Zheng:
回复 David Liu1:
你在IAR上试一下
Triton Zhang:
1. 先纠正你一个代码错误,
temp16 = abc.mid16;
这句话是错的,应该是
temp16 = abc.combo.mid16;
2. 在定义结构体的前面加上
#pragma pack (1) // 表明该结构体为字节对齐
typedef struct
{
}
#pragma pack () // 注意改语句会恢复默认对齐方式.
David Liu1:
回复 Triton Zhang:
@Triton 很抱歉,疏忽了, 软件中 进行了 宏定义
#define low16 word.low16
#define high16 word.high16
#define LSbyte combo.LSbyte
#define mid16 combo.mid16
#define MSbyte combo.MSbyte
#define byte0 bytes.byte0
#define byte1 bytes.byte1
#define byte2 bytes.byte2
#define byte3 bytes.byte3
你的方法:
#pragma pack (1) // 表明该结构体为字节对齐
typedef struct
{
}
#pragma pack () // 注意改语句会恢复默认对齐方式.
我试过了,可以CCSv4环境下编译,会报warning,无法识别#pragma pack
而且在MSP430 Optimizing C/C++ Compiler v 3.3里也没有找到 #pragma pack 的说明 ?
David Liu1:
回复 David Liu1:
@ Peter and Triton
FYI, 我换了种方法,还是没有办法取到奇数地址的Uint16_t
Uint8_t abc[4] = {0x78,0x56,0x34,0x12}; //abc的起始地址是0x0x1cb4
在使用时,
Uint16_t temp;
temp = *(Uint16_t *)&abc[1]; // temp 结果得到 0x5678
机器码 反汇编代码
421F 1CB5 MOV.W &0x1cb5,R15
0F60 1CAC MOVA R15,&temp32
temp = *(Uint16_t *)&abc[0]; // temp 结果得到 0x5678
机器码 反汇编代码
421F 1CB4 MOV.W &abc,R15
0F60 1CAC MOVA R15,&temp32
问题: 而实际上我希望通过temp = *(Uint16_t *)&abc[1]的结果是0x3456,而且汇编程序及机器码也是对的,但是运行结果却没有得到正确的结果呢?是不是需要通过编译器设置MCU内核的对齐方式?