RISC-V基础指令之addi与lui(生成一个更大的立即数,包含负数符号拓展的特殊情况)

这篇具有很好参考价值的文章主要介绍了RISC-V基础指令之addi与lui(生成一个更大的立即数,包含负数符号拓展的特殊情况)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这两条指令都是RISC-V体系结构中的整数指令,它们的功能和格式如下:

  • lui指令的全称是Load Upper Immediate,它的功能是把一个20位的立即数加载到寄存器的高20位,低12位为0。它的格式是:

    lui rd, imm

    其中,rd是目标寄存器,imm是20位的立即数。例如,lui x1, 0x12345会把0x12345000加载到x1寄存器中。

  • addi指令的全称是Add Immediate,它的功能是把一个寄存器的值和一个12位的立即数相加,并把结果存入另一个寄存器。它的格式是:

    addi rd, rs1, imm

    其中,rd是目标寄存器,rs1是源寄存器,imm是12位的立即数。例如,addi x2, x1, 0x678会把x1寄存器的值和0x678相加,并把结果存入x2寄存器中。

这两条指令可以组合起来生成一个大于20位的立即数。例如,如果想要生成一个32位的立即数0x12345678,就可以这样做:

lui x3, 0x12345
addi x3, x3, 0x678

lui指令和addi指令的立即数必须是12位和20位的。这是因为RISC-V指令集的设计原则之一是固定长度的指令,也就是说每条指令都是32位的。为了在32位的指令中表示操作码,寄存器编号,和立即数,就需要对每个部分分配一定的位数。lui指令和addi指令都属于I类型的指令,它们的格式如下:

31:20 19:15 14:12 11:7 6:0
imm rs1 funct3 rd opcode

可以看到,imm部分占用了12位,rs1和rd部分各占用了5位,funct3和opcode部分各占用了3位和7位。这样加起来刚好是32位。所以lui指令和addi指令的立即数不能超过12位。

但是,lui指令的立即数实际上是20位的,因为它会被左移12位后加载到寄存器的高20位。所以lui指令可以看作是把一个20位的立即数分成两个10位的部分,然后把高10位放在imm的高10位,低10位放在imm的低10位。例如,如果想要加载0x12345到寄存器的高20位,就可以这样写:

lui x1, 0x12345

这条指令实际上相当于:

lui x1, 0x012_345

其中,0x012是高10位,0x345是低10位。它们被合并成一个12位的立即数0x12345,并且左移12位后加载到寄存器x1中。

lui和addi指令都可以用来生成立即数,但是它们有一些限制:

  • lui指令可以把一个20位的立即数加载到寄存器的高20位,低12位为0。
  • addi指令可以把一个12位的立即数加到一个寄存器的值上,并把结果存入另一个寄存器。
  • 12位的立即数是有符号的,也就是说它可以表示正数或负数。如果它是负数,那么它的最高位(第11位)为1,并且在加法运算时会被符号扩展,也就是说它的高20位都会变成1。

因此,如果想要生成一个大于20位的立即数,就需要用lui和addi指令组合起来。例如,如果想要生成一个32位的立即数0xFEEDA987,就可以这样做:

  • 用lui指令把0xFEEDB加载到s2寄存器的高20位,低12位为0。这样s2寄存器的值就变成了0xFEEDB000。
  • 用addi指令把0x987加到s2寄存器的值上,并把结果存入s2寄存器。这样s2寄存器的值就变成了0xFEEDA987。

注意,这里有两个地方需要特别注意:

  • 为什么lui指令要加载0xFEEDB而不是0xFEEDA呢?因为0x987是一个负数,它在加法运算时会被符号扩展成0xFFFFF987。如果lui指令加载了0xFEEDA,那么加法运算后的结果就会变成0xFEED9987,而不是我们想要的0xFEEDA987。所以我们需要把lui指令加载的立即数增加1,这样加法运算后才能得到正确的结果。
  • 为什么0x987是一个负数呢?因为它是一个12位的有符号数,它的最高位(第11位)为1。在二进制补码表示法中,如果一个数的最高位为1,那么它就是一个负数。要求出它的绝对值,就需要对它取反并加1。例如,0x987取反后得到0xF678,再加1得到0xF679。所以0x987表示的负数就是−1657。

在这里,更详细地解释一下负号(即addi中的立即数第11位即最大位为1,也就是负号拓展后产生更大负数的情况)

假设我们想要生成一个32位的立即数0x12345678,我们可以用lui和addi指令组合起来,如下:

lui s0,0x12345 # 把0x12345加载到s0寄存器的高20位,低12位为0

addi s0,s0,0x678 # 把0x678加到s0寄存器的值上,并把结果存入s0寄存器

这样就可以得到我们想要的结果0x12345678。这是因为0x678是一个正数,它在加法运算时不会被符号扩展,也就是说它的高20位都是0。所以加法运算后的结果就是两个数的简单相加。

但是,如果我们想要生成一个32位的立即数0x1234F678,我们就不能用上面的方法了。因为0xF678是一个负数,它在加法运算时会被符号扩展,也就是说它的高20位都会变成1。所以如果我们用lui和addi指令组合起来,如下:

lui s0,0x1234F # 把0x1234F加载到s0寄存器的高20位,低12位为0

addi s0,s0,0xF678 # 把0xF678加到s0寄存器的值上,并把结果存入s0寄存器

那么我们得到的结果就不是我们想要的了。这是因为加法运算后的结果是:

s0 = 0x1234F000 + 0xFFFFF678 = 0x1234E678

可以看到,结果比我们想要的少了1000。这是因为符号扩展相当于把负数变成了更大的负数。所以我们需要把lui指令加载的立即数增加1,这样才能抵消符号扩展带来的影响。也就是说,我们应该这样写:

lui s0,0x12350 # 把0x12350加载到s0寄存器的高20位,低12位为0

addi s0,s0,0xF678 # 把0xF678加到s0寄存器的值上,并把结果存入s0寄存器

这样就可以得到我们想要的结果了。这是因为加法运算后的结果是:

s0 = 0x12350000 + 0xFFFFF678 = 0x1234F678

注意这里要理解好补码的意义,负数的补码,是能够和其相反数相加通过溢出从而使计算机内计算结果变为0的二进制码,所以之前的地方采取了+1的操作。

对补码更详细介绍转至计算机体系结构基础知识介绍之简单回顾原码反码补码_管二狗赶快去工作!的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-667870.html

到了这里,关于RISC-V基础指令之addi与lui(生成一个更大的立即数,包含负数符号拓展的特殊情况)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【RISC-V】 li指令

    在RISC-V中有这样一条伪指令: 可以将任意的32位数据或者地址加载到指定的寄存器中 在 RV32I中,它扩展到 lui 和/或 addi li 何时扩展为 lui 或者 addi呢?又何时扩展为lui 和 addi呢? 我们观察lui 和 addi 的指令码即可得出结果 由上图可知, lui 加载的立即数为高20位, addi 加载的立即

    2023年04月08日
    浏览(39)
  • RISC-V 指令集介绍

            指令集从本质上可以分为复杂指令集(Complex Instruction Set Computer, CISC )和精简指令集(Reduced Instruction Set Computer, RISC )两种。复杂指令集的特点是能够在一条指令内完成很多事情。         指令架构(Instruction Set Architecture, 缩写为ISA),是软件和硬件的接口

    2024年02月14日
    浏览(44)
  • RISCV 6 RISC-V加载存储指令

    RISCV - 1 RV32/64G指令集清单 RISCV - 2 “Zicsr“, CSR Instructions RISCV -3 RV32I/RV64I基本整型指令集 RISCV - 4 ISA 扩展名命名约定 RISCV 5 RISC-V调用规则 RV32I is a load-store architecture, where only load and store instructions access memory and arithmetic instructions only operate on CPU registers. RV32I provides a 32-bit address s

    2024年02月10日
    浏览(37)
  • 19|RISC-V指令精讲(四):跳转指令实现与调试

    你好,我是LMOS。 前面我们学习了无条件跳转指令,但是在一些代码实现里,我们必须根据条件的判断状态进行跳转。比如高级语言中的if-else 语句,这是一个典型程序流程控制语句,它能根据条件状态执行不同的代码。这种语句落到指令集层,就需要有根据条件状态进行跳转

    2024年01月22日
    浏览(38)
  • RISC-V(2)——特权级及特权指令集

    目录 1.  特权级 2. 控制和状态寄存器(CSR) 2.1 分类  2.2 分析               一个 RISC-V 硬件线程( hart )是运行在某个特权级上的,这个特权级被编码到一个或者多个 CSR (control and status register, 控制和状态寄存器 )中的一种模式。         当前定义了四种特权级

    2024年02月10日
    浏览(43)
  • 从CISC到RISC-V:揭开指令集的面纱

    对于大多数同学来说,计算机或智能手机的运行似乎就像魔法一样神奇。你可能知道它们内部都是一些复杂的电子组件,比如CPU、内存等等,但这些组件是如何协同工作,让我们可以在电脑上打字,或者在手机上看视频呢?实际上,这一切都归功于一种名为“指令集”的神秘

    2024年01月21日
    浏览(36)
  • RISC-V处理器的设计与实现(一)—— 基本指令集

    RISC-V处理器的设计与实现(一)—— 基本指令集_Patarw_Li的博客-CSDN博客 RISC-V处理器的设计与实现(二)—— CPU框架设计_Patarw_Li的博客-CSDN博客 RISC-V处理器的设计与实现(三)—— 上板验证_Patarw_Li的博客-CSDN博客 RISC-V处理器设计(四)—— Verilog 代码设计-CSDN博客  RISC-V处

    2024年02月05日
    浏览(44)
  • RISC-V指令集架构------RV32F/RV32D浮点扩展指令集

        RV32D和RV32F是RISC-V指令集架构中的浮点扩展指令,用于支持浮点运算。其中,RV32D是双精度浮点扩展指令,而RV32F是单精度浮点扩展指令。在RISC-V中,浮点扩展指令是可选的,需要根据具体应用场景来选择是否使用。如果应用场景需要进行浮点运算,那么就需要使用RV32D和

    2024年02月08日
    浏览(38)
  • 【基于FPGA的芯片设计】RISC-V的20条指令CPU设计

    实验板卡 :xc7a100tlc sg324-2L,共20个开关 实验要求:          

    2024年02月16日
    浏览(46)
  • RISC-V公测平台发布 · 第一个WEB Server “Hello RISC-V world!”

    RISC-V公测平台Web Server地址:http://175.8.161.253:8081 Web Server是互联网应用的基础设施,无论是用户访问网站,还是后端服务提供商和开发者构建各种应用程序,Web Server都在其中扮演着至关重要的角色。 显而易见,对于RISC-V生态来说, Web Server也是不可缺少的一部分 。 接下来我们

    2024年02月14日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包