即使在 CISC 上,您所描述的也很不寻常。 这不是因为是 CISC,而是因为使用的地址比寄存器更宽。这通常只存在于 8 位 CPU 中。(尽管 x86 分段也符合条件,间接远跳转采用指向m16:32
段/偏移对的指针。或者在 16 位模式下,m16:16
. 作为 little-endian,偏移量是第一个。)在 64 位模式之外,jmp ptr16:32
也是可编码的,绝对段:偏移量作为指令流的一部分。)
通常,当您想设计一个具有更大地址空间的 CPU 时,您还会使寄存器更宽,以便您可以有效地处理地址。只有当您想通过主要使用 8 位寄存器/ALU 来节省晶体管,但又不能将地址空间限制为 256 字节时,它才处于非常低端,您可以在其中找到这种设计。
即使地址大小与字长匹配,这里也存在一个真正的问题。 构造任意 32 位(或 64 位)常量是不同 ISA 解决方法不同的问题。ARM 经常使用来自附近“文字池”的 PC 相对加载,而其他人经常使用 alui
或等价物来设置高 16 位并将其余部分归零,然后ori
使用 16 位立即数。(ARM 有一些巧妙的技巧,可以通过使用移位/旋转的立即数对仅设置几位的立即数进行编码。)
一般来说,在 RISC 上,如果您需要跳得很远,您可能需要使用多条指令在寄存器中构造地址。 然后使用跳转到寄存器指令。
MIPS 分支指令很有趣:它具有向程序计数器添加一个相当大范围的有符号位移的相对分支,以及将 PC 的低 28 位替换为新地址的绝对跳转指令。(由 26 位立即左移构造,因为 MIPS 要求指令对齐,所以低 2 位不需要存储。) 如何计算跳转目标地址和分支目标地址?. 但是,当目标无法从当前位置到达时,您需要jr
在寄存器中提供地址。
x86-64 也缺少 64 位相对跳转指令。如果您需要跳出超过 +-2GiB 的距离(不像far
在新的 CS 段中那样),则需要间接跳跃。正常的跳转/分支指令仍然使用rel8
或rel32
位移,保持机器代码紧凑。唯一可以采用 64 位立即数的指令是mov
-to-register。普通代码模型假设同一库或可执行文件中的所有代码彼此之间的距离在 2GiB 以内,因此链接器将能够填充 32 位位移。
8 位 RISC
我所知道的唯一一个程序计数器比寄存器宽的 RISC ISA 是 AVR,它是一个具有 8 位寄存器的微控制器。 它可以把成对的寄存器当作 16 位地址,它的 PC 是 16 位的。它IJMP
(间接跳转)指令设置 PC = Z(其中Z
是一对 8 位寄存器)。在具有 22 位程序计数器而不是 16 位程序计数器的 AVR 上,它会归零PC(21:16)
。
EIJMP(扩展间接跳转)从 I/O 空间获取 EIND 寄存器用于 PC 的高位,低位仍然来自Z
.
AVR 指令几乎都是 2 字节长,但有些版本有4 字节jmp
指令,跳转目标需要 0..4M 绝对地址。
具有 32 位寄存器的主流 RISC 机器也具有 32 位程序计数器和虚拟地址空间。(拥有超过 4GiB 的物理内存是可能的,但您不能在一个进程中同时映射所有内存)。
它们中的大多数在设计中都非常面向字,因此它们所需要的只是jr reg
(MIPS)或任何等效于分支到任何可能地址的东西,因为它适合一个寄存器。这是RISC 字面上所代表的降低复杂性的一部分。
在 MIPS、SPARC 或 PowerPC 等普通 RISC 上,64 位地址仅在 64 位 ISA 扩展中可用,其中您有 64 位整数寄存器。因此,您将使用 MIPS 之类的指令ld $2, 0($3)
来执行 64 位(双字)加载,并将$3
其用作 64 位基址。请参阅此MIPS-IV ISA 手册。(MIPS-III 添加了 64 位扩展,带有和 之类的指令ld
。daddu
显然 MIPS-I 留下了很多未使用的操作码编码空间,因此新操作码有足够的空间来执行完整的 64 位 ALU 操作。)
一些 32 位 CPU 添加了扩展以支持大型物理地址,而无需增加虚拟地址空间。例如,x86 的 PAE 定义了一种具有 36 位物理地址的新页表格式。但即使有分段,单个进程一次也不能处理超过 4GiB 的虚拟内存。(x86 段基址+偏移发生在virt->phys 转换之前,创建一个 32 位线性地址。因此它对于线程本地存储仍然有用,例如,[fs:0]
根据该线程的fs
段基址作为不同的线性地址。)
32 位 RISC ISA 上的扩展寻址
保罗克莱顿评论:
PA-RISC 具有提供扩展寻址的“空间寄存器”。32 位 PowerPC 具有根据 16 项表中有效地址的最高有效 4 位选择的段寄存器(提供 52 位虚拟地址空间)。对于 PA-RISC,“SR 5 到 7 只能通过在最高特权级别执行的代码进行修改。” 对于 PowerPC,任何段寄存器更改都需要特权。
因此,显然一些 RISC ISA 在完全 64 位之前确实扩展了它们的寻址。但我不知道细节,也不打算花时间研究这个。欢迎其他答案!