如何解决C 编译器使用的数据布局对齐概念
以下是红龙书的摘录。
例 7.3。图 7.9 是 C 编译器对我们称为 Machine 1
和 Machine 2
的两台机器使用的数据布局的简化。
Machine 1
:Machine 1
的内存被组织成字节,每个字节由 8 位组成。尽管每个字节都有一个地址,但指令集倾向于将 short
整数定位在地址为偶数的字节上,并将整数定位在可被 4
整除的地址上。编译器在偶数地址放置短整数,即使它必须在过程中跳过一个字节作为填充。因此,可以为后跟短整数的字符分配由 32
位组成的四个字节。
Machine 2
:每个字由64
位组成,字地址允许24
位。一个字内的各个位有 64
种可能性,因此需要 6
额外位来区分它们。按照设计,指向 Machine 2
上的字符的指针需要 30
位 — 24
来查找单词,6
表示字符在单词内的位置。 Machine 2
指令集的强字方向性导致编译器一次分配一个完整的字,即使较少的位就足以表示该类型的所有可能值;例如,只需要 8
位来表示一个字符。因此,在对齐情况下,图 7.9 显示了每种类型的 64
位。在每个字中,每个基本类型的位都位于指定的位置。由 128
位组成的两个字将分配给后跟一个短整数的字符,该字符仅使用第一个字中的 8
位,而短整数仅使用 24
第二个字中的位。 □
我发现了对齐的概念 here 、here 和 here。我可以从它们中理解如下:在字可寻址 cpu(大小超过一个字节)中,在数据对象中引入了某些填充,以便 cpu 可以有效地从内存中检索数据,而最少没有。内存周期。
现在这里的 Machine 1
实际上是一个字节地址。 Machine 1
规范中的条件可能比字大小为 4
字节的简单字可寻址机器更困难。在这样的 64
位机中,我们需要确保我们的数据项只是字对齐,没有更多的困难。但是如何在像 Machine 1
这样的系统中找到对齐(如上表所示),其中字对齐的简单概念不起作用,因为它是字节可寻址的,并且具有更困难的规范。
此外,我觉得很奇怪的是,在 double
行中,类型的大小大于对齐字段中给出的大小。不应该 alignment(in bits) ≥ size (in bits)
吗?因为对齐是指实际为数据对象分配的内存(?)。
"每个字由 64
位组成,字的地址允许有 24
位。字内的各个位有 64
种可能性,所以需要 6
额外的位来区分它们。根据设计,指向 Machine 2
上的字符的指针需要 30
位 — 24
来查找单词和 {{1} }} 用于字符在单词中的位置。” - 此外,基于对齐的关于指针概念的声明应该如何可视化(2^6 = 64,这很好,但是如何这6位与对齐概念相关)
解决方法
首先,机器 1 一点也不特别——它和 x86-32 或 32 位 ARM 完全一样。
此外,我觉得很奇怪的是,在两倍的行中,类型的大小超过了对齐字段中给出的大小。不应该对齐(以位为单位)≥大小(以位为单位)吗?因为对齐是指实际为数据对象分配的内存(?)。
不,这不是真的。对齐意味着对象中最低可寻址字节的地址必须能被给定的字节数整除。
此外,对于C,数组中的sizeof (ElementType)
也需要大于或等于每个成员的对齐方式和sizeof (ElementType)
可以被对齐方式整除,因此脚注a。因此在后者的计算机上:
struct { char a,b; }
可能有 16 的大小,因为字符在不同的可寻址词中,而
struct { char a[2]; }
可以压缩成 8 个字节。
这个基于对齐的关于指针概念的陈述应该如何可视化(2^6 = 64,这很好,但这6位与对齐概念如何相关)
至于字符指针,6位是假的。在8-byte字中选择8个字节中的一个需要3位,所以这是书中的一个错误。一个普通的字节只会选择一个 24 位的字,一个字符(一个字节)指针会选择一个 24 位的字,以及字内的一个 8 位字节,其中一个是 3 位。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。