我最近注意到 Windows 发出长鸣声,这可能是 BSOD 错误代码中 1a 的内存问题,我运行 memtest 并发现了如下所示的错误地址。
2024-01-24 14:20:11 - [Data Error] Test: 13, CPU: 0, Address: 293B98920, Expected: 5F0DF0A5, Actual: 5F8DF0A5
2024-01-24 14:18:53 - [Data Error] Test: 13, CPU: 0, Address: 293B98920, Expected: D70BA8A2, Actual: D78BA8A2
2024-01-24 14:17:20 - [Data Error] Test: 13, CPU: 0, Address: 293B98920, Expected: 1F1F39AC, Actual: 1F9F39AC
2024-01-24 14:17:05 - [Data Error] Test: 13, CPU: 0, Address: 293B98920, Expected: 50039BF9, Actual: 50839BF9
我有 ~12GB 的 ram,所以地址高达 31F000000,即 12784MB,但它还显示了另外 4 个字节,它们是这些地址中存储的信息,这是如何工作的?有13.404.995.584个地址,每个地址存储4个字节?
尽管内存是字节寻址的,但程序(甚至 CPU)通常以 16 位(2 字节)、32 位(4 字节)甚至 64 位(8 字节)来处理它单位。例如,程序可以跨 bytes 存储 32 位值
0xABC0...0xABC3
,据说该值存储在“0xABC0”(暗示了范围的其余部分)。这就是 memtest 在这里所做的事情。(即使在机器代码级别,也有指令从内存中加载 32 位宽整数作为仅指定“起始”地址的单个指令,这通常比四个单字节加载更快。时间指示。)
内存读取和写入不是“每个字节”发生的,它们是在“字边界”上对齐的。
这意味着,如果您的内存在 32 位传输上运行,那么要从
0x000F0000
(so0x000F0002
) 向上读取第三个字节,您必须向下处理到最近的 32 位边界0x000F0000
,然后传输所有四个字节以读取第三个字节。对于大多数现代系统使用的 64 位内存,您必须从内存中传输完整的 8 字节(64 位)“字”才能读取该内存区域中的单个字节。Memtest 刚刚选择了一次显示 4 个字节的默认视图,而不是 8 个字节或任何系统内存传输大小。
软件显示的内容通常是基于人们最习惯的任意选择,并且是简洁和过于冗长之间的选择。两个块
293B98920 51F22EAB
对于一个人来说更容易解析293B9892051f22eab
无论如何,您实际上无法传递
0x000F0002
到物理内存芯片。由于现代内存使用跨内存芯片组的并行数据总线,因此允许字节寻址的最低地址线被有效隐藏。通过使用 8 个芯片(或 4 个芯片,每个芯片有两个存储体),您基本上不再“看到”任何地址的最低 3 位。这 8 个芯片都将被赋予相同的地址,然后编组到内存控制器的将是一个长 64 位字,它是排列在一起的每个内存芯片的内容。
然后该 64 位字被放入处理器的寄存器中。
然后,您的处理器看到您要求的特定字节,
0x000F0002
就会检查它收到的 8 个字节,并为您提供第三个字节。这些其他字节是在处理器内存控制器处接收的,并且可能将其放入各种 CPU 缓存中,您只是不费心去读取软件中的内容。