【问题标题】:Loading Values to Register in RISC-V将值加载到 RISC-V 中的寄存器
【发布时间】:2019-09-22 04:14:31
【问题描述】:

只是希望有人帮助我将一些值加载到某些寄存器中。

任务是“指示编译器将 0x2222333344445555 和 0x1111222233334444 的值分别存储在地址 0x1000100010001000 和 0x1000100010001100 中。在运行时将值加载到寄存器 x6 和 x7...”。

通过阅读 PDF 文件提供的信息以及问题,到目前为止,我的代码如下所示:

ORG 0x1000100010001000
a: DD 0x2222333344445555

ORG 0x1000100010001100
b: DD 0x1111222233334444

【问题讨论】:

  • RISC-V 汇编器是否有像 la x6, a 这样的伪指令或将扩展为指令序列以在寄存器中生成静态地址的东西?如果是这样,请使用它,然后使用反汇编程序查看您得到了什么。甚至ld x6, a 构造一个静态地址。 (例如,使用地址的低几位作为寻址模式的一部分,而不是首先在寄存器中构造完整地址)。我忘记了 8 字节加载指令的 RISC-V 助记符; ld 是 MIPS64 助记符。
  • 哪个指令集 rv64i?
  • 是的,应该是 rv64i。好吧,我们使用的是双字,而不是单词 sold、sd 而不是 lw、sw 等。我也在使用 RISC-V 视觉模拟器 (RVS),因为这是我的教授告诉我们在课程中使用的。我确信有一种比我最初提供的更合适的方式来启动代码。对于这些问题,我们介绍了 DD、DM、ld、sd、ORG 等内容,如果有帮助的话。真的很想学习这一点,并试图找到好的资源来帮助我为这门课程打下基础。

标签: assembly riscv


【解决方案1】:

我假设这是 rv64i,当你问这样的 risc-v 问题时,你需要指定指令集。

你可以先让编译器指导你

void fun ( void )
{
    unsigned long long *a;
    a=0x1000100010001000;
    *a=0x2222333344445555;
    a=0x1000100010001100;
    *a=0x1111222233334444;
}

例如:

0000000000000000 <fun>:
   0:   10001737            lui x14,0x10001
   4:   02071793            slli    x15,x14,0x20
   8:   00000637            lui x12,0x0
   c:   97ba                    add x15,x15,x14
   e:   00063703            ld  x14,0(x12) # 0 <fun>
  12:   000006b7            lui x13,0x0
  16:   e398                    sd  x14,0(x15)
  18:   000007b7            lui x15,0x0
  1c:   0007b783            ld  x15,0(x15) # 0 <fun>
  20:   0006b703            ld  x14,0(x13) # 0 <fun>
  24:   e398                    sd  x14,0(x15)
  26:   8082                    ret

Disassembly of section .srodata.cst8:

0000000000000000 <.LC0>:
   0:   5555    
   2:   4444    
   4:   22223333

0000000000000008 <.LC1>:
   8:   1100    
   a:   1000    
   c:   1000    
   e:   1000    

0000000000000010 <.LC2>:
  10:   4444    
  12:   22223333
  16:   1111   

这显示了两种解决方案,在多个指令中建立价值。或者将值加载到寄存器中。

好的,是的,编译器使用的是 rv64ic,它在抱怨我的命令行,所以我使用了:

riscv64-none-elf-gcc -c -O2 so.c -o so.o

我构建了一个交叉编译器,如果你愿意,你可以使用 Godbolt。

lui 为您提供 20 位立即数。仅使用指令任何 64 位值将需要 3 luis,一些移位和 orring。还有一个addi或orri。然后使用 sd 进行双字(64 位)存储。

【讨论】:

  • 哇哇哇,等一下,在你的反汇编中,我在非 4 字节对齐的地址(如 0xe 和 0x12)处看到 4 字节指令,这是由于插入了没有填充的 2 字节指令引起的。我认为根据 RISC-V 规范 4 字节指令与 4 字节边界对齐?这是编译器错误吗?
  • 我认为这取决于变化。如果内核接受,未对齐(至少在半字边界上)指令是完全合法的。我最熟悉的核心是。虽然 rv32i 我认为确实有一些关于对齐的声明
  • 但是当您进入 rv32ic 添加压缩指令时,是否需要分散 nop 以使 32 位指令对齐?这就是为什么低位讲述了大部分关于指令的故事,所以我们可以混合和匹配 16、32 和 64 位指令......
  • 我(您)将不得不重新阅读规范,了解当您包含 rv32i 以外的指令时,对齐规则会消失吗? (相当肯定,但需要再次检查文本)。编写我最熟悉的核心的人是规范的贡献者,所以我认为它符合要求。并且 gcc 没有问题构建未对齐...
  • 我认为它们必须是 16 位/半字对齐
猜你喜欢
  • 2020-08-27
  • 2023-03-29
  • 2020-04-18
  • 1970-01-01
  • 2021-02-09
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
相关资源
最近更新 更多