小编ElP*_*roo的帖子

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

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

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

  2. 将 LSB 设置为零。

关于这个,我有几个问题。

问题 1

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

000000000000 to 111111111110
Run Code Online (Sandbox Code Playgroud)

也就是说,4KiB。

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

[000000000000]0 to [111111111111]0      
Run Code Online (Sandbox Code Playgroud)

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

  1. 左移一点点给出地址。

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

问题2

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

riscv

6
推荐指数
1
解决办法
2194
查看次数

汇编中main函数开头的栈内存操作

我把一个很简单的C程序转成汇编文件(这里是RISC-V ISA),在堆栈指针上做了一些我不明白的操作。

C程序:

int main()
{
        int a = 10;
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

相关的汇编代码:

        .file   "alternating_branches_2.c"
        .option nopic
        .text
        .align  1
        .globl  main
        .type   main, @function
main:
        addi    sp,sp,-32
        sd      s0,24(sp)
        addi    s0,sp,32
        li      a5,10
        sw      a5,-20(s0)
        li      a5,0
        mv      a0,a5
        ld      s0,24(sp)
        addi    sp,sp,32
        jr      ra
        .size   main, .-main
        .ident  "GCC: (GNU) 8.3.0"
Run Code Online (Sandbox Code Playgroud)

这是我的理解。

sp 包含堆栈内存的最后一个地址。因此,压入堆栈会降低 sp 的值。s0 是帧指针,指向 sp 的前一个值。

在第一行中,从堆栈指针开始减少 32 的偏移量。这是要创建堆栈帧吗?通常,在堆栈中,推送操作会减少堆栈指针。但是,既然已经创建了一个栈帧,现在sp指向栈的下层内存,push会增加sp的值吗?

-------------| <--sp
-------------|
-------------|
-------------|
-------------|
-------------|
-------------|
Run Code Online (Sandbox Code Playgroud)

创建堆栈帧后:

-------------| <--s0
-------------|
-------------|
-------------|
-------------| …
Run Code Online (Sandbox Code Playgroud)

assembly callstack riscv

5
推荐指数
1
解决办法
652
查看次数

标签 统计

riscv ×2

assembly ×1

callstack ×1