文章目录
算术运算指令 ADD
语法
ADD RD,RS1,RS2
例子
add x5,x6,x7
x5=x6+x7
编码格式:R-type opcode(7):0110011(OP) 从RS里面取出数据,把里面的数据计算,得出的结果放在rd里面 func3取值000,func7取值0000000
1 2 3 4 5 6 7 8 9 10 11 12 .text # Define beginning of text section,告诉汇编器,所有的数据都放到text section里面 .global _start # Define entry _start 这里面就是程序的入口,_start就是主体程序 _start: li x6, 1 # x6 = 1 li就是进行赋值 li x7, 2 # x7 = 2 add x5, x6, x7 # x5 = x6 + x7 stop: j stop # Infinite loop to stop execution j跳转,跳转到stop,就死循环,不退出 .end # End of file
ADDI 使用了立即数 少了一个寄存器,占12个bit位,用一个立即数
1 2 3 _start: li x6, 2 # x6 = 2 ,li这里就是一个赋值运算的操作 addi x5, x6, 1 # x5 = x6 + 1
注意sub没有subi,减一个正数相当于加一个负数
SUB 1 2 3 4 _start: li x6, -1 # x6 = -1 li x7, -2 # x7 = -2 sub x5, x6, x7 # x5 = x6 - x7
和前面的add一样
伪指令
LUI LUI:把一个数左移12位
1 2 3 _start: lui x5, 0x12345 # int x5 = 0x12345 << 12 addi x5, x5, 0x678 # x5 = x5 + 0x678
最后x5=0x12345678
LI LI 赋值
x5=0x80
AUIPC 1 2 3 auipc x5, 0x12345 # x5 = PC + (0x12345 << 12 ) auipc x6, 0 # x6 = PC, to obtain the current PC
有利于构造相对地址 auipc就是把一个数左移12位,后再加上pc值
LA 常用于加载一个函数或者变量的地址,上面的赋值一个数都可以用li,而赋值地址就只能使用la
1 2 3 _start: la x5, _start # x5 = _start jr x5
这里给x5加载_start地址 jr跳转到x5里面,就是死循环
逻辑运算指令 and x5,x6,x7按位与操作
x5=x6&x7
or x5,x6,x7和c语言或操作
x5=x6|7
xor x5,x6,x7异或操作
x5=x6^x7
NOT:取反操作
等价于xori rd ,rs ,-1==~rs
sll:左移逻辑上,只补0
sll x5,x6,x7 x5=x6<<x7 srl:右移
sra:算术移位
内存读写指令 内存读取指令 :LOAD,将数据从内存读取到寄存器 里面内存写指令 :STORE,将数据从寄存器放到内存 中 lw,把把数据从内存里面读取到寄存器里面 sw,就是把数据从寄存器里面放到内存里面 最典型的就是ra
一个a函数调用b函数 b函数需要使用sw将ra值存到内存里面,大部分就是栈顶的位置sp b函数执行完毕,就要把内存栈顶的ra返回到寄存器中,继续我们的使用
条件分支指令 如果条件成立就跳转到最后一个最后一个地址上
1 2 3 4 5 6 7 8 # i = 0 # while (i < 5) i++; li x5, 0 li x6, 5 loop: addi x5, x5, 1 bne x5, x6, loop
bne最后一个就是要跳转的地址
无条件跳转指令 JAL(jump and link) 语法
JAL RD ,LABEL 这里的RD,就是为了跳转回来爱能执行子过程,后面的函数 lable就是要跳转到的地方,RD就是label地址处理完之后返回的地址
JALR(jump and link register)
jalr x0, 0(x5) 跳转到x5+0的位置,x0保存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # int a = 1; # int b = 1; ## void sum() # {# a = a + b; # } ## void _start() # {# sum(); # } .text # Define beginning of text section .global _start # Define entry _start # _start就是函数的入口 _start: li x6, 1 li x7, 2 jal x5, sum # call sum, return address is saved in x5,把函数地址保存在x5里面 stop: j stop # Infinite loop to stop execution sum: add x6, x6, x7 # x6 = x6 + x7 jalr x0, 0 (x5) # return 这里是跳转到x5+0的地址,是要进行相对地址进行处理的 .end # End of file
J/JR 是不返回的跳转,J/JR就是一个伪指令