Skip to content

2.5

:material-circle-edit-outline: 约 429 个字 :fontawesome-solid-code: 25 行代码 :material-clock-time-two-outline: 预计阅读时间 2 分钟

Character Data

double word-->64bit, 8byte -->lb

word --> 32bit, 4byte -->lw

offset永远按照byte算,与上面无关

String Copy Example

strcpy:
    addi sp, sp, -8      # adjust stack for 1 doubleword
    sd x19, 0(sp)        # save x19
    add x19, x0, x0      # i = 0
L1:
    add x5, x19, x11     # x5 = address of y[i]
    lbu x6, 0(x5)        # x6 = y[i]
    add x7, x19, x10     # x7 = address of x[i]
    sb x6, 0(x7)         # x[i] = y[i]
    beq x6, x0, L2       # if y[i] == 0 then exit
    addi x19, x19, 1     # i = i + 1
    jal x0, L1           # next iteration of loop
L2:
    ld x19, 0(sp)        # restore saved old s3
    addi sp, sp, 8       # pop 1 double word from stack
    jalr zero 0(x1)      # return

Addressing for 32-Bit Immediate and Addresses

寻址这部分比较重要

先看怎么构造地址

寻址需要指令里面Imm部分提供地址,但是大部分指令类型只有12bit的Imm

于是诞生了U-type指令,里面有20bit的Imm,用于辅助其它指令寻址。由此我们就有了32bit寻址空间

image-20240507215154366

用到了lui指令,其将寄存器高处的20bit填充为该指令指定的立即数

我们不能直接两条指令一起用,所以需要借助寄存器取出两者的地址

就先用lui将U-type包含的地址放入reg高位,addi将原指令包含的地址直接加入reg,由此合并到一个寄存器里

注意必须先lui,因为其会让寄存器低的位置0

Branch Addressing

先看下面这图,SB-type和UJ-type的Imm没有最低位,这是为了在总位数固定的情况下增大1倍寻址空间,位从11 ~ 0位变成12 ~ 1位,最低位直接不考虑,永远为0,因为一条指令占4byte(12bit),pc每次是+4,最低位不会变化

实际上倒数第二位也可以不管,也不会变,但是没这么设计,这是考虑到16位指令,pc+2,这个我们不考虑

这里的思想类似浮点数标准格式下舍去整数的1

image-20240321201847606

SB和UJ两类跳转指令都遵循这一设计:

image-20240508202355829

这部分就注意Imm要乘2

意思是,我们人眼看到的Imm后面要加一个0,才是其真正代表的数值

while (save[i]==k) i=i+1;
Loop:
    slli x10, x22, 3   # temp reg x10 = 8 * i
    add x10, x10, x25  # x10 = address of save[i]
    ld x9, 0(x10)      # temp reg x9 = save[i]
    bne x9, x24, Exit  # go to Exit if save[i] != k
    addi x22, x22, 1   # i = i + j
    beq x0, x0, Loop   # go to Loop
Exit:

image-20240508203432945