常数或立即数操作数
我们需要将常数从内存中取出才能使用,将常数加载到寄存器。
或者是通过addi使用立即数相加的指令。
addi x22,x22,4
常数0,可以有效使用它,简化指令系统体系结构。例如,使用常0寄存器求原数的相反数,RISC-V专用寄存器x0硬连线到常数0. 根据使用频率来确定要定义的常数。
偏移量加基址寄存器寻址方式,对于数组和结构体来说非常适用。
寄存器可以指向结构的起始地址,偏移量可以选择所需元素。
有符号数和无符号数
区分正数和负数,通过一个单独的符号位。
前导0表示正数,前导1表示负数。有符号的二进制数为二进制补码。
二进制补码的优点是,所有负数的最高有效位都为1,因此只需检查这一位就可以知道正数还是负数。符号位。
采用二进制补码,不需要考虑最高位溢位的情况,发生溢位直接丢弃即可,计算效率也更高。 将减法变为加法运算即可。
有符号载入,复制符号位填充寄存器剩余部分,符号扩展。
无符号数载入,只需在数据左侧填充0.
无符号字节载入lbu,将字节视为无符号数,用零扩展填充寄存器最左位。而字节载入lb使用带符号整数。
使用二进制补码,第一种对二进制补码求相反数的快速方法。把,每个0转为1,以及每个1转为0.最后将结果加1.
第二种是将一个用n位表示的二进制数转换为一个用多于n位表示的数。先取位数更少的数的最高位符号位,并将其复制来填充位数更多的数的新位,原来的非符号位被复制到新双字的右侧部分。符号扩展。
计算机中的指令表示
opcode 操作码:指令的基本操作。表示指令操作和指令格式的字段。
rd目的寄存器,存放操作结果。
funct3 一个另外的操作码字段
rs1第一个源操作数寄存器
rs2第二个源操作数寄存器
funct7一个另外的操作码字段
优秀的设计要适当的折中
保持所有指令长度相同,对不不同的指令使用不同的指令格式。
对于I型立即数指令。 12位立即数表示-2^11 - 2^11 - 1 之间的整数。
当I型指令用于加载指令时,immediate字段表示一个字节偏移量。
指令格式通过操作码字段中的值来区分。每个格式在第一个字段被分配了不同的操作码值。
对于ld指令,rs1为基址寄存器x10,立即数为240 = 8x30 表示偏移量。rd为目标寄存器。
逻辑操作
逻辑移位, 用0填充空出来的位。
算术移位,用原来的符号位来填充。
用于决策的指令
if else:
beq rs1 rs2 L1 如果rs1和rs2值相等,则转到L1的语句指令。beq为相等则分支。
bne为不等则分支。
无条件分支
beq x0 x0 EXIT
循环
while循环。
计算,然后bne进行判断,否则继续,成立则退出exit。
最高有效位。来判断。小于则分支指令blt,大于等于分支bge。
case/switch语句
分支地址表。
程序索引到表中,跳转到合适的指令序列。
无条件跳转,jalr。
计算机硬件对过程的支持
过程或函数是结构化编程的一种工具,过程允许程序员只专注于任务的一部分,参数可以传递数值并返回结果。
因此可以充当过程和其余程序与数据之间的接口。
分配寄存器遵循约定:
x10-x17: 8个地址寄存器,用于传递参数或返回值。
x1:一个地址寄存器,用于返回起始点。
仅用于过程的指令,跳转到某个地址的同时将下一条指令的地址保存到目标寄存器rd。跳转-链接指令jal
存储在x1中的链接称为返回地址。jalr x0,0(x1)
程序计数器,保存当前执行指令的地址。 x0硬连线为0。
对于大立即数的编码和寻址
lui指令,load upper immediate取立即数最高位。 lui使用新的指令格式U型指令,将20位常数加载到寄存器的第12位到31位。并将31位的值复制到最左边32位,最右边的12位用0填充。
分支中的寻址
PC相对寻址: 地址是PC和指令中的常量之和。
对于条件分支和无条件跳转使用PC相对寻址。
分支指令设计为PC相对偏移表示分支和目标指令之间的字数而不是字节数。
RISCV寻址方式总结
1 立即数寻址 操作数是指令本身的常量
2 寄存器寻址 操作数在寄存器中
3 基址或偏移寻址 操作数在内存中,其地址是寄存器和指令中的常量之和
4 PC相对寻址 分支地址是PC和指令中的常量之和