32位处理器真的可以处理2 ^ 32个内存位置吗?

我觉得这可能是一个奇怪/愚蠢的问题,但是这里……

在问题中,C中的NULL是否需要/定义为零? ,已经确定NULL指针指向不可寻址的内存位置,并且NULL也是0

现在,据称32位处理器可以处理2^32内存位置。

2^32只是可以使用32位表示的不同数字的数量。 其中数字是0 。 但是,因为0 ,即NULL ,应该指向什么,我们不应该说32位处理器只能处理2^32 - 1内存位置(因为0不应该是有效地址) ?

NULL指针指向不可寻址的内存位置

这不是真的。 从您链接的问题中接受的答案:

请注意,由于如何制定空指针的规则,用于分配/比较空指针的值保证为零,但实际存储在指针内的位模式可以是任何其他东西

我所知道的大多数平台实际上通过将地址空间的前几页标记为无效来处理此问题。 这并不意味着处理器无法解决这些问题; 这只是使低值成为无效指针的便捷方式。 例如,几个Windows API使用它来区分资源ID和指向实际数据的指针; 低于某个值的所有内容(如果我没记错的话,为65k)不是有效指针,而是有效的资源ID。

最后,仅仅因为C说某些东西并不意味着CPU需要以这种方式受到限制。 当然,C表示访问null模式是不确定的 – 但是没有理由在汇编中写一些人需要受到这样的限制。 真正的机器通常可以做得比C标准所说的要多得多。 虚拟内存,SIMD指令和硬件IO是一些简单的例子。

如果32位处理器可以处理2 ^ 32个内存位置,那么这只意味着该架构上的C指针可以引用2 ^ 32-1个位置加上NULL

首先,让我们注意线性地址(AKA指针的值)和物理地址之间的区别。 虽然线性地址空间确实是32位(AKA 2 ^ 32个不同的字节),但到存储器芯片的物理地址并不相同。 线性地址空间的部分(“页面”)可能会映射到物理内存,或页面文件,或任意文件,或标记为不可访问且不受任何内容支持。 第零页恰好是后者。 映射机制在CPU级别上实现并由OS维护。

也就是说,零地址是不可寻址的内存只是自第一个Unices以来每个保护模式OS强制执行的C约定。 在MS-DOS时代的实模式歌剧系统中,null far指针(0000:0000)是完全可寻址的; 但是,在那里写文件会破坏系统数据结构并带来麻烦。 空指针(DS:0000)也可以完全访问,但运行时库通常会在零周围保留一些空间以防止意外的空指针解除引用。 此外,在实模式下(如在DOS中),地址空间不是32位的扁平空间,实际上是20位。

这取决于操作系统。 它与虚拟内存和地址空间有关

在实践中(至少在Linux x86 32位上),地址是字节“数字”s,但大多数是4字节字,因此通常是4的倍数。

更重要的是, 从Linux应用程序可以看出 ,4G字节中只有最多 3G字节可见。 未映射整个千兆字节的地址空间(包括空指针附近的第一页和最后一页)。 在实践中,这个过程看起来要少得多。 查看其/proc/self/maps伪文件(例如,运行cat /proc/self/maps以查看Linux上cat命令的地址映射)。