gro*_*taj 44
简短回答:可用地址的数量等于这些地址中的较小者:
上面的长答案和解释:
内存由字节 (B) 组成。每个字节由 8 位 (b) 组成。
1 B = 8 b
Run Code Online (Sandbox Code Playgroud)
1 GB 的 RAM 实际上是 1 GiB(千兆字节,而不是千兆字节)。区别在于:
1 GB = 10^9 B = 1 000 000 000 B
1 GiB = 2^30 B = 1 073 741 824 B
Run Code Online (Sandbox Code Playgroud)
无论 CPU 机器字有多大,内存的每个字节都有自己的地址。例如。Intel 8086 CPU 是 16 位的,它按字节寻址内存,现代 32 位和 64 位 CPU 也是如此。这就是第一个限制的原因——地址不能多于内存字节。
内存地址只是 CPU 必须从内存的开头跳过才能到达它正在寻找的字节数。
现在您必须知道 32 位实际上意味着什么。正如我之前提到的,它是一个机器字的大小。
机器字是 CPU 用来保存数字(在 RAM、缓存或内部寄存器中)的内存量。32 位 CPU 使用 32 位(4 个字节)来保存数字。内存地址也是数字,因此在 32 位 CPU 上,内存地址由 32 位组成。
现在想一想:如果你有一位,你可以在上面保存两个值:0 或 1。再加一位,你有四个值:0、1、2、3。在三个位上,你可以保存八个值: 0, 1, 2... 6, 7. 这实际上是一个二进制系统,它的工作原理是这样的:
Decimal Binary
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
Run Code Online (Sandbox Code Playgroud)
它的工作原理与通常的加法完全一样,但最大数字是 1,而不是 9。十进制 0 是0000
,然后加 1 得到0001
,再加一得到0010
。这里发生的事情就像有小数09
并加一个:你把 9 改为 0 并增加下一个数字。
从上面的示例中,您可以看到始终有一个最大值可以保留在具有恒定位数的数字中 - 因为当所有位均为 1 并且您尝试将值增加 1 时,所有位都将变为 0,从而破坏数字。它被称为整数溢出,会导致许多令人不快的问题,对用户和开发人员来说都是如此。
11111111 = 255
+ 1
-----------
100000000 = 0 (9 bits here, so 1 is trimmed)
Run Code Online (Sandbox Code Playgroud)
最大可能的数字总是 2^N-1,其中 N 是位数。正如我之前所说,内存地址是一个数字,它也有一个最大值。这就是为什么机器字的大小也是可用内存地址数量的限制 - 有时您的 CPU 无法处理足够大的数字来寻址更多内存。
因此,在 32 位上,您可以保留 0 到 2^32-1 之间的数字,即 4 294 967 295。它比 1 GB RAM 中的最大地址还多,因此在您的特定情况下,RAM 数量将成为限制因素。
32 位 CPU 的 RAM 限制理论上为 4 GB (2^32),而 64 位 CPU 的 RAM 限制为 16 EB(艾字节,1 EB = 2^30 GB)。换句话说,64 位 CPU 可以处理整个 Internet... 200 次 ;)(由WolframAlpha估计)。
但是,在实际操作系统中,32 位 CPU 可以处理大约 3 GiB 的 RAM。那是因为操作系统的内部架构 - 一些地址被保留用于其他目的。您可以在 Wikipedia 上阅读有关此所谓3 GB 障碍的更多信息。您可以使用Physical Address Extension解除此限制。
说到内存寻址,有几件事我要提一下:虚拟内存、分段和分页。
正如@Daniel R Hicks 在另一个答案中指出的那样,操作系统使用虚拟内存。这意味着应用程序实际上并不在实际内存地址上运行,而是在操作系统提供的内存地址上运行。
这种技术允许操作系统将一些数据从 RAM 移动到所谓的页面文件 (Windows) 或交换 (*NIX)。HDD 比 RAM 慢几个数量级,但对于很少访问的数据来说这不是一个严重的问题,它允许操作系统为应用程序提供比您实际安装的更多的 RAM。
到目前为止我们所谈论的称为平面寻址方案。
分页是另一种寻址方案,它允许寻址更多内存,而您通常可以在平面模型中使用一个机器字来寻址。
想象一本书充满了 4 个字母的单词。假设每页有 1024 个数字。要寻址一个数字,您必须知道两件事:
现在这正是现代 x86 CPU 处理内存的方式。它分为 4 KiB 页(每页 1024 个机器字),这些页有编号。(实际上页面也可以是 4 MiB 大或带有PAE 的2 MiB )。当您想寻址内存单元时,您需要该页中的页码和地址。请注意,每个内存单元都由一对数字引用,这不是分段的情况。
嗯,这与分页非常相似。它用于 Intel 8086,仅举一个例子。地址组现在称为内存段,而不是页。不同之处在于段可以重叠,而且它们确实重叠了很多。例如,在 8086 上,大多数存储单元可从 4096 个不同的段中获得。
一个例子:
假设我们有 8 个字节的内存,除了第 4 个字节等于 255 之外,所有字节都保持为零。
平面内存模型图示:
_____
| 0 |
| 0 |
| 0 |
| 255 |
| 0 |
| 0 |
| 0 |
| 0 |
-----
Run Code Online (Sandbox Code Playgroud)
具有 4 字节页面的分页内存示意图:
PAGE0
_____
| 0 |
| 0 |
| 0 | PAGE1
| 255 | _____
----- | 0 |
| 0 |
| 0 |
| 0 |
-----
Run Code Online (Sandbox Code Playgroud)
4 字节段移位 1 的分段内存示意图:
SEG 0
_____ SEG 1
| 0 | _____ SEG 2
| 0 | | 0 | _____ SEG 3
| 0 | | 0 | | 0 | _____ SEG 4
| 255 | | 255 | | 255 | | 255 | _____ SEG 5
----- | 0 | | 0 | | 0 | | 0 | _____ SEG 6
----- | 0 | | 0 | | 0 | | 0 | _____ SEG 7
----- | 0 | | 0 | | 0 | | 0 | _____
----- | 0 | | 0 | | 0 | | 0 |
----- ----- ----- -----
Run Code Online (Sandbox Code Playgroud)
如您所见,第 4 个字节可以通过四种方式寻址:(从 0 开始寻址)
它总是同一个记忆单元。
在现实生活中,段被移位超过 1 个字节(对于 8086,它是 16 个字节)。
分段的不好之处在于它很复杂(但我想您已经知道了;)好的地方在于您可以使用一些巧妙的技术来创建模块化程序。
例如,您可以将某个模块加载到一个段中,然后假设该段比实际小(刚好足以容纳该模块),然后选择第一个不与该伪较小的段重叠的段并加载下一个模块, 等等。基本上你通过这种方式得到的是可变大小的页面。
归档时间: |
|
查看次数: |
120807 次 |
最近记录: |