为什么在16位机器上使用20位地址空间只能访问1MB而不是2MB?

7

好的,这个问题听起来很简单,但却让我感到惊讶。在古老的时代,1兆字节是巨大的内存量,英特尔正在尝试找出如何使用16位来访问1兆字节的内存。他们想出了使用段和偏移地址值生成20位地址的方法。

现在,20位可以寻址2^20 = 1,048,576个位置。假设我们每个地址位置访问1个字节,那么我们得到1,048,576/(1024*1024) = 2^20/2^20兆字节 = 1兆字节。好的,明白了。

混淆出现在这里,我们在古老的8086中有16位数据总线,每次可以访问2个字节而不是1个,这相当于20位地址能够访问总共2兆字节的数据,对吗?为什么我们假设每个地址只存储1个字节,而数据总线是2个字节宽度呢?我在这里感到困惑。


对于开发人员而言,一个地址可以指向任意大小的内存块,是吗?我认为,处理器模型需要一个最小的可加载到寄存器(字节,对吧?)的块来唯一寻址。 - mikalai
也许,在这里你不应该涉及总线。我怀疑你计算了类似“带宽”的东西:拥有2字节宽的总线,你可以传输比1字节宽的总线多两倍的数据。但是总线与寻址无关。你应该能够寻址某个特定的字节。例如,你有地址#0指向单词“AB”,#1指向“CD”。如何告诉CPU“将字节'B'加载到AX”?如果我想寻址一个双字或四字呢? - mikalai
8086 可以说是一种过渡性的混合处理器,旨在擅长于全新的 16 位代码和可能被移植到它上面的当时流行的 8 位代码。这就是为什么它具有完整的 8 位指令集的原因。此外,英特尔还推出了一个名为 8088 的变体,它具有 8 位总线而不是 16 位,这将允许人们制造使用当时普遍组件的更便宜的机器。IBM 5150(最初的 PC)配备了 8088 而不是 8086。因此,它需要支持 8 位寻址,无论其最佳字长(16 位)如何。 - Euro Micelli
仅回答你的问题:因为8086使用8位寻址,而不是16位。即使使用具有完整16位数据总线的8086(与具有8位总线的8088相比),地址也指向单个字节,而不是16位字。 - Euro Micelli
哇,终于看到了。如果我们使用16位数据总线和16位寻址来仅寻址单个字节,而数据总线可以一次传输2个字节,这确实有点不合理。 - quantum231
显示剩余2条评论
2个回答

5
当尝试理解这个问题时,考虑总线非常重要。这可能更多是一个电气问题而不是软件问题,但以下是答案:
对于8086,在从ROM读取时,最低有效地址线(A0)未使用,直接将地址线的数量减少到19。
在CPU需要从奇地址读取16位(例如0x3和0x4字节)的情况下,它实际上会执行两次16位读取:一次从0x2,一次从0x4,并丢弃0x2和0x5字节。
对于8位ROM读取,总线上的读取仍然为16位,但不需要的字节会被丢弃。
但是对于RAM,有时只需要写入单个字节,这会变得更加复杂。处理器上有一个名为BHE#(总线高使能)的额外输出信号。 A0和BHE#的组合用于确定写入是8位还是16位,以及其是否为奇或偶地址。
了解这两个信号是回答您的问题的关键。简单地说:
8位偶数访问:A0关闭,BHE#关闭
8位奇数访问:A0打开,BHE#打开
16位访问(必须为偶数):A0关闭,BHE#打开
我们不能使A0为ON且BHE#为OFF的总线周期,因为对总线的偶字节进行奇访问是没有意义的。
将其与您的原始理解联系起来:在内存设备的情况下,您完全正确。1兆字节的16位内存芯片确实只有19条地址线,对于该芯片,16位是一个字节,并且实际上它们没有物理A0地址输入。
...几乎。可写16位内存设备具有两个额外信号(BHE#和BLE#),它们分别连接到CPU的BHE#和A0。这样,当8位访问正在进行时,它们知道要忽略总线的一部分,使它们成为混合的8/16位设备。ROM芯片没有这些信号。
对于硬件不了解的人来说,这是一个相当复杂的领域,对于性能考虑和混合8和16位硬件的大型系统而言,它确实变得非常复杂。
这在8086数据手册中详细说明。

我现在为我的旧答案感到羞愧:D - Alireza

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接