if-statement instruction is beq reg1, reg2, L1 means: 如果相等则跳转
bne reg1, reg2, L1 means:如果不相等则跳转
branch if less than: blt
branch if greater than or equal: bge
unsigned版本:bltu, bgeu
无条件分支:j lable
Logical instructions
逻辑左移:sll,立即数:slli slli x11,x12,2 #x11=x12<<2
逻辑右移与逻辑左移同理
运算移位:只有右移,最高位用符号位填充,sra,srai
Assembler to Machine Code
为寄存器起别名
伪指令:
mv rd, rs = addi rd, rs, 0
li rd, 13 = addi rd, x0, 13
nop = addi x0, x0, 0
Function Calls
六个步骤:
把参数放在函数可以访问的位置
把控制权转移到函数
函数访问资源
函数进行任务
把返回值放到合适的位置,恢复寄存器
把控制权转移回主函数
Function Call Convention
a0–a7(x10-x17): 参数寄存器
ra(x1): 返回地址寄存器
s0-s1(x8-x9), s2-s11(x18-x27): 保存寄存器
jump register(jr): jr ra ret = jr ra
jump and link(jal):
Before: 1008 addi ra,zero,1016 # ra=1016 1012 j sum # goto sum
After: 1008 jal sum # ra=1012,goto sums
jump and link register(jalr): jalr rd, rs, imm
Function Call Example
Stack: 暂时存储保存寄存器中的值,使用后再恢复
栈是从上向下增长的
例:
1 2 3 4 5
intLeaf(int g, int h, int i, int j) { int f; f = (g + h) – (i + j); return f; }
RISC-V:
1 2 3 4 5 6 7 8 9 10
Leaf: addi sp,sp,-8 # adjust stack for 2 items sw s1, 4(sp) # save s1 for use afterwards sw s0, 0(sp) # save s0 for use afterwards add s0,a0,a1 # f = g + h add s1,a2,a3 # s1 = i + j sub a0,s0,s1 # return value (g + h) – (i + j) lw s0, 0(sp) # restore register s0 for caller lw s1, 4(sp) # restore register s1 for caller addi sp,sp,8 # adjust stack to delete 2 items jr ra # jump back to calling routine
Nested Calls and Register Conventions
保存寄存器:s0-s11,被调用者在使用后要恢复原来的值
临时寄存器:t0-t6,其中的值不必恢复
Symbolic Register Names
Memory Allocation
使用栈: 例:
1 2 3
intsumSquare(int x, int y) { return mult(x,x)+ y; }
RISC-V:
1 2 3 4 5 6 7 8 9 10
addi sp,sp,-8 # space on stack sw ra, 4(sp) # save ret addr sw a1, 0(sp) # save y mv a1,a0 # mult(x,x) jal mult # call mult lw a1, 0(sp) # restore y add a0,a0,a1 # mult()+y lw ra, 4(sp) # get ret addr addi sp,sp,8 # restore stack jr ra