对齐,在定义结构体的时候 是非常要注意的问题, 而且 x86 和ARM的处理方式又不相同。
在对齐的问题的处理上, 又两种方式: 不管他(编译器自动填充,费时间) , 人为填充(空间换时间)
比如下面的例子:思考一下 ,来自 u-boot :
//watchdog 本身没有什么问题, 因为寄存器就是 4个字节连续的。
/* WATCH DOG TIMER (see manual chapter 18) */
typedef struct {
S24X0_REG32 WTCON;
S24X0_REG32 WTDAT;
S24X0_REG32 WTCNT;
} /*__attribute__((__packed__))*/ S24X0_WATCHDOG;
//但是UART 就填充了 , 还要注意endian 的问题, endian的问题, 自己上google学习一下。
/* UART (see manual chapter 11) */
typedef struct {
S24X0_REG32 ULCON;
S24X0_REG32 UCON;
S24X0_REG32 UFCON;
S24X0_REG32 UMCON;
S24X0_REG32 UTRSTAT;
S24X0_REG32 UERSTAT;
S24X0_REG32 UFSTAT;
S24X0_REG32 UMSTAT;
#ifdef __BIG_ENDIAN //这都是今后咱们定义板子上的寄存器要注意的问题,所以我说 这种用结构体定义 寄存器的方式不是很稳当 ,有风险。
S24X0_REG8 res1[3];
S24X0_REG8 UTXH;
S24X0_REG8 res2[3];
S24X0_REG8 URXH;
#else /* Little Endian */
S24X0_REG8 UTXH;
S24X0_REG8 res1[3];
S24X0_REG8 URXH;
S24X0_REG8 res2[3];
#endif
S24X0_REG32 UBRDIV;
} /*__attribute__((__packed__))*/ S24X0_UART; //__attribute__((__packed__)) 事实上加上也是可以的, 因为已经认为填充了, 所以 再 __packed__就没有意义了。
下面是我原来学习的时候 ,总结的一个帖子,你们对照着学习一下 对齐方面的知识 , 以此强化 c 语言编程的能力, 这是 谭浩强 的书里面没有的。
上学的时候, 大家用的是 谭浩强的书 。 因地制宜 , 现在复习这本书肯定是不行了,太初级了。 推荐一本 c primer plus,现在好像是第五版, 我看的时候是第四版 , 不错, 一本大厚书, 基本上都能查到, refer : http://www.china-pub.com/computers/common/info.asp?id=23985
关于对齐本身请参阅我的blog 另一篇文章: