【RISC |
您所在的位置:网站首页 › cad中li指令怎么使用的 › 【RISC |
在RISC-V中有这样一条伪指令: li a0, immediately可以将任意的32位数据或者地址加载到指定的寄存器中 在 RV32I中,它扩展到 lui 和/或 addi li 何时扩展为 lui 或者 addi呢?又何时扩展为lui 和 addi呢? 我们观察lui 和 addi 的指令码即可得出结果 由上图可知,lui加载的立即数为高20位,addi加载的立即数为低12位 由此得出结论 若 li 加载的立即数范围为:0~4096 时,会扩展成 addi 指令li a0, immediately ⇒ addi a0, x0, imme 若 li 加载的立即数范围超过4096时,会扩展成 lui 指令 和 addi 指令li a0, immediately 扩展成 1、lui a0, (immediately >> 12) 2、addi a0, a0, (immediately & 0xFFF) 若 li 加载的立即数范围超过4096时,并且低12位为0,会扩展成 lui 指令li a0, immediately 扩展成 lui a0, (immediately >> 12) 接上文,观察 lui指令、addi指令 会得到这个结果:lui指令加载的立即数为无符号,无需注意。addi指令加载的为有符号数,这个需要考虑一下立即数的符号位 假如我们要加载大立即数到指定的寄存器,需要考虑两种情况 1、第11位为0 第11位为0,则指令:li a0, immediate 会直接扩展成: lui a0, immediate >> 12 addi a0, a0, (immediate & 0xFFF)2、第11位为1 第11位为1,此时 li a0, immediate 就不会扩展成 lui a0, immediate >> 12 addi a0, a0, (immediate & 0xFFF)而是扩展成 lui a0, ((immediate >> 12) + 1) addi a0, a0, ((immediate & 0xFFF) - 2^12)解释一下: addi指令所加载的立即数的第11位为1时,这个立即数是符号扩展的,因此加数将为负数。这意味着除了添加常量的最右边11位 之外,我们还需要减去2^12。为了弥补这个错误,只需将lui 加载的常量添加一个1,因为 lui 常量缩小了 2 ^12倍 例如:将 0xE76 加载到寄存器a0中 答: lui a0, 0x01 addi a0, a0, (0xE76 - 4096) 代码实现 #define immediate XXXX uint32_t MSB, LSB; MSB = immediate >> 12; LSB = immediate & 0xFFF; if (MSB == 0) { if (LSB & 0x800) { asm volatile("lui a0, 0x01"); asm volatile("addi a0, a0, LSB - 4096"); } else { asm volatile("addi a0, x0, LSB"); } } else { if (LSB & 0x800) { asm volatile("lui a0, MSB + 0x01"); asm volatile("addi a0, a0, LSB - 4096"); } else { asm volatile("lui a0, MSB"); asm volatile("addi a0, x0, LSB"); } } |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |