数据对齐的理解与一道组成原理题的详细解释

时间:2021-09-10 17:06:26

首先需要解释的是数据对齐到底是什么,为什么有,如何处理。

以2012年408统考的一道题目为例,详细解释其中的细小知识点:

某计算机存储器按照字节编址,采用小端方式存储数据,假定编译器规定int和short型长度分别为32位和16位,并且数据按照边界对齐存储。 某C语言的程序段如下:

struct 
{
    int a;
    char b;
    short c;
} record;
record.a = 273;

若record变量的首地址为0xC008,则地址0xC008的内容以及record.c的地址分别为:
A. 0x00、0xC00D
B. 0x00、0xC00E
C. 0x11、0xC00D
* D. 0x11、0xC00E

这种题目需要很小心每一个知识点的运用,一步错全全错。

首先,小端存储是指:数据的高位存在高地址,数据的低位存在低地址。

比如十六进制数0x123456,则我们知道12是最高位,34其次,56最低。那么存储的时候,如果用的是小端序,内存地址最小的那个用来存储56,地址增大一些存34,再高一些存12.

这里,其实我还要一个没弄明白的问题,分配的int数据,这个地址是高位还是低位?
当然按照题目的做法是,指代低位,继续增长。因此,一个int数据的4个字节,0xC008指代的是最小的地址。
现在我们把这个假定为一个条件,不去细说(我还不知道怎么来的)。

接着,重点在于对齐,结构体中会根据第一个数据的大小进行对齐。
问题来了,我们是按照最大数据进行对齐还是按照第一个数据进行对齐?

不同机器上的对齐策略不同,一般按照int的4个字节进行对齐。
而这个结构体共7个字节,所以对齐后是8个字节。

那么这个留空的字节位置在哪?

就需要牵涉到变量起始地址的问题。

规定:变量的起始地址必须能够被自身数据类型的大小整除。

对于273,十六进制是0x111,因此第一个低位字节存储0x11,再高一点的字节存储0x01,后面两个字节为空的不管。好了,看存储char b,这个大小是1个字节,存完之后,如果紧接着就存short c,那么c的起始地址是个奇数,不能被2整除。
因此在char b后留白一个字节。

所以,问题得解。