C编译器使用的数据布局(对齐概念)

C编译器使用的数据布局(对齐概念),c,compiler-construction,local,memory-alignment,runtime-environment,C,Compiler Construction,Local,Memory Alignment,Runtime Environment,下面是红龙书的摘录 例7.3。图7.9简化了C编译器对两台机器使用的数据布局,我们称之为machine1和machine2 machine1:将machine1的内存组织为字节,每个字节由8位组成。即使每个字节都有一个地址,指令集也支持将short整数定位在地址为偶数的字节上,而将整数定位在可被4整除的地址上。编译器在偶数地址处放置短整数,即使在该过程中必须跳过一个字节作为填充。因此,可以为后跟短整数的字符分配由32位组成的四个字节 machine2:每个单词由64位组成,单词地址允许24位。一

下面是红龙书的摘录

例7.3。图7.9简化了C编译器对两台机器使用的数据布局,我们称之为
machine1
machine2

machine1
:将
machine1
的内存组织为字节,每个字节由8位组成。即使每个字节都有一个地址,指令集也支持将
short
整数定位在地址为偶数的字节上,而将整数定位在可被
4
整除的地址上。编译器在偶数地址处放置短整数,即使在该过程中必须跳过一个字节作为填充。因此,可以为后跟短整数的字符分配由
32
位组成的四个字节

machine2
每个单词由
64
位组成,单词地址允许
24
位。一个单词中的各个位都有
64
的可能性,因此需要额外的
6
位来区分它们。根据设计,指向
机器2
上字符的指针需要
30位-
24位-
24位-
6位
查找字符在单词中的位置。
机器2
指令集的强单词方向导致编译器一次分配一个完整的单词,即使更少的位足以表示该类型的所有可能值;e、 例如,只需要
8
位来表示字符。因此,在对齐下,图7.9显示了每种类型的
64
位。在每个字中,每个基本类型的位都位于指定的位置。由
128
位组成的两个字将分配给一个字符,后跟一个短整数,该字符只使用第一个字中位的
8
,短整数只使用第二个字中位的
24
。□

我发现了关于对齐的概念,以及。我可以从中理解如下:在字可寻址CPU(大小超过一个字节)中,在数据对象中引入了某些填充,这样CPU就可以用最少的内存周期有效地从内存中检索数据

现在机器1实际上是一个字节地址1。
machine1
规范中的条件可能比单词大小为say
4
字节的简单单词寻址机器更困难。在这样的
64
位机器中,我们需要确保我们的数据项只是单词对齐,没有更多的困难。但是如何在
machine1
(如上表所示)这样的系统中找到对齐,因为简单的单词对齐概念不起作用,因为它是字节可寻址的,并且具有更困难的规范

此外,我发现非常奇怪的是,在
double
的行中,类型的大小大于对齐字段中给出的大小。不应
对齐(以位为单位)≥ 大小(以位为单位)
?因为对齐是指实际分配给数据对象(?)的内存


“每个字都由
64
位组成,一个字的地址允许
24
位。一个单词中的各个位都有
64
的可能性,因此需要额外的
6
位来区分它们。根据设计,指向
机器2
上字符的指针需要
30位-
24位-
24位-
6位-
查找字符在单词中的位置。”-此外,基于对齐的指针概念的这一陈述应该如何可视化(2^6=64,这很好,但这6位与对齐概念有何关联)

首先,机器1一点也不特殊-它完全像x86-32或32位ARM

此外,我发现非常奇怪的是,在double的行中,类型的大小超过了alignment字段中给出的大小≥ 大小(以位为单位)?因为对齐是指实际分配给数据对象(?)的内存

不,这不是真的。对齐意味着对象中最低可寻址字节的地址必须可以被给定的字节数整除

此外,对于C,数组中
sizeof(ElementType)
需要大于或等于每个成员的对齐度,并且
sizeof(ElementType)
可以被对齐度整除,因此脚注a在后面的计算机上:

 struct { char a, b; }
可能具有sizeof16,因为字符位于不同的可寻址单词中,而

struct { char a[2];  }
可以压缩为8个字节


关于基于对齐的指针概念的这一陈述应该如何可视化(2^6=64,这很好,但这6位与对齐概念有何关联)


至于字符指针,6位是假的。在8字节字中选择8字节之一需要3位,因此这是本书中的一个错误。普通字节只选择一个24位的字和一个字符(一个字节)指针将选择24位的单词,其中一个8位字节将选择3位。

另一个有趣的事实是,C允许指向不同类型的指针具有不同的格式,“机器2”“实现利用了这一事实。这一切都是可行的,因为不能保证将指针转换为整数类型会产生以字节为单位的值;换句话说,您无法通过简单地将指针转换为
intptr\t
并检查