学习笔记 - 结构体与字节对齐控制指针结构(二)

以下内容仅为个人笔记,个人理解

接上一篇.

字节对齐命令的处理位置

根据图片可以看到,在编译的第二阶段开始出现了不同,导致在编译的第三阶段也出现了不同,但是在编译的最后阶段,链接脚本来搞事的时候,程序的要装入内存的各段大小相同,装入的位置也相同
原因 : 直接上一段链接脚本的代码

.data : ALIGN(4) {
    ...
    _data_start = ABSOLUTE(.);
    *(.data)
    *(.data.*)
    ...
} ...

这里强制了4字节对齐,所以我们一开始的编译命令 #pragma pack(1) 并不能改变最后的链接脚本对齐命令,所以我们不用担心cpu的效率降低 , 我的猜测是链接脚本会在后面的内存段补0 , 不过我没有验证 ,因为不知道怎样去验证…
好了,接下来就说在代码中的实际运用

字节对齐命令在代码中的实际运用

要操作的空间和变量
这里我们假设x变量(32位无符号)被放在了0X00~0X03处(为了好说明每个内存单元的内容)

uint32_t x ;

初始时 0X00~0X03 00 00 00 00
假设我们要将0X00 变为F0 0X01~0X02 变为 F1 F2 (在lwip中发送数据帧的时候这样的操作很多,被封装在内核里)

先用默认的被4字节对齐的结构体来操作

定义结构体

#pragma pack(4)
struct test_4{
 uint8_t  u8;
 uint16_t  u16;
} ;
#pragma pack()

用这个指针结构的话u16实际上是指向后两个内存单元的(0X02~0X03)
而不是在0X01~0X02处,上代码来验证

struct test_4* px = (struct test_4*)&x ;
px->u8 = 0XF0 ;
px->u16 = 0XF2F1 ;
printf("%p",x) ;

在这里插入图片描述
这就是被默认字节对齐的后果

用1字节对齐的结构体来操作

只要将上面的结构体中的 pack(4)改为pack(1) ,就能立竿见影
在这里插入图片描述
最后
一般在内核中都会定义很多宏,这个宏分别放在结构体的头部,尾部或者语句结束符号(;)的前面,目的就是因为根据编译器的不同,字节对齐命令会放在结构体的不同位置,更改宏的话就可以方便的在这三个地方(头,;前和尾部)加上字节对齐命令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值