L. *_*ldt 2 memory x86 assembly memory-alignment low-level
我知道这个问题已经被问了一千次,我已经通读了每一个答案,但我仍然不明白。我的 RAM 模型可能存在一些基本错误,这使我无法理解任何答案。
我从互联网上获得了所有这些小信息,但我无法连接它们。
以下是我目前所知道的:以 IA-32 架构为例,其字边界为 32 位(边界 = CPU 可以从内存中读取的最大值?)。它将始终在其字边界内读取。
1)那么,无论我给它什么地址,它总是会读取 4 个字节?如果我在地址 x 有一个简单的字符怎么办。它会从那个地址读取 4 个字节,然后做一些奇怪的事情来只得到一个字节吗?
2)如果是这样,那么字符串(字符序列)n_chars * 4 字节大吗?我很确定它不是那样的,但是我应该如何解释“将始终阅读其单词边界”呢?
3)内存对齐似乎只与数据结构有关。为什么?内存的其余部分是否未对齐?我的意思是物理、虚拟、内核空间等?
4) 为什么我只能在可被 4 整除的地址中存储 32 位值?我的意思是我知道它最终只会读取 32 位,但为什么它不能从奇数地址读取 32 位?比如这里的限制是什么?
我只是很困惑请帮助我
在现代计算机中,内存是面向字节的。每个字节都有自己的地址,可以单独从 RAM 中获取。为了你的程序,你可以假设获取一个字的行为就像获取以任意顺序组成的字节,然后将它们组合成你加载到的寄存器中的一个字。
请注意,这是一个抽象。存储芯片通常以一次获取 8 个或更多字节的方式连接。CPU 有一些电路可以将所有这些从机器代码中抽象出来。然而,这种抽象是有漏洞的,这会导致许多影响:
所以现在,对于您的问题:
1)那么,无论我给它什么地址,它总是会读取 4 个字节?如果我在地址 x 有一个简单的字符怎么办。它会从那个地址读取 4 个字节,然后做一些奇怪的事情来只得到一个字节吗?
也许。这取决于您使用的硬件。但是,是的,如果您请求一个字节,您将只会得到一个字节。你不应该关心硬件读取多少字节来给你一个字节。
2)如果是这样,那么字符串(字符序列)n_chars * 4 字节大吗?我很确定它不是那样的,但是我应该如何解释“将始终阅读其单词边界”呢?
字符串通常是n_chars字节大。当您从字符串中读取一个字符时,您会得到一个字节。硬件可能会读取更多字节来满足您的请求,但这不是您需要关心的。请注意,Windows 有时使用 UTF-16 字符串,每个字符占用两个字节,但这种趋势并没有真正流行起来。
3)内存对齐似乎只与数据结构有关。为什么?内存的其余部分是否未对齐?我的意思是物理、虚拟、内核空间等?
每当您考虑 RAM 中的数据时,内存对齐都很重要。该内存是在内核内部使用还是在您的用户进程中使用并不重要。MMU 通常以保持对齐的方式映射内存,因此使用物理内存还是虚拟内存并不重要。磁盘上的数据没有这些对齐要求,但由于您使用的存储扇区大小,其他性能特征可能适用。
4) 为什么我只能在可被 4 整除的地址中存储 32 位值?我的意思是我知道它最终只会读取 32 位,但为什么它不能从奇数地址读取 32 位?比如这里的限制是什么?
如果您从奇数地址读取 32 位,根据您的 CPU 和操作系统,会发生以下情况之一:
您通常不应该假设这些情况中的哪一个会发生。永远不要编写读取未对齐数据的代码。如果您需要读取未对齐的数据,请考虑单独读取每个字节,然后手动将字节重新组合成您想要的数据。