RISC-V:PC 绝对值与 PC 相对值

2023-11-25

我是 RISC-V 新手。

我无法理解何时写入 PC(程序计数器)相对指令以及何时写入 PC 绝对指令。

例如,一条指令lui其次是jalr考虑指令PC-绝对,以及一条指令auipc其次是jalr考虑指令相对于PC.

据我了解,所有指令都将由 PC 执行,因此执行此类 PC 绝对指令似乎是隐藏的(即在 PC 不知情的情况下)。

对我来说,那些 PC 绝对指令将不会被执行。

有人可以提供一些基本的例子来帮助我理解这一点吗?


我认为你遇到的问题是“PC-absolute”这个概念,这实际上并不是一个东西。您的选项是“相对电脑”和“绝对”。 RISC-V 定义了两个寻址指令,可以有效地实现这些模式:

  • lui(加载上立即数):这组rd为 32 位值,低 12 位为 0,高 20 位来自 U 型立即数。
  • auipc(将上立即数添加到程序计数器):此设置rd为当前 PC 与一个 32 位值之和,其中低 12 位为 0,高 20 位来自 U 型立即数。

这些指令本质上是相同的:它们都采用 U 型立即数(即 32 位量的高 20 位),将其添加到某些内容,并产生结果rd。不同之处在于lui将立即添加到0, while auipc将其立即添加到 PC 中。有时,更容易将两种寻址模式视为“PC 相对”和“0 相对”,因为这使得区别更加明确。

虽然两者auipc and lui由于第二条指令被设计为双指令对中的第一条指令,因此并不是特别相关。两个都auipc and lui填充 32 位地址的高 20 位,让它们配对的指令填充低 12 位。 I 和 S 格式的指令被设计为可以很好地配对,并且基本 ISA 中的每条指令都有一个 I 或 S 变体,这种格式是有意义的。

作为一个具体的例子,下面的 C 代码执行一个非常简单的

int global;
int func(void) { return global; }

例如,假设 global 位于 0x20000004,func 中第一条指令的 PC 为 0x10000008。

当编译时-mcmodel=medlow(0-相对寻址模式),你会得到

func:
    lui a0, 0x20000
    lw  a0, 0x004(a0)

正如你所看到的,全局的完整绝对地址(0x2000004)被填充到指令对中。另一方面,当编译时-mcmodel=medany(PC相对寻址模式)你会得到

func:
    auipc a0, 0x10000
    lw    a0, 0x004(a0)

这次,只有 PC 之间的偏移量auipc目标符号出现在指令对中。发生这种情况是因为 PC 明确地(通过使用auipc指令)包含在寻址计算中。在这种情况下,即auipc正在设置a0 to 0x2000004:执行的计算是a0 = PC + (imm20 << 12),这里我们有0x10000004对于 PC 和0x10000 for imm20.

这些与 PC 相关的寻址序列还允许一定程度的位置独立性:如果您非常小心地限制正在执行的操作,则可以生成链接的二进制文件,这些二进制文件在以与链接位置不同的偏移量加载时仍然可以工作。实际上,这对于 POSIX 风格系统中完全位置无关的寻址来说是不够的(这就是为什么我们还有一个-fPIC争论,就像其他人一样),但如果您处于严格约束的嵌入式系统中,您可能能够摆脱它。

对于最后的问题,就像 RISC-V ISA 中的几乎所有其他内容一样,auipc and lui符号扩展为 XLEN。在 32 位系统上,这些寻址模式可以生成系统中的任何地址,但 64 位系统则不然。这就是为什么我们将这些寻址模式称为“medany”和“medlow”:“med”代表“medium”,这意味着所有全局符号都必须适合一个 4GiB 窗口。 “低”部分意味着该窗口以绝对地址 0 为中心,而“任意”部分则意味着该窗口以所链接的任何 PC 为中心。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RISC-V:PC 绝对值与 PC 相对值 的相关文章

  • 在 NASM 中使用 istruc 时:“警告:尝试初始化 BSS 部分‘.bss’中的内存:忽略 [-w+other]”

    在搜索这个错误时我发现this https stackoverflow com questions 65731514 nasm attempt to initialize memory in bss section 77001709问题 但
  • 如何在汇编程序中使用 C 库?

    我想知道如何用汇编语言编写文本编辑器 但现代操作系统需要 C 库 特别是对于它们的窗口系统 我找到了这个page http pengu1n is programmer com posts 8304 html 这对我有很大帮助 但我想知道是否
  • arm-thumb指令集的blx指令如何支持4MB范围

    读自https www keil com support man docs armasm armasm dom1361289866046 htm https www keil com support man docs armasm arma
  • C/C++ 中的简单“Hello World”内联汇编语言程序

    我使用 devcpp 和 borland c 编译器 asm mov ax 4 I O Func mov bx 1 Output func mov cx name address of the string mov dx 6 length
  • 装配中出现奇怪的字符?

    我写了以下代码 386 model small stack 100h data text db Paper 0 code start lea dx text mov ah 9h int 21h mov ah 4ch int 21h end
  • 为什么我可以使用 ret 退出 main?

    我即将弄清楚程序堆栈到底是如何设置的 我了解到用以下方式调用该函数 call pointer 实际上等同于 mov register pc programcounter add register 1 where 1 is one instr
  • x86-64 上这个语句有什么问题?

    该函数的目的是获取堆栈的起始地址 unsigned long find start void asm movq rsp eax 当我编译它时 出现错误 Error suffix or operands invalid for movq mo
  • C++ 中的 CPUID 实现

    我想知道这里是否有人有一些可以从任何托管 net 语言引用的 C CPUID 实现的好示例 另外 如果情况并非如此 我是否应该注意 X86 和 X64 之间的某些实现差异 我想使用 CPUID 来获取运行我的软件的机器上的信息 崩溃报告等
  • Clang 使用 -nostdlib 生成崩溃代码

    我正在尝试为可执行文件设置自己的运行时环境 但无法使用 clang v3 4 1ubuntu1 目标 x86 64 pc linux gnu 来生成没有段错误的可执行文件 我已将问题简化为以下内容 如果我有一个文件 crt1 c 除了满足
  • 取消的分支与常规分支有何不同?

    特别是对于 SPARC Assembly 取消的分支与常规分支有何不同 我一直认为 当我需要填充分支指令的 nop 延迟槽时 需要取消分支指令 但是 我认为我在这一部分上是不正确的 因为您可以在不取消分支的情况下填充 nop 如果不采用分支
  • 为什么不能执行 mov [eax], [ebx] [重复]

    这个问题在这里已经有答案了 我可以做这个 mov eax ebx 和这个 mov eax ebx 甚至这个 mov eax ebx 但不是这个 错误C2415 mov eax ebx 只是wtf 为什么 它与 ptr1 ptr2 相同 为什
  • CALL指令是否总是将EIP指向的地址压入堆栈?

    x86架构中函数调用时是否存在返回地址不入栈的情况 No CALL根据定义 将在跳转到目标地址之前将返回地址压入堆栈 该返回地址是EIP or RIP sizeof call instruction 通常为 5 个字节 英特尔 64 和 I
  • NASM 轮班操作员

    您将如何在寄存器上进行 NASM 中的位移位 我读了手册 它似乎只提到了这些操作员 gt gt lt lt 当我尝试使用它们时 NASM 抱怨移位运算符处理标量值 您能解释什么是标量值并举例说明如何使用 gt gt and lt lt 另外
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 两个基本的 ANTLR 问题

    我正在尝试使用 ANTLR 来获取简单的语法并生成汇编输出 我在 ANTLR 中选择的语言是 Python 许多教程看起来非常复杂或详细阐述与我无关的事情 我真的只需要一些非常简单的功能 所以我有两个问题 将值从一个规则 返回 到另一规则
  • 弹出 x86 堆栈以访问函数 arg 时出现分段错误

    我正在尝试链接 x86 程序集和 C 我的C程序 extern int plus 10 int include
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • 从 exe 文件中获取汇编级代码?

    我当时正在做linux汇编编程 在过去的几天里我已经转而学习windows汇编编程 我在用ml作为我的汇编器和golink作为我的链接器 我有我的汇编代码并已获得我的exe从中 现在我需要取回它的十六进制 xff xab x55等等 在li
  • 使用 NEON 优化 Cortex-A8 颜色转换

    我目前正在执行颜色转换例程 以便从 YUY2 转换为 NV12 我有一个相当快的函数 但没有我预期的那么快 主要是由于缓存未命中 void convert hd uint8 t orig uint8 t result uint32 t wi
  • 阴影空间示例

    EDIT 我接受了下面的答案 并添加了我自己的代码的最终修订版 希望它向人们展示影子空间分配的实际示例 而不是更多的文字 编辑 2 我还设法在 YouTube 视频 所有内容 的注释中找到了一个调用约定 PDF 的链接 其中有一些关于 Li

随机推荐

  • 在 PHP 和 MySQL 中创建不带 HTTPS 的安全登录脚本

    Question Is 维基百科上的这篇文章在 PHP 和 MySQL 中创建安全登录脚本的好参考 在警告部分 作者强调该代码只能与 HTTPS 一起使用 我无法使用 HTTPS 但需要在 PHP 和 MySQL 中实现相对安全的登录脚本
  • C# 事件删除语法

    我对 C 中删除事件处理程序的语法感到困惑 Something new MyHandler HandleSomething add Something new MyHandler HandleSomething remove new 在每一
  • 两个 PCI 设备之间直接通信

    我有一个 NIC 卡和一个 HDD 它们都连接在 Linux 机器的 PCIe 插槽上 理想情况下 我希望将传入数据包传输到 HDD 而不涉及 CPU 或最少涉及 CPU 是否可以像这样沿着 PCI 总线建立直接通信 有谁知道要阅读什么内容
  • 从命令行运行 JUnit 测试套件

    如何从命令行运行 Junit 4 8 1 测试套件 另外我想使用 JUnit 4 8 引入的类别 有没有办法 我可以从命令行指定我想要运行的类别 Using java run JUnit核心类 另见here 类别应该与测试套件一起使用 Ru
  • JavaScript 中的 URL 帮助器

    我正在使用 jQuery Lightbox 作为我的图片库 按钮图像的 URL 是 Content Lightbox lightbox btn next gif 如果我的网址是 localhost Something1 Somtehing2
  • Visual Studio 2012 中缺少 Visual C++ 的先决条件

    我最近安装了vs2012我已经更新了我的 ClickOnce 应用程序 更准确地说 我第一次打开我的C project 这取决于我的主要 c 项目 我还没有更新它 一切都工作正常 VS 2012仍然能够看到 Visual C 2010 先决
  • 如何在java中打印给定整数a = 1234的最后两位数字

    如果我给出像 a 1234 这样的值 我只想打印最后两位数字 34 任何人都可以给我解决这个问题 int a 1234 System out print a number 100结果是最后 2 位数字 See ideone演示
  • 如果不向数据库(例如 SQL Server)提交事务会发生什么?

    假设我有一个查询 begin tran some other sql code 然后我忘记提交或回滚 如果另一个客户端尝试执行查询 会发生什么 只要你不COMMIT or ROLLBACK一个事务 它仍然在 运行 并且可能持有锁 如果您的客
  • FTP 协议中有类似 HTTP Range 标头的内容吗?

    假设我只想通过 FTP 传输文件的一部分 是否可以使用标准 FTP 协议 在 HTTP 中我可以使用范围标头在请求中指定远程资源的数据范围 如果是 1mb 文件 我可以要求 600k 到 700k 之间的字节 FTP中有类似的东西吗 我在读
  • 实体框架 4 - ApplyCurrentValues 与 ObjectStateManager.ChangeObjectState

    我们有一个 WCF 服务 其更新方法可以更新数据库中的客户 此方法从客户端获取一个分离的实体 void UpdtaeCustomer Customer detachedCustomer 我们想出了两种编写此方法的方法 1 context C
  • PDF打印视图问题

    我尝试过两种方式 1 正在创建一个WebView并加载我的pdf文档 我的应用程序几乎完成了打印过程的一部分 但在这方面我面临着打印问题 它没有完整的 A4 表格视图 任何人都可以帮忙吗 我使用了以下代码 public void creat
  • 标准化 Python Pandas 数据框中的一些列?

    下面的Python代码只返回一个数组 但我希望缩放后的数据替换原始数据 from sklearn preprocessing import StandardScaler df StandardScaler fit transform df
  • MVC 将数据从视图发送到控制器

    我对 MVC 3 还很陌生 我知道如何将强类型对象从控制器发送到视图 我现在拥有的是一个视图 其中包含一个由该数据组成的表 表单 用户可以在该视图 html 页面 中更改该数据 当他们单击 保存 时 如何将数据从视图发送回控制器 以便我可以
  • Java 和 C++ 运算符有什么区别吗?

    如果您采用 Java 的原始数字类型加上布尔值 并将其与 C 等效类型进行比较 那么运算符 例如优先级规则或位操作运算符的作用 是否存在任何差异 还是括号的作用 换句话说 如果我采用 Java 表达式并尝试在 C 中编译并运行它 它是否总是
  • 我应该使用 IIFE 还是 window onload 来初始化?

    以下两个代码片段均有效 在js文件中使用IIFE function initialize txtInput document getElementById txtInput txtResult document getElementById
  • 更改 tkinter 消息框按钮上的文字

    我使用 tkinter 的 askokcancel 消息框通过弹出窗口警告用户不可逆转的操作 from tkinter import Tk Tk withdraw from tkinter messagebox import askokca
  • C# Visual Studio GPIB 命令

    在 C Visual Studio 中使用什么命令与 GPIB 仪器进行通信 我需要能够向仪器写入命令并读取输出 I use 安捷伦 IO 库套件 这是在 C 上使用它的教程 C 中的 I O 编程示例 然而 在我的公司中 我们遇到了 VI
  • Popstate - 将弹出状态传递给事件处理程序

    以下代码应导致警报 1 但实际上什么也不执行 window onpopstate function event alert event state a history pushState a 1 history back Fiddle ht
  • 创建具有圆形区域边缘的 Voronoi 艺术

    I m trying to create some artistic plots like the ones below 区域的颜色并不重要 我想要实现的是沿着 Voronoi 区域的边缘的可变 厚度 特别是 它们看起来像一个更大的圆形斑点
  • RISC-V:PC 绝对值与 PC 相对值

    我是 RISC V 新手 我无法理解何时写入 PC 程序计数器 相对指令以及何时写入 PC 绝对指令 例如 一条指令lui其次是jalr考虑指令PC 绝对 以及一条指令auipc其次是jalr考虑指令相对于PC 据我了解 所有指令都将由 P