【发布时间】:2022-10-16 07:08:33
【问题描述】:
这是我的一次考试中提出的问题,这意味着这是可能的。
问题是如果我有一个 40 位地址总线,我怎样才能只使用两个 16 位寄存器访问它的所有内存位置。传统的移位加法方法仅适用于 32 位地址总线,所以我想知道答案是什么或方法是什么。
【问题讨论】:
标签: cpu-architecture cpu-registers microprocessors address-bus
这是我的一次考试中提出的问题,这意味着这是可能的。
问题是如果我有一个 40 位地址总线,我怎样才能只使用两个 16 位寄存器访问它的所有内存位置。传统的移位加法方法仅适用于 32 位地址总线,所以我想知道答案是什么或方法是什么。
【问题讨论】:
标签: cpu-architecture cpu-registers microprocessors address-bus
如果我们可以仅将每个可能的 40 位数字存储在 32 位中,那将是一项违反逻辑的壮举,而这种技术的发明者将赢得奖项!
天真地,如果所有的都是 32 位,则无法区分 2^40 个不同的值。
不过,这似乎是一个棘手的问题。
所以,可以做的是使用 256 字节的字长,然后 32 位只需要区分每个可能的 256 字节字,它只需要 32 位。从某种意义上说,32 位将应用于 40 位地址空间的高 32 位,而其余的低 8 位将始终为零。在这样的方案中,所有内存位置都可以访问——只需要一个巨大的字长!
【讨论】:
addr<<8 来memcpy 到低地址(隐式0,或通过一个或两个16 位寄存器指定不同的方式),因此您可以获取任何数据块你想要,把它带到你可以单独获取它的字节的地方。
一个 32 位的值只有 2^32 个可能的值,但一个 40 位的地址空间有 2^40 个字节。你需要一些额外的位来自某个地方,例如提前在段库之类的东西中设置,或者在每次使用时从内存中加载。
您可以让它像 286 或 386 保护模式一样工作,其中一个 16 位寄存器索引内存中具有更大段基地址的表(GDT 或 LDT)。在实际的 386 中,最大段基数接近 32 位地址空间的顶部,但如果您真的想在不将寄存器扩大到其一小部分的情况下扩大地址空间,您可以拥有该段-base 为 40 位。
或者像 6502 那样,有一种内存间接寻址模式,可以从内存中加载更广泛的指针并使用它。在 6502 的情况下,零页,即内存的低 256 字节,可用于此目的,允许使用一个 8 位寄存器或立即数访问 65536 字节的内存,外加一个只需要存在于内存中的 16 位指针。请参阅X, Indirect addressing mode。
在不依赖内存中更宽的指针的情况下,您可以使用特殊指令将对齐的高内存块复制到可以以字节粒度正常寻址的范围。
例如copy_from_high256 dst, src1:src2 可以使用 src1:src2 作为 32 位值,左移 8 位,形成一个 256 对齐的 40 位线性地址。dst 可以使用任何常规方式指定地址或隐式目标喜欢0。您将有相应的指令以另一种方式进行复制。您可能需要对这些指令进行计数,或者期望它们循环运行。
因此,您可以获取所需的任何 256 字节对齐数据块,让软件手动将数据“分页”到/从作为后备存储的高内存中,进入它们通常可访问的地址空间,该地址空间可以通过其他一些寻址模式进行字节寻址。
这不可能是机器对所有指令的正常寻址模式,除非字长为 256 字节(2048 位)!
【讨论】: