假设您正在运行32位RISC系统。您将使用什么指令来访问64位内存地址?
在CISC指令集中,您可以使用多字指令简单地传递额外的字。例如:
1a) JMP
1b) loAddress
1c) hiAddress
鉴于RISC指令每个只有一个字,您将如何访问多字地址?
假设ALU为32位且具有进位标志。
此外,在CISC系统(例如8080)中,loAddress和hiAddress字都将存储在程序存储器中。即JMP
指令知道查看程序存储器中的下一个项目以检索loAddress
,然后检查项目以检索hiAddress
。 RISC会发生什么?
答案 0 :(得分:3)
即使在CISC上,你所描述的也很不寻常。 这不是因为它是CISC,而是因为使用的地址比寄存器更宽。这通常只在8位CPU中找到。 (虽然x86分段也有资格,间接远跳采用指向m16:32
段/偏移对的指针。或者在16位模式下,m16:16
。作为little-endian,偏移是第一个。 )在64位模式之外,jmp ptr16:32
也是可编码的,绝对段:offset作为指令流的一部分。)
通常,当您想要设计具有更大地址空间的CPU时,您还可以使寄存器更宽,以便您可以有效地处理地址。当你想通过使用大多数8位寄存器/ ALU来节省晶体管时,它只是在最低端,但是你不能将你的地址空间限制在256字节,你会发现这种设计。 / p>
即使地址大小与字大小匹配,也存在一个真正的问题。 构造任意32位(或64位)常量是一个问题,不同的ISA解决不同的方式。 ARM经常使用来自附近"文字池的PC相对负载#34;而其他人经常使用lui
或等效设置高16位而其余为零,然后ori
一个16位立即。 (通过使用移位/旋转立即数,ARM有一些简洁的技巧可以设置只有几位的immediate。)
通常在RISC上,如果需要跳远,可能需要使用多条指令在寄存器中构造地址。然后使用跳转到寄存器指令。
MIPS分支指令很有意思:它具有相对分支,它为程序计数器添加一个带有相当大范围的有符号位移,以及用新地址替换PC的低28位的绝对跳转指令。 (由26位立即左移构建,因为MIPS需要对齐指令,因此不需要存储低2位。)How to Calculate Jump Target Address and Branch Target Address?。但是当目标位置无法与目标位置到达时,您需要jr
在寄存器中包含地址。
x86-64也缺少64位相对跳转指令。如果您需要远离+ -2GiB跳跃(不像新的CS段那样far
),则需要间接跳转。正常跳转/分支指令仍然使用rel8
或rel32
位移,保持机器代码紧凑。唯一可以采用64位立即数的指令是mov
- 要注册。正常的代码模型假设同一个库或可执行文件中的所有代码都在2GiB之内,因此链接器将能够填充32位位移。
我唯一知道程序计数器比寄存器更宽的RISC ISA是AVR,一个带8位寄存器的微控制器。 它可以将寄存器对视为16位地址,其PC为16位。它IJMP
(indirect jump) instruction设置PC = Z(其中Z
是一对8位寄存器)。在具有22位程序计数器而不是16位的AVR上,它将PC(21:16)
归零。
EIJMP(扩展间接跳转)从I / O空间获取EIND寄存器用于PC的高位,低位仍然来自Z
。
AVR指令几乎都是2个字节长,但有些版本的a 4-byte jmp
instruction为跳转目标需要0..4M绝对地址。
具有32位寄存器的主流RISC机器也具有32位程序计数器和虚拟地址空间。 (拥有超过4GiB的物理内存是可能的,但你无法在一个过程中同时映射所有内容)。
它们中的大多数在设计中都是以字为导向的,所以他们只需要jr reg
(MIPS)或任何等效的分支到任何可能的地址,因为它适合一个寄存器。这是RISC字面意义上降低的复杂性的一部分。
在MIPS,SPARC或PowerPC等普通RISC上, 64位地址仅在64位ISA扩展中可用,其中有64位整数寄存器。因此,您使用MIPS ld $2, 0($3)
等指令使用$3
作为64位基址进行64位(双字)加载。见MIPS-IV ISA manual。 (MIPS-III添加了64位扩展,带有ld
和daddu
等指令。显然MIPS-I使其许多操作码编码空间未使用,因此新的操作码有足够的空间来做完整的64位ALU操作。)
某些32位CPU添加了扩展以支持大型物理地址,而不会增加虚拟地址空间。例如,x86的PAE定义了一个具有36位物理地址的新页表格式。但即使使用分段,单个进程也无法同时处理超过4GiB的虚拟内存。 (x86段基+偏移在 virt-> phys转换之前发生,创建一个32位线性地址。因此它对于线程本地存储仍然有用,例如{{1} }是一个不同的线性地址,取决于该线程的[fs:0]
段基数。)
PA-RISC有#34;空间寄存器"它提供了扩展寻址。 32位PowerPC具有段寄存器,这些寄存器是根据16项表(提供52位虚拟地址空间)中有效地址的最高4位选择的。对于PA-RISC" SR 5到7只能通过在最高权限级别执行的代码进行修改。"对于PowerPC,任何段寄存器都需要更改权限。
显然,一些RISC ISA在完全64位之前确实扩展了它们的寻址。但我不知道细节,也不打算花时间研究这个。其他答案欢迎!
答案 1 :(得分:2)
鉴于RISC指令每个只有一个字
这不是事实。大多数现代RISC体系结构都具有可变宽度的指令集,或者至少具有特殊的可变宽度模式(在ARM中ForwardCom,SuperH,MIPS16e,thumb2,{{ 3}}在RISC-V中...),尽管它们主要是为了实现紧凑目的以提高代码密度。那仍然意味着您实际上可以使RISC体系结构使用多字指令
即使那样,它也无济于事,除非您可以使用比64位宽的指令(该指令太大而无法实际使用)。仅使用两个32位字,您仍然会局限于基地址周围的一些偏移量,而不是完整的64位地址空间。但这不是问题,因为几乎没有一个程序可以利用庞大的64位地址空间。这就是为什么没有指令在x86-64中接收64位立即地址的原因,因为32位偏移量已经足够了。因此,您可以这样做:在大多数情况下,请使用较小的立即数偏移量;在需要完整的64位地址时,请使用2寄存器对
正如彼得所说,比字长更宽的地址主要仅在8位微控制器中才能看到。除了AVR,它还用于程序计数器为13或14位长的8位C instruction set中。指令通常只包含地址的低位,高位将来自PC或PCLATH寄存器。如果您不想使用上述偏移量,则可以直接替换低位,这是另一种方法。显然,您仍需要一个单独的寄存器来存储高位。但是,如果您不关心PIC,那么只需使用专用的大型寄存器即可寻址,例如8051、6502或其他较旧的CISC体系结构
还有很多其他方法可以支持比寄存器大小更大的地址范围,如我在orthogonality中所述。其中之一是将虚拟地址限制为仅寄存器大小(如ARM LPAE或x86 PAE),同时允许物理地址为64位宽。这些页面将被映射到TLB中,并且您不需要使用2个寄存器来寻址。如果您想在此模式下访问超过4GB的内存,只需使用类似于How can 8-bit processor support more than 256 bytes of RAM?的API,或使用多个进程(例如Adobe Premiere CS4的操作方式)