我是RISC-V的新手。
我在理解何时编写PC(程序计数器)相关指令以及何时编写PC绝对指令方面遇到困难。
例如,使用 lui 后跟 jalr 的指令被认为是 PC绝对,而使用 auipc < / strong>后跟 jalr 指令被视为相对于PC 。
据我了解,所有指令都将由PC执行,因此执行此类PC绝对指令似乎是隐藏的(即,在不了解PC的情况下)。
对我来说,那些PC绝对指令将不会执行。
有人可以提供一些基本示例来帮助我理解吗?
答案 0 :(得分:2)
相对于PC
绝对
如果相对于代码本身的地址计算地址,则称某些指令(或代码)为“ PC相对”。
当未计算相对于指令本身地址的地址时,您将指令称为“绝对”。
不幸的是,我不了解RISC V CPU,但是下面的(旧)68000 CPU示例显示了您的意思:
x:
lea.l (PC+y-x-2), a0
lea.l (y).l, a0
...
y:
两条指令都将地址y
加载到寄存器a0
中。
但是有区别:
假设代码位于地址0x1000,地址y
位于地址0x2000。
现在,我们将代码移至地址0x1200,然后在此处执行代码。会发生什么?
第一条指令会将地址0x2200加载到寄存器:
该地址是相对于指令地址的 计算的:它计算为(address of the instruction)+0x1000
。而且由于该指令现在位于地址0x1000而不是0x1200,因此要写入寄存器的值将是0x2200,而不是0x2000。
这称为(PC)相对寻址。
第二条指令会将地址0x2000加载到寄存器中。它总是将值0x2000加载到寄存器中-指令本身的地址无关紧要。
这称为绝对寻址。
答案 1 :(得分:2)
我认为您遇到的问题是“绝对PC”的概念,这实际上不是问题。您可以选择“相对PC”和“绝对”。 RISC-V定义了两个寻址指令,可以有效地实现这些模式:
lui
(立即加载上限):将rd
设置为32位值,其中低12位为0,高20位来自U型立即数。auipc
(在程序计数器中添加高位立即数):这会将rd
设置为当前PC与一个32位值之和,低12位为0,高20位为后从U型即时开始。这些指令本质上是相同的:它们都采用U型立即数(即32位数量的高20位),将其加到某个东西上,并在rd
中产生结果。区别在于lui
将该立即数添加到0
,而auipc
将该立即数添加到PC。有时,将两种寻址模式分别认为是“相对于PC”和“相对于0”是比较容易的,因为这样会使区分更加明确。
虽然auipc
和lui
都设计为在两个指令对中用作第一条指令,但第二条指令并不是特别相关。 auipc
和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, 0x008(a0)
如您所见,全局(0x2000004)的完整绝对地址已填充到指令对中。另一方面,使用-mcmodel=medany
(相对于PC的寻址模式)进行编译时,您会得到
func:
auipc a0, 0x10000
lw a0, 0x004(a0)
这一次,仅auipc
的PC与目标符号之间的偏移出现在指令对中。发生这种情况是因为PC已明确(通过使用auipc
指令)包含在寻址计算中。在这种情况下,auipc
将a0
设置为0x2000004
:执行的计算是a0 = PC + (imm20 << 12)
,这里我们有0x10000004
用于PC和{{1 }} 0x10000
。
这些相对于PC的寻址序列还允许一定程度的位置独立性:如果您非常谨慎地限制正在执行的操作,则可以生成链接的二进制文件,该二进制文件在以与它们的位置不同的偏移量加载时仍然可以工作。重新链接。在实践中,这不足以在POSIX风格的系统中进行完全独立于位置的寻址(这就是为什么我们像其他所有人一样也有一个imm20
自变量的原因),但是如果您处于严格受限的嵌入式系统中您也许可以摆脱它。
对于最后的皱纹,就像RISC-V ISA中的几乎所有其他内容一样,-fPIC
和auipc
使用的立即数被符号扩展为XLEN。在32位系统上,这些寻址模式可以在系统中生成任何地址,但对于64位系统则不是这样。这就是为什么我们将这些寻址模式称为“ medany”和“ medlow”:“ med”代表“ medium”的意思,这意味着所有全局符号必须适合的4GiB窗口。 “低”部分表示此窗口以绝对地址0为中心,而“任意”部分表示此窗口以其链接到的PC为中心。