Memory 内存地址对齐

Memory 内存地址对齐,memory,assembly,operating-system,Memory,Assembly,Operating System,我对记忆对齐的概念有点困惑。所以我的疑问是: 文本所说的是,如果你想读取4字节的数据,从一个不能被4整除的地址开始,你有一个未对齐的内存访问的情况。例如,如果我想从地址05开始读取10个字节,这将被称为未对齐访问(http://www.mjmwired.net/kernel/Documentation/unaligned-memory-access.txt). 这种情况是否特定于4字节字可寻址体系结构,或者对于字节可寻址体系结构也是有效的?如果上述情况对于字节可寻址体系结构是不一致的,为什么

我对记忆对齐的概念有点困惑。所以我的疑问是: 文本所说的是,如果你想读取4字节的数据,从一个不能被4整除的地址开始,你有一个未对齐的内存访问的情况。例如,如果我想从地址05开始读取10个字节,这将被称为未对齐访问(http://www.mjmwired.net/kernel/Documentation/unaligned-memory-access.txt).

这种情况是否特定于4字节字可寻址体系结构,或者对于字节可寻址体系结构也是有效的?如果上述情况对于字节可寻址体系结构是不一致的,为什么会这样


谢谢

对齐与数据大小和寻址有关。大多数指令集/软件的寻址以字节为单位。0,1,2,3都是有效的字节地址。假设您正在访问的内存系统或外围设备是“字节可寻址”的,基本上您可以向其写入单个字节,您通常有允许您使用任何地址值的指令。当您有一个或两个以上的字节时,对齐开始。如果对齐表示地址的lsbit为零,则未对齐表示为一。四个字节,32位数量,低两位为零,对齐,一个或两个不为零,未对齐,依此类推。可以将其视为一个地址的模,其中模4=0在4字节边界上对齐

现在,作为一名软件工程师,您通常不会故意将自己置于一种情况下,即您需要在地址5处获取10个字节,您可能会在0x4处获取12个字节,或者在0x0处获取16个字节,或者沿着这些线进行一些操作,即使您只使用其中的10个字节,您也会更符合逻辑地对齐它们。外部影响、网络数据包、文件系统、共享内存、硬件等,任何时候当您跨越编译域时,您可能必须处理这些问题并采取相应的行动。10字节是否有趣取决于您是否试图将这些字节复制到另一个同样糟糕的地址,或者只是读取或写入它们。如果要读取,您可能只想读取地址0x4处的12个字节,然后将其处理完毕。如果写得好,您可以在一个漂亮的循环中完成所有10个,或者一次展开一个字节,您可以在0x5处写入一个,在0x6处写入两个,在0x8处写入四个,在0xC处写入两个,在0xE处写入一个,或者在0x5处写入一个循环或展开的4个16位值,从0x6开始,然后在0xE处写入一个字节。等等

既然您说过读取,那么您可以读取0x4处的3个32位量或从0x0处开始的两个64位量。这在很大程度上取决于您计划对数据做什么以及您正在使用的指令集等。10字节的读取循环可能是最干净/最简单的读取、维护等方式

如果您想知道对齐与未对齐,那么正如我在上面提到的写操作一样,您可以

8 bit access at 0x5
16 bit access at 0x6
32 bit access at 0x8
16 bit access at 0xC
8 bit access at 0xE

正如我一直在说的那样,阅读可能不是最有效的。对于写操作,您可以按32位或64位的数量或我上面提到的组合进行读修改写操作。

一般来说,内存中的位0选通到总线上,该总线的位0连接到每个寄存器的位0。这样一直持续到第31位。可能存在将每个字节(位15:8、23:16和31:24)定向到低位字节(位7:0)的特殊硬件。(当您到达位“32”时,它实际上是地址4处4字节字的第0位。)

然而,在标称情况下,没有任何特殊硬件将字节移动到它们名义上以自然顺序连接到的位置之外的任何位置,可能还有字节通道0

想象一下,一个具有32个数据引脚的简单内存芯片和一个具有32个数据引脚的简单CPU。每个芯片上的一个给定数据管脚连接到另一个芯片上的对应管脚,并且仅连接到该管脚。对于一个简单的CPU来说,根本没有办法进行错位读取

,请考虑从0读取。接下来的4个字节都会以有线方式落入寄存器,从地址4读取时也会发生这种情况。但是如果您从地址1读取(32位)会怎么样?还是2?还是3?虽然读取不能直接在硬件中完成,但是一个花哨的控制器会导致很多事情发生:

  • CPU可以执行两次读取以获取所有位。它不能同时做这些,它只有32个引脚。一个从地址0读取,一个从地址4读取
  • 然后,CPU必须执行各种移位、掩码和包含或操作,以便从两个组件中构造一个字
所有这些都需要额外的时间



注意。实际上,数据总线通常是32位的倍数,内存也是如此。可能存在用于重新排列对象的特殊硬件。但即使如此,因为这是一种异常情况,它可能无法获得正确对齐的读取所获得的管道优化,即使使用特殊硬件,通过它运行操作数也可能会有时间损失。

这是操作系统用来解决的问题之一……据我所知,没有一个处理器的数据类型为10字节。让我们使用一个具有32位数据总线并试图从地址1读取32位值的普通处理器来保持简单。这需要先读取地址0处的值,将字节1移动到偏移量0,将字节2移动到偏移量1,将字节3移动到偏移量2。然后读取地址4处的值,并将字节0移动到偏移量3。听起来很复杂,不是吗:)