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寻址空间
用到了
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
SB和UJ两类跳转指令都遵循这一设计:
这部分就注意Imm要乘2
意思是,我们人眼看到的Imm后面要加一个0,才是其真正代表的数值
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: