嵌入式C语言(六)

对齐这个事情在内核中可不是个什么小事,内核中涉及到内存方面的都需要非常的谨慎。

上一篇我们知道了可以通过__attribute__来声明属性,也知道了section这个属性,这篇我们来看看关于内存对齐使用的两个属性–>aligned和packed

地址对齐:aligned

GNU C通过__attribute__来声明aligned和packed属性,指定一个变量或类型的对齐方式。

使用这两个变量告诉编译器,按照我让aligned和packed两同事给你传的信息做事情哦。

举个栗子:在内存中以8字节地址对齐

int a __attribute__((aligned(8)))

这个aligned的参数必须是2的幂次方

但是确实总是可以的专业显示指定变量的对齐方式,会因为边界对齐造成一些内存空洞,浪费内存资源。所以这个操作的必要性在哪里呢?

一个主要原因就是:**这种对齐设置可以简化CPU和内存RAM之间的接口和硬件设计。**一个32位的计算机系统,在CPU读取内存时,硬件设计上可能只支持4字节或4字节倍数对齐的地址访问,CPU每次向内存RAM读写数据时,一个周期可以读写4字节。如果我们把一个int型数据放在4字节对齐的地址上,那么CPU一次就可以把数据读写完毕;如果我们把一个int型数据放在一个非4字节对齐的地址上,那么CPU可能就要分两次才能把这个4字节大小的数据读写完毕。

为了配合计算机的硬件设计,编译器在编译程序时,对于一些基本数据类型,如int、char、short、float等,会按照其数据类型的大小进行地址对齐,按照这种地址对齐方式分配的存储地址,CPU一次就可以读写完毕。虽然边界对齐会造成一些内存空洞,浪费一些内存单元,但是在硬件上的设计却大大简化了。

这个对齐要求不只是针对普通变量,对于复合变量也需要满足地址对齐的要求。

结构体对齐

结构体是复合的数据类型,编译器在分配空间时需要的不仅仅是考虑成员变量的对齐,还要考虑整个结构体的。当老大也是很不容易的。

于是: 为了结构体内各个成员地址对齐,编译器可能会在结构体内填充一些空间;
为了结构体整体对齐,编译器可能会在结构体的末尾填充一些空间。

整个栗子吃吃看:

struct data{
	char a;
	int b;
	short c;
}

因为结构体的成员b需要4字节对齐,所以编译器在给成员a分配完1字节的存储空间后,会空出3字节,在满足4字节对齐的0x0028FF34地址处才给成员b分配4字节的存储空间。接着是short类型的成员c占据2字节的存储空间。三个结构体成员一共占据1+3+4+2=10字节的存储空间。

根据结构体的对齐规则,结构体的整体对齐要按结构体所有成员中最大对齐字节数或其整数倍对齐,或者说结构体的整体长度要为其最大成员字节数的整数倍,如果不是整数倍则要补齐。因为结构体最大成员int为4字节,所以结构体要按4字节对齐,或者说结构体的整体长度要是4的整数倍,要在结构体的末尾补充2字节,最后结构体的大小为12字节。

但是我们换个顺序试试:

struct data{
	char a;
	short b;
	int data;
}

char型变量a和short型变量b,被分配在了结构体前4字节的存储空间中,而且都满足各自的地址对齐方式,整个结构体大小是8字节,只造成1字节的内存空洞。

当然这里我们也可以让这个变成12字节

struct data{
	char a;
	short b __attribute__((aligned(4)));
	int c;
}

也可以指定整个结构体

struct data{
char a;
short b;
int c;
}__attribute__((aligned(16)));

整个结构体的对齐只要按最大成员的对齐字节数对齐即可,结构体整体就以4字节对齐,结构体的整体长度为8字节,但是在这里,显式指定结构体整体以16字节对齐,所以编译器就会在这个结构体的末尾填充8字节以满足16字节对齐的要求,最终导致结构体的总长度变为16字节。

想想这个编译器就说什么听什么?会不会它觉得自己更靠谱。

编译器一定会按照aligned指定的方式对齐吗? NONONO

我们通过这个属性声明,其实只是建议编译器按照这种大小地址对齐,但不能超过编译器允许的最大值。一个编译器,对每个基本数据类型都有默认的最大边界对齐字节数。如果超过了,则编译器只能按照它规定的最大对齐字节数来给变量分配地址。(在我的底线内你随便玩)

char c2 __attribute__((aligned(16))) = 4;    //能执行

char c2 __attribute__((aligned(32))) = 4;    //nonono

这是因为32字节的对齐方式超过了编译器允许的最大值。

编译器还挺霸道总裁

到这里,关于aligned七七八八了,具体的还需要去内核的源码中遨游学习,在属性中,还有个packed,在上篇文章的例子中有出现过。下面来一起看看。

属性声明:packed

aligned属性一般用来增大变量的地址对齐,元素之间因为地址对齐会造成一定的内存空洞。

packed属性则与之相反,一般用来减少地址对齐,指定变量或类型使用最可能小的地址对齐方式。

话不多说,给大爷们摆上栗子:

struct data{
	char a;
	short b __attribute__((packed));
	int c _attribute__((packed));
};

结构体内各个成员地址的分配,使用最小1字节的对齐方式,没有任何内存空间的浪费,导致整个结构体的大小只有7字节。

上面刚刚说了内存对齐方便读写,这感觉有点矛盾?不是的哈,各个使用的场景不同。

packed这个特性在底层开发驱动还是非常有用:

例如,你想定义一个结构体,封装一个IP控制器的各种寄存器,在ARM芯片中,每一个控制器的寄存器地址空间一般都是连续存在的。如果考虑数据对齐,则结构体内就可能有空洞,就和实际连续的寄存器地址不一致。使用packed可以避免这个问题,结构体的每个成员都紧挨着,依次分配存储地址,这样就避免了各个成员因地址对齐而造成的内存空洞。

于是我们可以对结构体加packed属性,保证每个结构体的成员是连续的。

配合使用packed和aligned

我们可以在结构体内部保持 连续,然后让结构体去对齐,这样既避免了结构体内各成员因地址对齐产生内存空洞,又指定了整个结构体的对齐方式。

struct data{
	char a;
	short b;
	int c;
}__attribute__((packed,aligned(8)));

在这里插入图片描述

结构体data虽然使用了packed属性声明,结构体内所有成员所占的存储空间为7字节,但是我们同时使用了aligned(8)指定结构体按8字节地址对齐,所以编译器要在结构体后面填充1字节,这样整个结构体的大小就变为8字节,按8字节地址对齐。

  • 资料:《嵌入式C语言自我修养——从芯片、编译器到操作系统》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/447553.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Altium Designer如何对走线模式进行切换

AD软件提供了比较智能的走线模式切换功能,可以根据个人习惯进行切换,能有效的提高了PCB设计效率。 点击界面右上角系统参数的图标 或者在pcb界面中使用快捷键OP进入到优选项界面,然后选中 PCB Editor-Interactive Routing,在布线…

ubuntu設定QGC獲取pixhawk Mini4(PX4 Mini 4) 的imu信息

ubuntu20.04 QGC使用v4.3.0的版本 飛控pixhawk Mini4 飛控上只使用一條micro USB連接電腦,沒有其他線 安裝命令 sudo apt-get remove modemmanager -y sudo apt install gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl -y sudo apt install libf…

Vue:纯前端实现文件拖拽上传

先看一下拖拽相关的事件:dragover、dragenter drop和dragleave 。 dragover事件:当被拖动的元素在一个可放置目标上方时,该事件会被触发。 通常,我们会使用event.preventDefault()方法来取消浏览器默认的拖放行为,以便…

amv是什么文件格式?如何播放amv视频?

AMV文件格式源自于中国公司Actions Semiconductor,最初作为其MP4播放器中使用的专有视频格式。产生于数码媒体发展的需求下,AMV格式为小屏幕便携设备提供了一种高度压缩的视频存储方案。 AMV文件格式的主要特性与使用场景 AMV格式以其独特的特性在小尺寸…

复合式统计图绘制方法(7)

复合式统计图绘制方法(7) 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制,饼图环形图绘制较难。 在统计图的应用方面,有时候有两个关联的统计学的样本值要用统计图来表达&#xff0…

运动想象 (MI) 迁移学习系列 (5) : SSMT

运动想象迁移学习系列:SSMT 0. 引言1. 主要贡献2. 网络结构3. 算法4. 补充4.1 为什么设置一种新的适配器?4.2 动态加权融合机制究竟是干啥的? 5. 实验结果6. 总结欢迎来稿 论文地址:https://link.springer.com/article/10.1007/s11517-024-0…

天府锋巢直播产业基地:直播带岗,成都直播基地奔向产业化

天府锋巢直播产业基地位于成都市天府新区科学城板块,是一座集直播带岗、电商孵化、产业培训、供应链整合等多功能于一体的现代化全域直播产业基地。近年来,随着成都直播产业的蓬勃发展,成都积极响应市场需求,致力于打造出西部地区…

linux进程间通信-共享内存

一、共享内存是什么 在Linux系统中,共享内存是一种IPC(进程间通信)方式,它可以让多个进程在物理内存中共享一段内存区域。 这种共享内存区域被映射到多个进程的虚拟地址空间中,使得多个进程可以直接访问同一段物理内存…

【Python可视化系列】一文教你绘制雷达图(源码)

这是我的第234篇原创文章。 一、引言 雷达图是以从同一点开始的轴上表示的三个或更多个定量变量的二维图表的形式显示多变量数据的图形方法,也称为蜘蛛图或星形图。雷达图通常用于综合分析多个指标,具有完整,清晰和直观的优点。通常由多个等…

Constrained Iterative LQR 自动驾驶中使用的经典控制算法

Motion planning 运动规划在自动驾驶领域是一个比较有挑战的部分。它既要接受来自上层的行为理解和决策的输出,也要考虑一个包含道路结构和感知所检测到的所有障碍物状态的动态世界模型。最终生成一个满足安全性和可行性约束并且具有理想驾驶体验的轨迹。 通常,motion plann…

遥感影像植被波谱特征总结

植被跟太阳辐射的相互关系有别于其他物质&#xff0c;如裸土、水体等&#xff0c;比如植被的“红边”现象&#xff0c;即在<700nm附近强吸收&#xff0c;>700nm高反射。很多因素影响植被对太阳辐射的吸收和反射&#xff0c;包括波长、水分含量、色素、养分、碳等。 研究…

Kubernetes--ingress实现七层负载

目录 一、传统方式&#xff1a;不借助ingress实现七层代理 二、nginx-ingress 三、使用ingress实现七层代理 四、部署ingrss-nginx及功能 五、样例 1.Ingress-nginx HTTP代理访问 2.Ingress HTTPS代理访问&#xff08;会话卸载层&#xff09; 3.Nginx进行BasicAuth&…

亚马逊店铺解决和预防订单下滑的技巧

1. 保持账号的良好表现。不要销售侵权产品&#xff0c;发货要及时&#xff0c;能有追踪号的就带可查询追踪号&#xff0c;能发FBA的就通过FBA发货。 2. 持续做好产品优化工作&#xff0c;及时留意大环境的变化和平台政策变动。遇到编辑权限受限&#xff0c;可开case咨询或申请…

【数据库】软件测试之MySQL数据库练习题目

有表如下&#xff1a; Student 学生表 SC 成绩表 Course 课程表 Teacher 老师表 每个学生可以学习多门课程&#xff0c;每一个课程都有得分&#xff0c;每一门课程都有老师来教&#xff0c;一个老师可以教多个学生 1、查询姓‘朱’的学生名单 select * from Student whe…

vb机试考试成绩分析与统计,设计与实现(高数概率统计)-141-(代码+程序说明)

转载地址http://www.3q2008.com/soft/search.asp?keyword141 前言: 为何口出狂言,作任何VB和ASP的系统, 这个就是很好的一个证明 :) 又有些狂了... 数据库操作谁都会,接触的多了也没什么难的,VB编程难在哪?算法上,这个是一个算法题的毕业设计,里面涉及到对试卷的 平均分,最…

AI编程已有公司纳入绩效,你的AI编程工具是什么?

自从ChatGPT带动全球AI热潮&#xff0c;AI席卷着各行各业。编程界也不例外&#xff0c;最出名的摸过OpenAI与GitHub联合开发的Github Copilot。Github Copilot带动了一大堆AI编程工具的出现。后来Github Copilot付费了&#xff0c;再加上网络方面的问题&#xff0c;在国内使用G…

基于PHP的店家服务与管理交互平台

目 录 摘 要 I Abstract II 引 言 1 1相关技术 3 1.1 PHP 3 1.2 ThinkPHP框架 3 1.2.1 Struts结构 3 1.2.2 MVC 3 1.2 Tomcat服务器 3 1.3 MySQL数据库 3 1.4 LayUI框架 4 1.5 ECharts 4 1.6 本章小结 4 2 系统分析 5 2.1 功能需求 5 2.2 用例分析 6 2.3 非功能需求 8 2.4 本章…

MySQL--索引类型详解

索引的类型 主键索引&#xff1a; PRIMARY KEY&#xff0c;当一张表的某个列是主键的时候&#xff0c;该列就是主键索引&#xff0c;一张表只允许有一个主键索引&#xff0c;主键所在的列不能为空。 创建主键索引的SQL语法&#xff1a; # 给user表中的id字段创建名为id_ind…

【Datawhale学习笔记】从大模型到AgentScope

从大模型到AgentScope AgentScope是一款全新的Multi-Agent框架&#xff0c;专为应用开发者打造&#xff0c;旨在提供高易用、高可靠的编程体验&#xff01; 高易用&#xff1a;AgentScope支持纯Python编程&#xff0c;提供多种语法工具实现灵活的应用流程编排&#xff0c;内置…

数字化车间MES管理系统如何降低如何降低企业生产成本

数字工厂管理系统在降低制造企业生产成本方面发挥了重要的作用。通过优化物流和信息流&#xff0c;实现生产过程的自动化、智能化和可视化&#xff0c;数字工厂管理系统将从三个方面来降低生产成本。 1、数字工厂管理系统可以通过减少库存量来降低企业的生产成本。数字工厂管理…