RISC-V 中 JAL 和 JALR 指令的偏移地址

2023-12-31

在 RISC-V 规范中,JAL 和 JALR 指令中的立即数被转换为跳转偏移量,如下所示:

  1. 将给定立即数符号扩展为 XLEN 位。

  2. 将 LSB 设置为零。

我对此有几个问题。

问题1

对于 JAL,这给出了一个范围:

000000000000 to 111111111110

即4KiB。

在这里,如果 LSB 必须始终为零,为什么不将立即数视为地址的强制零 LSB 之前的 12 位,从而将地址范围增加到:

[000000000000]0 to [111111111111]0      

[ ] 表示给定的立即偏移量,内部会在给定的立即偏移量末尾加零。那是,

  1. 左移一位给出地址。

  2. 将结果符号扩展至 XLEN 位。

问题2

如何区分正偏移和负偏移?是否使用了给定偏移量的 MSB?


JAL有一个 20 位偏移量和一个寄存器作为操作数。

其操作是pc := pc + sxt ( imm20 << 1 ).

从公式中可以看出,分支是与 pc 相关的。立即数可以达到 +/- 1 MBJAL本身。立即数移位一位,真正的 LSB 始终为零,因此不进行编码。

由于 RISC V 支持 16 位倍数(两个字节)的指令,因此我们不能假设下一个 LSB 也为零,就像 MIPS(具有 32 位指令)一样。

寄存器操作数在JAL除了执行分支之外,还可以选择用于捕获返回地址。

JAL的功能是使用其 20 位范围执行相对较远的 pc 分支或调用。 (与 RISC V 条件分支指令相比,RISC V 条件分支指令只有 12 位,范围为 +/- 4 KB。)


JALR有一个 12 位偏移量和两个寄存器作为操作数。

其操作是pc := ( rs1 + sxt ( imm12 ) ) & -2.

从公式中可以看出,分支是寄存器间接的,相对于中的值rs1.

Like JAL, JALR还可以捕获返回地址。

JALR用于从函数返回(又名RET在装配中。在这种形式中,$ra 用作源寄存器,并且不捕获返回地址)。这使用零作为偏移量(即不需要偏移量)。

JALR还用于执行间接函数调用:通过函数指针、虚拟方法分派等进行调用。这些用途也使用零作为偏移量。

JALR也可以依次使用AUIPC.


AUIPC有一个 20 位偏移量和一个寄存器作为操作数。

其操作是rd := pc + ( imm20 << 12 ).

它计算 pc 相对立即数的上半部分(同时还提供非相对 pc 的下半部分)。

结合JALR,这可以完成 32 位 pc 相关的分支或调用。

AUIPC r5, labelFarAway      # AUIPC encodes upper 20 bits of label's distance from pc
JALR r5, $ra, labelFarAway  # JALR encodes the lower 12 bits of same
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RISC-V 中 JAL 和 JALR 指令的偏移地址 的相关文章

  • 如何在 AVX/AVX2 中递增向量

    我想使用内在函数来增加 SIMD 向量的元素 最简单的方法似乎是为每个元素加 1 如下所示 note vec inc之前已设置为1 vec mm256 add epi16 vec vec inc 但是是否有任何特殊指令来增加向量 类似于in
  • 气体:内存引用太多

    编译时指令如下 movl 4 ebp 8 ebp I got 内存引用过多 它出什么问题了 括号之前的数字是字节偏移量 这会导致发生内存引用 并且不能有两个movl 您需要先将值暂时移至寄存器 movl 4 ebp ecx movl ecx
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • 直接写入 ARM Cortex A8 分支预测器中的全局历史缓冲区 (GHB) 或 BTB?

    我有兴趣直接修改 Cortex A8 上的 BTB 分支目标缓冲区 和 GHB 的内容 ARM 手册上有这样的内容 要在指令端 GHB 数组中写入一项 例如 LDR R0 0x3333AAAA MCR p15 0 R0 c15 c1 0 M
  • 为什么将 char 传递给函数会改变它在 c 中的值?

    我目前正在关注本作业簿 http www cs bham ac uk exr lectures opsys 10 11 lectures os dev pdf关于构建操作系统 我的目的是写一个64位内核 我已经在文本模式下加载 内核 代码并
  • nasm/ld“重定位被截断以适合:R_386_16”

    集会 BITS 16 global start start mov ax 0x07C0 mov ds ax mov si hw call print string jmp print string mov ah 0x0E char lods
  • x86 程序执行期间方向标志 (DF) 的默认状态

    在反汇编中 我经常看到使用字符串操作指令而不考虑方向标志 DF 的状态 如下所示 or ecx 0FFFFFFFFh xor eax eax mov edi ebp repne scasb CLD or STD自函数开始以来未找到指令 也未
  • LDR指令如何将常量加载到寄存器中?

    我刚刚读了一本ARM指令书 看到一条指令我无法解释 It says LDR将 32 位常量加载到r0登记 LDR r0 pc const number 8 pc const number DCD 0xff00ffff 我不明白什么 pc c
  • 为什么 NASM 在使用有效的指令助记符作为操作数中的符号名称方面没有问题?

    我编写了以下简单程序 但 nasm 拒绝编译它 section text global start start mov rax 0x01 mov rdi 0x01 mov rsi str mov rdx 0x03 syscall mov r
  • 如何在 x86 汇编中编写自修改代码

    我正在考虑为我最近开发的一个业余爱好虚拟机编写一个 JIT 编译器 我了解一些汇编语言 我主要是一名 C 程序员 我可以阅读大多数汇编语言并参考我不理解的操作码 并编写一些简单的程序 但是我很难理解这几个示例我在网上找到的自我修改代码 这是
  • Linux 内核中是否使用了扩展指令集(SSE、MMX)?

    好吧 它们带来 至少应该带来 性能的巨大提升 不是吗 所以 我还没有看到任何 Linux 内核源代码 但很想问 它们是否以某种方式被使用 在这种情况下 对于没有此类指令的系统 必须有一些特殊的 代码上限 SSE 和 MMX 指令集在音频 视
  • 本机代码、机器代码和汇编代码有什么区别?

    我对 NET 语言上下文中的机器代码和本机代码感到困惑 它们之间有什么区别 它们是一样的吗 这些术语确实有点令人困惑 因为它们有时使用不一致 机器代码 这是定义最明确的一种 它是使用字节码指令的代码 您的处理器 执行实际工作的物理金属部件
  • 为什么每次在 GDB 中构建和反汇编函数时都会得到相同的地址?

    每次反汇编函数时 为什么总是得到相同的指令地址和常量地址 例如 执行以下命令后 gcc o hello hello c ggdb gdb hello gdb disassemble main 转储代码将是 当我退出 gdb 并重新反汇编 m
  • 汇编:使用数据段寄存器(DS)

    目前我正在学习 x86 汇编 因为我喜欢微控制器编程 所以我熟悉汇编 目前我一直在到处寻找这个问题的答案 但似乎找不到它 DS寄存器 我知道它应该指向我程序中的全局数据 但我不知道知道它到底是如何工作的 我正在使用 NASM 在大多数简单的
  • 两个 16 位数字相乘 - 为什么结果是 32 位长? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如果我将两个 16 位数字相乘 结果将是 32 位长 但为什么会这样呢 对此有何明确解释 为了我的正确理解 其计算方法是 n 位数字乘以
  • 是否可以调用驻留在 exe 中的非导出函数?

    我想调用驻留在第 3 方 exe 中的函数并获取其结果 好像有should是一种方法 只要我知道函数地址 调用约定等 但我不知道如何 有谁知道我会怎么做 我意识到任何解决方案都是非标准的黑客 但有must成为一种方式 我的非恶意用例 我正在
  • 如果没有按下任何键,则检查按键而不阻塞

    我正在创建一个应用程序来查看当前时间 并创建了一个循环来每秒更新时间 循环看起来像这样 UPDATE The code to be re executed JMP UPDATE 但我无法结束它 当我使用 MOV AH 00H INT 21H
  • 如何在 MOS 6502 的 asm 中创建延迟

    我是 ASM 新手 我正在尝试研究如何为以下代码创建延迟 org 1000 loop inc d021 jmp loop 我想评论已经足够清楚了 每帧更改颜色的代码示例 1 50 秒 sei enable interrupts loop1
  • 在 x86 汇编语言中获取文件大小的简单方法

    假设我已经在汇编中打开了一个文件 并且在寄存器 eax 中有该文件的文件句柄 我将如何获取文件的大小 以便为其分配足够的缓冲区空间 我在这里研究了另一个讨论 建议使用sys fstat 28 系统调用来获取文件统计信息但无法实现它 My a
  • 内存映射图形输出

    我正在探索使用内存映射图形绘制像素和线条 我在 Windows 的 Textpad 中使用 TASM 当我单击 运行 时 整个屏幕变成蓝色 就是这样 没有绘制像素 model small stack data saveMode db xVa

随机推荐