一起学RISC-V汇编第8讲之RISC-V寻址方式及内存访问方式

一起学RISC-V汇编第8讲之RISC-V寻址方式及内存访问方式

1 RISC-V的寻址方式

计算机常用的寻址方式有3种:

1.1 立即数寻址

指令中直接给出相应的操作数(立即数),比如RISC-V中的短立即数指令,因为操作码直接包含立即数中,所以立即数寻址对立即数的大小有限制,在RV32I指令集中,立即数一共12位,最大支持4096:

# 加立即数(算术指令), t0 = a0 + 1234,这里1234就是立即数寻址
addi t0, a0, 1234

1.2 寄存器寻址

指令中给出寄存器,操作数放在寄存器中,通常直接使用寄存器名表示它所保存的数据,即寄存器寻址。比如RISC-V的R-type指令:

# 加操作, a1 = s0 + s1,这里a1 s0 s1都是寄存器寻址,对于RV32I可寻址范围为32个通用寄存器
add a1, s1, s0

1.3 存储器寻址

数据保存到主存储器中,指令需要能够寻址到存储中的操作数。
访存指令唯一支持的寻址模式是将 12 位立即数符号扩展后与寄存器相加,即寄存器相对寻址。

  1. 寄存器相对寻址(基址寻址,RISC-V唯一支持的访存方式)

    数据地址为:寄存器址 + 偏移量,RISC-V支持寄存器相对寻址。

    # x[rd] = sext(M[x[rs1] + sext(offset)][31:0]),数据地址为x[rs1] + sext(offset)
    lw rd, offset(rs1)
    
  2. 寄存器间接寻址(可采用寄存器相对寻址模拟实现)

    寄存器存放的是数据的地址而非数据本身,RISC-V并不支持寄存器间接寻址,而是采用另一种形式来替代,RISC-V是利用寄存器相对寻址,将偏移量设为0,来实现寄存器间接寻址的功能的。

    # x[rd] = sext(M[x[rs1] + sext(0)][31:0]),数据地址为x[rs1] + sext(0)
    lw rd, 0(rs1)
    
  3. 直接寻址(RISC-V不支持)

    指令中给出操作数的有效地址,RISC-V不支持直接寻址,ARM同样不支持直接寻址,但X86提供这种寻址方式。

1.4 PC相对寻址

PC相对寻址表示地址为相对于PC的偏移,PC 相对寻址可用来支持位置无关代码,像RISC-V的分支跳转指令也都是相对寻址,如RISC-V的分支跳转指令:

# if (rs1 < rs2) pc += sext(offset)
blt rs1, rs2, offset

总结:

由上面分析可知,RISC-V支持4种寻址方式:立即数寻址、寄存器寻址、相对寻址、寄存器相对寻址(基址寻址)这几种方式。

RISC-V的寻址方式如下图(引用《计算机组成与设计riscv》一书的插图):

2 内存访问方式

RISC-V架构属于加载-存储架构:

RISC-V架构是一种加载-存储架构(与ARM一样),意味着:数据只能在寄存器中处理,而不能直接在存储器中操作,也就是说:处理指令不直接操作内存中的数据,如果程序需要修改内存中的数据,需要使用加载指令将数据从内存中加载到寄存器,使用数据处理指令修改了之后,然后用存储指令将结果存回到内存。

与ARM与RISC-V不同,x86-32算术指令的操作数可位于内存中,并不要求一定在寄存器中,对于x86-32 复杂指令和内存操作数使得设计者实现比较难受。

RISC-V中只有访存指令才能访问内存。其他的普通指令无法访问内存,这种架构是RISC-V采用的一个基本策略,这种策略使得处理器核的设计变得简单。

RV32I/RV64I 指令集中,可以访问内存的指令如下:

指令示意:

参考:

  1. 动态链接库的实现原理是什么?
posted @ 2024-09-08 15:28  sureZ_ok  阅读(316)  评论(0编辑  收藏  举报