简体   繁体   English

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

[英]Can a 32-bit processor really address 2^32 memory locations?

I feel this might be a weird/stupid question, but here goes... 我觉得这可能是一个奇怪/愚蠢的问题,但是这里......

In the question Is NULL in C required/defined to be zero? 在问题中,C中的NULL是否需要/定义为零? , it has been established that the NULL pointer points to an unaddressable memory location, and also that NULL is 0 . ,已经确定NULL指针指向不可寻址的内存位置,并且NULL也是0

Now, supposedly a 32-bit processor can address 2^32 memory locations. 现在,据称32位处理器可以处理2^32内存位置。

2^32 is only the number of distinct numbers that can be represented using 32 bits. 2^32只是可以使用32位表示的不同数字的数量。 Among those numbers is 0 . 其中数字是0 But since 0 , that is, NULL , is supposed to point to nothing, shouldn't we say that a 32-bit processor can only address 2^32 - 1 memory locations (because the 0 is not supposed to be a valid address)? 但是,因为0 ,即NULL ,应该指向什么,我们不应该说32位处理器只能处理2^32 - 1内存位置(因为0不应该是有效地址) ?

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

the NULL pointer points to an unaddressable memory location NULL指针指向不可寻址的内存位置

This is not true. 这不是真的。 From the accepted answer in the question you linked: 从您链接的问题中接受的答案:

Notice that, because of how the rules for null pointers are formulated, the value you use to assign/compare null pointers is guaranteed to be zero, but the bit pattern actually stored inside the pointer can be any other thing 请注意,由于如何制定空指针的规则,用于分配/比较空指针的值保证为零,但实际存储在指针内的位模式可以是任何其他东西

Most platforms of which I am aware do in fact handle this by marking the first few pages of address space as invalid. 我所知道的大多数平台实际上通过将地址空间的前几页标记为无效来处理此问题。 That doesn't mean the processor can't address such things; 这并不意味着处理器无法解决这些问题; it's just a convenient way of making low values a non valid pointer. 它只是一种方便的方法,使低值成为无效指针。 For instance, several Windows APIs use this to distinguish between a resource ID and a pointer to actual data; 例如,几个Windows API使用它来区分资源ID和指向实际数据的指针; everything below a certain value (65k if I recall correctly) is not a valid pointer, but is a valid resource ID. 低于某个值的所有内容(如果我没记错的话,为65k)不是有效指针,而是有效的资源ID。

Finally, just because C says something doesn't mean that the CPU needs to be restricted that way. 最后,仅仅因为C说某事并不意味着CPU需要以这种方式受到限制。 Sure, C says accessing the null pattern is undefined -- but there's no reason someone writing in assembly need be subject to such limitations. 当然,C表示访问null模式是未定义的 - 但是没有理由在汇编中进行编写需要受到这些限制。 Real machines typically can do much more than the C standard says they have to. 真正的机器通常可以做得比C标准所说的要多得多。 Virtual memory, SIMD instructions, and hardware IO are some simple examples. 虚拟内存,SIMD指令和硬件IO是一些简单的例子。

It depends upon the operating system. 这取决于操作系统。 It is related to virtual memory and address spaces 它与虚拟内存地址空间有关

In practice (at least on Linux x86 32 bits), addresses are byte "numbers"s, but most are for 4-bytes words so are often multiple of 4. 在实践中(至少在Linux x86 32位上),地址是字节“数字”s,但大多数是4字节字,因此通常是4的倍数。

And more importantly, as seen from a Linux application , only at most 3Gbytes out of 4Gbytes is visible. 更重要的是, 从Linux应用程序可以看出 ,4G字节中只有大多数 3G字节可见。 a whole gigabyte of address space (including the first and last pages, near the null pointer) is unmapped. 未映射整个千兆字节的地址空间(包括空指针附近的第一页和最后一页)。 In practice the process see much less of that. 在实践中,这个过程看起来更少。 See its /proc/self/maps pseudo-file (eg run cat /proc/self/maps to see the address map of the cat command on Linux). 请参阅其/proc/self/maps伪文件(例如,运行cat /proc/self/maps以查看Linux上cat命令的地址映射)。

First, let's note the difference between the linear address (AKA the value of the pointer) and the physical address. 首先,让我们注意线性地址(AKA指针的值)和物理地址之间的区别。 While the linear address space is, indeed, 32 bits (AKA 2^32 different bytes), the physical address that goes to the memory chip is not the same. 虽然线性地址空间实际上是32位(AKA 2 ^ 32个不同的字节),但到存储器芯片的物理地址并不相同。 Parts ("pages") of the linear address space might be mapped to physical memory, or to a page file, or to an arbitrary file, or marked as inaccessible and not backed by anything. 线性地址空间的部分(“页面”)可能会映射到物理内存,或页面文件,或任意文件,或标记为不可访问且不受任何内容支持。 The zeroth page happens to be the latter. 第零页恰好是后者。 The mapping mechanism is implemented on the CPU level and maintained by the OS. 映射机制在CPU级别上实现并由OS维护。

That said, the zero address being unaddressable memory is just a C convention that's enforced by every protected-mode OS since the first Unices. 也就是说,零地址是不可寻址的内存只是自第一个Unices以来每个保护模式OS强制执行的C约定。 In MS-DOS-era real-mode operaring systems, null far pointer (0000:0000) was perfectly addressable; 在MS-DOS时代的实模式歌剧系统中,null far指针(0000:0000)是完全可寻址的; however, writing there would ruin system data structures and bring nothing but trouble. 但是,在那里写文件会破坏系统数据结构并带来麻烦。 Null near pointer (DS:0000) was also perfectly accessible, but the run-time library would typically reserve some space around zero to protect from accidental null pointer dereferencing. 空指针(DS:0000)也可以完全访问,但运行时库通常会在零周围保留一些空间,以防止意外的空指针解除引用。 Also, in real mode (like in DOS) the address space was not a flat 32-bit one, it was effectively 20-bit. 此外,在实模式下(如DOS),地址空间不是32位的扁平空间,实际上是20位。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM