首页 文章

RISC访问地址大于最大整数

提问于
浏览
1

假设您正在运行32位RISC系统 . 您将使用什么指令来访问64位内存地址?

在CISC指令集中,您可以使用多字指令简单地传递额外的字 . 例如:

1a) JMP
1b) loAddress
1c) hiAddress

鉴于RISC指令每个只有一个字,您将如何访问多字地址?

假设ALU是32位并且具有进位标志 .

此外,在CISC系统(例如8080)中,loAddress和hiAddress字都将存储在程序存储器中 . 即 JMP 指令知道查看程序存储器中的下一个项目以检索 loAddress ,然后检查项目以检索 hiAddress . RISC会发生什么?

1 回答

  • 3

    即使在CISC上,你所描述的也很不寻常 . It's not because of being CISC, it's because of using addresses wider than registers . 这通常只在8位CPU中找到 . (虽然x86分段也有资格,间接远程跳转指向 m16:32 段/偏移对 . 或者在16位模式下, m16:16 . 作为little-endian,偏移量是第一个 . )在64位模式之外, jmp ptr16:32 也是可编码的,绝对段:偏移量作为指令流的一部分 . )

    通常,当您想要设计具有更大地址空间的CPU时,您还可以使寄存器更宽,以便您可以有效地处理地址 . 当你想通过使用大多数8位寄存器/ ALU来节省晶体管时,它只是在非常低端,但是你不能将地址空间限制在256字节,你会发现这种设计 .


    即使地址大小与字大小匹配,这里也存在一个真正的问题 . Constructing arbitrary 32-bit (or 64-bit) constants is a problem that different ISAs solve different ways . ARM经常使用来自附近"literal pool"的PC相对负载,而其他人经常使用 lui 或等效设置高16位而其余为零,然后 ori 使用16位立即数 . (通过使用移位/旋转立即数,ARM有一些简单的技巧来编码只有几位的immediate . )

    In general on a RISC, if you need to jump far away you may need to construct the address in a register using multiple instructions. 然后使用跳转到寄存器指令 .

    MIPS分支指令很有意思:它具有相对分支,它为程序计数器添加一个相当大的范围的带符号位移,以及用新地址替换低28位PC的绝对跳转指令 . (由26位立即左移构造,因为MIPS要求指令对齐,因此不需要存储低2位 . )How to Calculate Jump Target Address and Branch Target Address? . 但是当目标位置无法从那些目标位置到达目标时,您需要 jr 并在寄存器中有一个地址 .

    x86-64也缺少64位相对跳转指令 . 如果你需要跳远-2GiB(而不是像新的CS段那样 far ),你需要间接跳转 . 正常跳转/分支指令仍然使用 rel8rel32 位移,保持机器代码紧凑 . 唯一可以采用64位立即数的指令是 mov -to-register . 正常的代码模型假设同一个库或可执行文件中的所有代码都在2GiB之内,因此链接器将能够填充32位位移 .


    8 -bit RISC

    我所知道的唯一一个比寄存器更宽的程序计数器的RISC ISA是AVR,一个带有8位寄存器的微控制器 . It can treat pairs of registers as 16-bit addresses ,其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绝对地址 .


    Mainstream RISC machines with 32-bit registers also have 32-bit program counters and virtual address-spaces . (拥有超过4GiB的物理内存是可能的,但是你无法在一个进程中同时映射所有内存) .

    它们中的大多数在设计中都是面向字的,因此它们只需要 jr reg (MIPS)或任何等效的分支到任何可能的地址,因为它适合于一个寄存器 . 这是RISC字面意义上降低复杂性的一部分 .


    在像MIPS,SPARC或PowerPC这样的普通RISC上, 64-bit addresses are only available in the 64-bit ISA extension ,其中有64位整数寄存器 . 因此,您可以使用MIPS ld $2, 0($3) 这样的指令,使用 $3 作为64位基址进行64位(双字)加载 . 见MIPS-IV ISA manual . (MIPS-III添加了64位扩展,带有 lddaddu 等指令 . 显然MIPS-I使其大部分操作码编码空间未被使用,因此新的操作码有足够的空间来完成64位的完整ALU操作 . )

    某些32位CPU添加了扩展以支持大型物理地址,而不会增加虚拟地址空间 . 例如,x86 's PAE defined a new page-table format with 36-bit physical addresses. But even with segmentation, a single process can' t一次可以处理超过4GiB的虚拟内存 . (x86段基址偏移发生在virt-> phys转换之前,创建一个32位线性地址 . 因此它对于线程局部存储仍然有用,例如 [fs:0] 是一个不同的线性地址,具体取决于该线程的 fs 段基础 . )


    在32位RISC ISA上进行扩展寻址

    保罗克莱顿评论:

    PA-RISC有“空间寄存器”,提供扩展寻址 . 32位PowerPC具有段寄存器,这些寄存器是根据16条表(提供52位虚拟地址空间)中有效地址的最高4位选择的 . 对于PA-RISC“SRs 5到7只能通过在最高权限级别执行的代码进行修改 . ”对于PowerPC,任何段寄存器都需要更改权限 .

    显然,一些RISC ISA在完全64位之前确实扩展了它们的寻址 . 但我不知道细节,也不打算花时间研究这个 . 其他答案欢迎!

相关问题