算术运算指令
ADD
语法 | ADD RD,RS1,RS2 | |
---|---|---|
例子 | add x5,x6,x7 | x5=x6+x7 |
编码格式:R-type
opcode(7):0110011(OP)
从RS里面取出数据,把里面的数据计算,得出的结果放在rd里面
func3取值000,func7取值0000000
.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位,用一个立即数
_start:
li x6, 2 # x6 = 2,li这里就是一个赋值运算的操作
addi x5, x6, 1 # x5 = x6 + 1
注意sub没有subi,减一个正数相当于加一个负数
SUB
_start:
li x6, -1 # x6 = -1
li x7, -2 # x7 = -2
sub x5, x6, x7 # x5 = x6 - x7
和前面的add一样
伪指令
LUI
LUI:把一个数左移12位
_start:
lui x5, 0x12345 # int x5 = 0x12345 << 12
addi x5, x5, 0x678 # x5 = x5 + 0x678
最后x5=0x12345678
LI
LI 赋值
li x5, 0x80
x5=0x80
AUIPC
auipc x5, 0x12345 # x5 = PC + (0x12345 << 12)
auipc x6, 0 # x6 = PC, to obtain the current PC
有利于构造相对地址
auipc就是把一个数左移12位,后再加上pc值
LA
常用于加载一个函数或者变量的地址,上面的赋值一个数都可以用li,而赋值地址就只能使用la
_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返回到寄存器中,继续我们的使用
条件分支指令
如果条件成立就跳转到最后一个最后一个地址上
# 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保存
# 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就是一个伪指令