如果32位处理器可以处理大约4 GiB的RAM(即字节),为什么我的Arduino Mega 2560具有8 KiB的SRAM,如果是8位处理器则允许它仅处理256个字节(2 ^ 8)?还是我阅读以下页面有误?
如果32位处理器可以处理大约4 GiB的RAM(即字节),为什么我的Arduino Mega 2560具有8 KiB的SRAM,如果是8位处理器则允许它仅处理256个字节(2 ^ 8)?还是我阅读以下页面有误?
Answers:
大多数8位CPU都有16位地址总线,允许它们寻址64kbyte,正是因为256个字节确实不足以完成很多工作!这仅表示每次需要加载地址时,它们都需要加载两个字节而不是一个字节。考虑到它们的大小,速度稍慢但可以忍受。
(是的,有很多例外,大多数例外是在64k变得太小时开发的,但是我们在这里谈论的是基本思想)。
的地址总线和数据总线是分离的,这样他们可以具有不同的尺寸。对于任何特定的地址总线大小,有很多技术可以寻址比寄存器位宽更多的存储器
最常见的方法是以某种方式增加地址总线的宽度
使用多个寄存器作为地址
X
,Y
和Z
数据寻址寄存器,以允许的最大RAM 64KB。依次将它们与RAMPX
,配对RAMPY
,RAMPZ
可以访问更大版本的更高RAM地址。SPH
除了SPL
具有超过256个字节的RAM 1的变量外,它还具有堆栈指针的高字节。H
&L
,B
&和&之类的寄存器对C
,它们可以一起用作16位地址寄存器D
E
使用大于自然大小的单个大特殊寄存器进行寻址
对地址的高位使用特殊的寄存器。当寻址某些存储器时,默认情况下,地址的低8位将取自8位微控制器上的8位立即数或8位寄存器,而高位将被其他地址寄存器的值代替。
call
或goto
指令时,立即数指示地址的8位或9位低位,其余部分取自当前程序计数器。因此,访问当前段附近的任何内容仅需使用一条指令,而其他地址将需要2条指令(以设置高位)。PC
同时无条件跳转。实现此目的的另一种方法是内存存储。这是一种有用的方法,如今仍在某些体系结构中使用。在此模型中,内存分为多个存储体。每次您只能寻址特定的银行。通常会有随时可见的全局存储区或地址范围,但是对于其他部分,您必须在需要时切换存储区。
还有一种不太常见的技术,但是可以在Intel 8051中找到。作为具有8位数据地址的微控制器,它最多可以具有256个地址。一半的空间(高半部分)用于特殊功能寄存器(SFR),从而将可寻址的实际RAM限制为仅128个字节。但是,现代8051系列的制造商发现了一种巧妙的方法,可以通过分离内存访问来克服这一问题。直接寻址将访问SFR,而间接寻址将通过寄存器访问RAM的高端,这意味着现在您有256 + 128 = 384个可寻址字节。
1 https://zh.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位偏移量足以寻址213个字节的ROM。)
根据需要,还具有其他内存寻址功能,以访问可用资源:
- 数据地址空间大于256字节(RAM≥256字节)的型号具有16位堆栈指针,其高半部分位于SPH寄存器中。
- ROM> 8 KiB的型号增加了2字(22位)JUMP和CALL指令。(如果跳过指令后跟2字指令,则某些早期模型会出现错误。)
- ROM> 64 KiB的型号添加了ELPM指令和相应的RAMPZ寄存器。LPM指令将ROM地址零扩展到Z;ELPM指令在RAMPZ寄存器前加高位。这与更通用的LPM指令不同。存在只有ELPM的零操作数形式的“经典”模型(ATmega103和at43usb320)。当有自动递增功能(大多数型号)时,它将更新整个24位地址,包括RAMPZ。
- ROM> 128 KiB的(罕见)型号具有3字节程序计数器。子例程调用和返回使用额外的堆栈空间字节,有一个新的EIND寄存器为工业跳转和调用提供了附加的高位,还有新的扩展指令EIJMP和EICALL,它们使用EIND:Z作为目标地址。(以前的IJMP和ICALL指令使用零扩展Z。)
- (稀有)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步进行:
读取字节到累加器的传输将与下一条指令的获取重叠。此外,对于许多操作,如果步骤3没有生成进位,则步骤4将读取正确的地址,并且执行可以直接从步骤4跳到下一条指令,而绕过步骤5。
如果检查一下操作顺序,就会注意到,在大多数情况下(尽管未显示),小端架构比大端架构具有明显的优势,尽管ALU需要一个周期来执行另外,可以从计算的地址读取一个字节而无需等待ALU结果,因为通常提取的高字节将是目标操作数的高字节。在具有8位ALU的big-endian机器上,索引加载将至少花费5个周期(因为地址的下半部分要到步骤3才会被读取,因此将在步骤4中进行计算)。
数据总线线(引脚)和地址线(引脚)是完全分开的。简而言之,数据总线线确定一次可传输的最大位数(并存储在存储器中),而地址线则确定可以选择的最大存储“单元”数。
32位x86 CPU不能处理超过4GB的RAM主要是一种营销手段。我记得某个地方在奔腾4 CPU上有A33-34引脚。
我将专门针对您提到的AVR控制器回答此问题。基本原理对于许多其他8位架构也适用。
AVR是8位内核。这意味着它们具有8位寄存器。但是,8位不足以访问可用的内存量。因此,AVR内核能够使用一组特定的寄存器,将其组合为16位指针寄存器。寄存器r30和r31(也别名为ZL和ZH)就是一个示例。它们一起形成Z指针。
在汇编中,读取地址0x1234的字节看起来像这样:
ldi ZL, 0x34 ; Load r30 (ZL) with low byte of address
ldi ZH, 0x12 ; Load r31 (ZH) with high byte of address
ld r16, Z ; Load byte to r16
AVR系列具有3个寄存器对可用于此目的。它们经过专门设计在硬件中以允许此类操作。
当使用像C这样的高级语言进行编程时,编译器会处理这些问题。
注意:某些AVR甚至支持大于64k的内存。这些控制器具有特殊的功能寄存器,其中的其他位地址在访问之前被写入。因此,该地址包含以下位(MSB至LSB):
特殊功能寄存器(通常为1个字节),ZH(8位),ZL(8位)。
处理器的“位宽”建立了处理器可以处理的最大RAM量的概念是计算中最普遍的神话之一。实际上,行业历史上充斥着没有这种关系的CPU。
HP 21MX,HP 1000:16位CPU,内存为16 MB
PDP-11:16位CPU,内存为4 MB
VAX-11 / 780:32位CPU,内存为512 MB
等等等