8 位处理器如何支持超过 256 字节的 RAM?

电器工程 Arduino 微控制器 微处理器 内存
2022-01-07 14:43:26

如果32位处理器可以处理大约 4 GiB 的 RAM(即\$2^{32} = 4 294 967 296\$)字节,为什么我的 Arduino Mega 2560 有 8 KiB 的 SRAM,如果是8位处理器允许它只处理 256 个字节(\$2^8\$)?还是我读错了以下页面?

http://www.atmel.com/devices/atmega2560.aspx?tab=parameters

4个回答

大多数 8 位 CPU 都有 16 位地址总线,允许它们寻址 64kbytes,正是因为 256 字节真的不足以做很多事情!这只是意味着他们每次需要加载一个地址时都需要加载两个字节而不是一个字节。考虑到它们的大小,速度稍慢但可以忍受。

(是的,有很多例外,主要是在 64k 变得太小时时开发的,但我们在这里讨论的是基本思想)。

地址总线数据总线是分开的,因此它们可能具有不同的大小对于任何特定的地址总线大小,有很多技术可以寻址比寄存器位宽更多的内存

  • 最常见的方法是以某种方式增加地址总线宽度

    • 使用多个寄存器作为地址

      • AVR有 R26..R31 可以配对成 16 位X数据寻址寄存器允许最大 64KB 的 RAM。反过来,它们可以与,配对以在更大的版本中访问更高的 RAM 地址。除了具有超过 256 字节 RAM 1的变体之外,它还具有堆栈指针的高字节YZRAMPXRAMPYRAMPZSPHSPL
      • Intel 8080Zilog Z80是 8 位 CPU,但它们具有像H& LB& 和C&D这样的寄存器对E,可以一起用作 16 位地址寄存器
    • 使用大于自然大小的单个大型特殊寄存器进行寻址

      • Intel 8051是一个8 位微控制器,即它有8 位数据地址。但是,它使用 16 位指令地址并具有 2 个 16 位寄存器:PC 和 DPTR,用于在指令空间中寻址。
      • AVR有一个 16 或 22 位 PC 寄存器
    • 对地址的高位部分使用特殊寄存器在寻址某些存储器时,默认情况下,地址的低 8 位将取自 8 位立即数或 8 位微控制器上的 8 位寄存器,而高位将被其他地址寄存器的值替换。

      • 这种情况的一个特殊情况是分段内存,由16 位 x86使用。在这种技术中,内存被分成多个大小为 64KB(2 16字节)的段。默认情况下,正常访问在单个段内,因此它们可以使用 16 位地址作为近端数据距离较远的数据必须通过段值专门寻址,因此必须使用 2 个寄存器进行远寻址。
      • 另一个例子是PIC 微控制器,其基线和中档系列可能具有 13 或 14 位地址。使用callorgoto指令时,地址的低 8 位或 9 位由立即数指示,其余的取自当前程序计数器。因此,访问当前段周围不远处的任何内容仅使用 1 条指令,而进一步的地址将需要 2 条指令(设置高位)。
      • 另一个例子是MIPS架构,它还结合了低 26 位立即地址和高 6 位,PC同时无条件跳转。
  • 实现此目的的另一种方法是内存银行这是当今某些架构中仍在使用的有用方法。在这个模型中,内存被划分为多个bank每次您只能针对特定的银行。通常有一个全局银行或地址范围始终可见,但对于其他部分,您必须在需要时切换银行。

    • Intel 8051对寄存器使用内存库。它有 32 个寄存器,但一次只能看到其中的 8 个。
    • x86 PAEARM LPAE,较大的物理地址空间映射到较小的虚拟地址空间
    • 另一个应用程序是 Windows 上的Address Windowing Extensions,32 位 x86 应用程序可以在 PAE 模式下使用它来访问超过 2/3GB 的内存。它不完全像微控制器上的内存库,但可以看作是这样,因为大地址范围可以认为是小窗口/库,它足够小以适合应用程序的地址空间。如果应用程序需要在某个窗口中使用数据,它将将该窗口映射到其当前地址空间。
    • 由于可寻址内存的范围有限,DOS 还具有某些类型的存储库切换,例如扩展内存扩展内存。
  • 还有一种不太常见的技术,但可以在Intel 8051中找到。作为一个 8 位数据地址的微控制器,它最多可以有 256 个地址。一半空间(高位部分)用于特殊功能寄存器 ( SFR ),将可寻址的实际 RAM 限制为仅 128 个字节。然而,现代 8051 系列的制造商找到了一种巧妙的方法,通过分离内存访问来克服这个问题直接寻址将访问SFR,而间接寻址虽然寄存器将访问 RAM 的高部分,这意味着现在您有 256 + 128 = 384 个可寻址字节。


1 https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set#Memory_addressing_instructions

最小的内核有≤256字节的数据地址空间(意味着在I/O端口和其他保留地址被移除后≤128字节的RAM)和≤8192字节(8 KiB)的程序ROM。它们只有一个 8 位堆栈指针(在 SPL 中),并且仅支持 12 位相对跳转/调用指令 RJMP/RCALL。(因为 AVR 程序计数器计数 16 位字,而不是字节,所以 12 位偏移量足以寻址 ROM 的 213 个字节。)

根据需要提供额外的内存寻址功能以访问可用资源:

  1. 具有 >256 字节数据地址空间(≥256 字节 RAM)的模型有一个 16 位堆栈指针,其高半部分在 SPH 寄存器中。
  2. 具有 >8 KiB ROM 的型号添加了 2 字(22 位)JUMP 和 CALL 指令。(如果跳过指令后跟 2 字指令,一些早期模型会出现错误。)
  3. 具有 >64 KiB ROM 的模型添加了 ELPM 指令和相应的 RAMPZ 寄存器。LPM 指令对 Z 中的 ROM 地址进行零扩展;ELPM 指令在 RAMPZ 寄存器前添加高位。这与更一般的 LPM 指令不同。存在只有零操作数形式的 ELPM(ATmega103 和 at43usb320)的“经典”模型。当自动递增可用时(大多数型号),它会更新整个 24 位地址,包括 RAMPZ。
  4. (罕见)具有 >128 KiB ROM 的型号具有 3 字节的程序计数器。子程序调用和返回使用一个额外的堆栈空间字节,有一个新的 EIND 寄存器为间接跳转和调用提供额外的高位,还有新的扩展指令 EIJMP 和 EICALL,它们使用 EIND:Z 作为目标地址。(前面的 IJMP 和 ICALL 指令使用零扩展 Z。)
  5. RAM 地址空间大于 64 KiB 的(罕见)型号通过 RAMPX、RAMPY、RAMPZ 和 RAMPD 寄存器扩展了 16 位 RAM 寻址限制。它们为分别使用 X、Y 或 Z 寄存器对或直接寻址指令 LDS/STS 的寻址模式提供额外的高位。与 ROM 访问不同,没有明显的“扩展”指令;而是无条件地使用 RAMP 寄存器。

几乎所有 8 位处理器都具有从低位部分和高位部分形成 16 位地址的能力。在包括原始 8080 在内的某些处理器上,有专门用于保存地址的上部和下部的寄存器(尽管从程序员的角度来看,可能有一些寄存器,例如 8080 的堆栈指针,它们不提供单独寻址它们的指令)。在其他一些处理器中,没有专门用于地址的上半部分或下半部分的寄存器,但地址是“即时”组装的。例如,在 6502 上,指令“LDA $1234,X”将通过将 $1234 添加到 8 位 X 寄存器 [假设它包含 $F0] 形成的地址加载累加器。该指令的执行将分 4 或 5 个步骤进行:

  1. 从上一条指令(如果有)完成寄存器写入并加载操作码($BD)
  2. 在解码指令时获取操作码 ($34) 之后的第一个操作数字节
  3. 获取第二个操作数字节($12),同时将先前获取的字节添加到 X 寄存器
  4. 在通过将第二个操作数字节连接到 ALU 结果形成的地址处读取内存 [即 $1224]。将第二个操作数字节送入 ALU 以加零或加一,具体取决于先前的加法是否产生进位
  5. 通过用 ALU 结果替换上半部分形成的地址读取内存 [$1334]

读取字节到累加器的传输将与下一条指令的获取重叠。此外,对于许多操作,如果第 3 步没有产生进位,第 4 步将读取正确的地址,执行可以直接从第 4 步跳到下一条指令,绕过第 5 步。

如果检查操作序列,就会注意到小端架构比大端架构具有明显优势,在大多数情况下(尽管不是显示的情况),即使 ALU 需要一个周期来执行另外,可以从计算地址读取一个字节而无需等待 ALU 结果,因为通常获取的高字节将是目标操作数的高字节。在具有 8 位 ALU 的大端机器上,索引加载至少需要 5 个周期(因为地址的下半部分直到步骤 3 才会被读取,因此将在步骤 4 中计算)。

数据总线(引脚)和地址线(引脚)是完全分开的。简而言之,数据总线决定了一次可以传输一个(并存储在内存上)的最大位数,而地址线决定了可以选择的内存“单元”的最大数量。

32 位 x86 CPU 无法处理超过 4GB 的 RAM,这主要是一种营销问题。我记得某处 Pentium 4 CPU 上有 A33-34 引脚。