第3章“程序的机器级表示”:对齐(alignment)

news2025/2/1 3:56:00

  许多计算机系统对基本数据类型的可允许地址做出了一些限制,要求某种类型的对象的地址必须是某个值 k k k (通常是2、4 或 8)的倍数。这种 对齐限制 简化了处理器和存储器系统之间接口的硬件设计。例如,假设一个处理器总是从存储器中取出 8 个字节出来,则地址必须是 8 的倍数。如果能保证所有的 double 都将它们的地址对齐成 8 的倍数,那么久可以用一个存储器操作来读或者写值了。否则,可能需要执行两次存储器访问,因为对象可能分放在两个 8 字节存储器块中。

  无论数据是否对齐,IA32 硬件都能正确工作。不过,Intel 还是建议要对齐数据以提高存储器系统的性能。Linux 沿用的对齐策略是 2 字节数据类型(例如 short)的地址必须是 2 的倍数,而较大的数据类型(例如 intint *floatdouble)的地址必须是 4 的倍数。注意,这个要求就意味着一个 short 类型对象的地址的最低位必须等于0。类似地,任何 int 类型的对象或指针的地址的最低两位必须都是0。

Microsoft Windows 的对齐

Microsoft Windows 对对齐的要求更严格——任何 k k k 字节(基本)对象的地址都必须是 k k k 的倍数。特别的,它要求一个 double 的地址应该是 8 的倍数。这种要求提高了存储器性能,代价是浪费了一些空间。Linux 中的设计决策可能对 i386 很好,以前存储器十分缺乏,而存储器总线只有 4 个字节宽。对于现代处理器来说,Microsoft 的对齐策略就是更好的选择了。

命令行选项 -malign-double 会使 Linux 上的 GCC 为 double 类型的数据使用 8 字节的对齐。这会提高存储器性能,但是在与用 4 字节对齐方式下编译的库代码链接时,会导致不兼容。

  确保每种数据类型都是按照指定方式来组织和分配的,即每种类型的对象都满足它的对齐限制,就可保证实施对齐。编译器在汇编代码中放入命令,指明全局数据所需的对齐。例如,3.6.6 小节中跳转表的汇编代码声明的第2行就包含下面这样的命令(directive):

.align 4

  这就保证了它后面的数据(在此,是跳转表的开始)会从以 4 的倍数的地址处开始。因为每个表项长 4 个字节,后面的元素都会遵守 4 字节对齐的限制。

  分配存储器的库例程(例如 malloc)的设计必须使得它们返回的指针能满足最糟糕情况的对齐限制,通常是 4 或者 8。对于有结构的代码,编译器可能需要在域的分配中插入间隙,以保证每个结构元素都满足它的对齐要求,而结构本身对它的起始地址也有一些对齐要求。

  例如,如下的结构声明:

struct S1 {
	int i;
	char c;
	int j;
};

  假设编译器用的是最小的 9 字节分配,画出图来是这样的:
在这里插入图片描述
  它是不可能满足域 i i i (偏移为 0)和 j j j (偏移为 5)的 4 字节对齐要求的。所以,编译器在域 c c c j j j 之间插入一个 3 字节的间隙(在此用 “XXX” 表示):

在这里插入图片描述
  结果, j j j 的偏移量为 8,而整个结构的大小为 12 字节。此外,编译器必须保证任何 struct S1 * 类型的指针 p p p 都满足 4 字节对齐。用前面的符号,让指针 p p p 的值为 x p x_p xp。那么, x p x_p xp 必须是 4 的倍数。这就保证了 p->i(地址 x p x_p xp)和 p->j(地址 x p + 4 x_p + 4 xp+4)都满足它们的 4 字节对齐要求。

  另外,编译器可能需要添加一些填充到结构的末尾,这样结构数组的每个元素都会满足它的对齐要求。例如,看如下这个结构声明:

struct S2 {
	int i;
	int j;
	char c;
};

  如果将这个结构打包成 9 个字节,只要保证结构的起始地址满足 4 字节对齐要求,仍然能够保证域 i i i j j j 的对齐要求。不过,考虑如下声明:

struct S2 d[4];

  分配 9 个字节,是不可能满足 d d d 的每个元素的对齐要求的,这是因为这些元素的地址分别为 x d x_d xd x d + 9 x_d + 9 xd+9 x d + 18 x_d + 18 xd+18 x d + 27 x_d + 27 xd+27

  编译器会为结构 S1 分配 12 个字节,最后 3 个字节是浪费的空间:

在这里插入图片描述
  这样一来, d d d 的元素的地址分别为 x d x_d xd x d + 12 x_d + 12 xd+12 d d + 24 d_d + 24 dd+24 x d + 36 x_d + 36 xd+36。只要 x d x_d xd 是 4 的倍数,所有的对齐限制就都可以满足了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pikachu靶场-File Inclusion

文件包含漏洞概述 在web后台开发中&#xff0c;程序员往往为了提高效率以及让代码看起来更加简介&#xff0c;会使用”包含“函数功能。比如把一系列功能函数都写进function.php中&#xff0c;之后当某个文件需要调用的时候就直接在文件头上写上一句<?php include functio…

多叉树的构建,条件查询,修改删除节点

多叉树的构建查询&#xff0c;新增&#xff0c;修改&#xff0c;删除 文章目录 多叉树的构建查询&#xff0c;新增&#xff0c;修改&#xff0c;删除一&#xff0c;数据库表设计二、新增相对应数据库表的实体类三、新建多叉树树工具类四、多叉树树的条件查询五、多叉树的节点新…

关于【Git】push失败与使用小乌龟(TortoiseGit)时的一些报错解决方案

1.报错:No supported authentication methods available (server sent: publickey) 原因.小乌龟没有设置git路径&#xff0c;解决如下 将红框标注的地址改为自己的git安装地址即可。 2.使用git推送到远程仓库的时候报错Failed to connect to 127.0.0.1 port 7890: 拒绝连接 …

C# 让程序代码在固定的线程里运行

一、概述 在平时我们的开发中&#xff0c;多线程也是经常用到的&#xff0c;尤其是我们做上位机行业的&#xff0c;平时更是必不可少&#xff0c;在以前我做 Unity3d 开发时&#xff0c;其实并不用关心线程的问题&#xff0c;在 Unity 的开发中&#xff0c;所有代码基本都是单…

点云综述(整理自网络资源)

目录 一、什么是点云 二、如何获取点云 1、三维激光扫描仪 2、双目相机 双目测距基本原理 视差图 双目测距的优点与难点 3、RGB-D相机 RGB-D什么意思 RGB-D相机的分类 RGBD相机的缺点&#xff1a; RGBD相机的优点 三、点云有哪些研究方向 1、基于点云的分类 2、基于…

华为OD机试真题 JavaScript 实现【IPv4地址转换成整数】【2023 B卷 100分】

一、题目描述 存在一种虚拟 IPv4 地址&#xff0c;由4小节组成&#xff0c;每节的范围为0~255&#xff0c;以#号间隔&#xff0c; 虚拟 IPv4 地址可以转换为一个32位的整数&#xff0c;例如&#xff1a; 128#0#255#255&#xff0c;转换为32位整数的结果为2147549183&#xff0…

【深入理解函数栈帧:探索函数调用的内部机制】

本章我们要介绍的不是数学中的函数&#xff0c;而是C语言中的函数哟&#xff01; 本章重点 了解汇编指令深刻理解函数调用过程 样例代码&#xff1a; #include <stdio.h> int MyAdd(int a, int b) {int c 0;c a b;return c; }int main() {int x 0xA;int y 0xB;int…

SpringCloud第二篇:Feign远程调用

思考&#xff1a;为啥要学Feign呢&#xff1f; 先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; String url "http://userservice/user/" order.getUserId(); User user restTemplate.getFor0bject(url,User.class);这里就有几个问题&#xff1a…

首届“设计·无尽谈”论坛完满收官 持续打造当代设计共同体

首届“设计无尽谈”论坛在京举行 5月16日&#xff0c;首届“设计无尽谈”论坛在北京举行&#xff0c;本次论坛以“漫谈当代空间精神”为主题&#xff0c;12位来自顶尖建筑设计领域的嘉宾和设计师到场&#xff0c;论坛以茶话会的形式进行&#xff0c;不受严格的议程和时间限制的…

计算机网络之网络层

四.网络层&#xff1a;数据平面 4.1 网络层概述 网络层被分解为两个相互作用的部分&#xff0c;即数据平面和控制平面。 数据平面决定到达路由器输入链路之一的数据报如何转发到该路由器的输出链路之一&#xff0c;转发方式有&#xff1a; 传统的IP转发&#xff1a;转发基于…

Nginx(一)介绍Nginx、正向代理和实现反向代理的两个实例

文章目录 一、Nginx介绍二、正向代理三、反向代理四、实例演示1、反向代理实例一&#xff08;反向代理&#xff0c;访问www.123.com&#xff09;2、反向代理实例二&#xff08;使用 nginx 反向代理&#xff0c;根据访问的路径跳转到不同端口的服务中&#xff09; 五、nginx之lo…

文件操作之文件下载(32)

下载和读取是差不多的情况 区分 文件被解析&#xff0c;我们称为文件包含漏洞 显示文件的源代码&#xff0c;我们称为文件读取漏洞 提示文件下载&#xff0c;我们称为文件下载漏洞 #文件下载 文件下载出现的原因&#xff0c;在任意代码里面出现下载性的功能性函数所导致的…

调用腾讯API实现人像分割

目录 1. 作者介绍2&#xff0e;腾讯云API人像分割2.1 人像分割接口描述2.2 请求参数介绍 3&#xff0e;代码实现3.1 获取SecretId和SecretKey3.2 人像分割代码调试3.3 完整代码3.4 实验结果 1. 作者介绍 岳泽昂&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c…

MySQL主从同步——主库已有的数据如何到从库

一、复制主库数据到从库 此步骤主要针对运行一段时间的主库&#xff0c;需要将历史数据导入到从库&#xff0c;保证主从强一致性。 主库锁表停止写操作 在主库MySQL命令行中执行 flush tables with read lock; 主库数据导出 将主库所在主机命令行下使用mysqldump命令导出…

交通状态分析 | Python实现基于张量分解的交通流量时空模式挖掘

文章目录 效果一览文章概述研究内容源码设计参考资料效果一览 文章概述 交通状态分析 | Python实现基于张量分解的交通流量时空模式挖掘 研究内容 一般出行行程通常都由某种明确目的驱使,例如上班、购物或娱乐,出行的起始区域因其承担功能的不同,通常能够反映出用户的出行目…

【一、Linux文件与目录结构】

1 Linux 文件 Linux系统中一切皆文件 2 Linux目录结构 /bin Binary的缩写&#xff0c;存放着命令。 /sbin s即Super User&#xff0c;存放着root用户使用的系统管理程序。 /home 存放着普通用户的主目录&#xff0c;在Linux中每个用户都有一个自己的目录&#xff0c;一般…

近期学习论文总结 3(23.06.05-23.06.09)

公众号&#xff1a;EDPJ 目录 0. 摘要 1. Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization 1.1 主要思想 1.2 AdaIN 1.3 结构以及不同层使用 AdaIN 的效果 2. Watch your Up-Convolution: CNN Based Generative Deep Neural Networks are…

day46_项目

debug bug - 虫 第一台计算机,房子那么大,机械零件,齿轮,坏了,虫子(bug)卡着机器,debug(调试),虫子拿走了,机器就运行了,从此调试机器程序–>debug 目前: 这个卡机器的虫子,在博物馆 工具(IDEAEclipse)支持debug --> 追踪代码 如何使用debug 运行时候就得使用debug模式…

00后从事软件测试一年的心路历程

初识软件测试 不知不觉&#xff0c;我做软件测试已经快一年了&#xff0c;入职第一天的场景仿佛还在昨天。入职前&#xff0c;我对测试的认识仅仅停留在一些软件测试和测试方法的理论知识上&#xff0c;最多也是对自己的代码进行一些单元测试。 我之前所理解的测试是与开发分…

Django-可重用注册登录系统--项目搭建

文章目录 一、项目开始前的思考二、搭建项目环境三、设计数据库模型数据库模型文件设置数据库后端注册app生成迁移脚本并写入数据库测试是否成功数据库模型后台管理 路由与视图函数框架搭建路由配置视图函数的配置模板template的配置测试是否成功 前端界面设计与优化完善登录的…