assembly - 如果我想将用户输入存储在 Risc-v 的数组中,如何存储值并进行比较
问题描述
如果我想将用户输入存储在 risc-v 中的数组中,如何存储值并进行比较
例如在 mips 我可以这样做:
addi $t1,$v0,0
sw $t1,array($t0)
addi $t0,$t0,4
然后像这样比较它:
lw $t2,array($t3)
beqz $t2,label # if t2 = 0 then go to label
addi $t3,$t3,4
解决方案
sw
您在 MIPS 上使用的是伪指令。伪指令在实际 MIPS 机器代码中扩展为两三条指令:这些指令通过一个寄存器相互连接,即$at
——汇编器临时寄存器。
您使用的确切形式是 3 条指令;它扩展到
lui $at, %hi(array)
addu $at, $at, $t0
sw $t1, %lo(array)($at)
RISC V 清理了 MIPS 的许多寄存器使用,包括删除为汇编程序保留的临时寄存器。他们还将参数寄存器的数量从 MIPS 的 4 增加到 8,同时删除了为操作系统保留的寄存器$k0
& $k1
。此外,它们使用与前两个参数相同的a0
和a1
作为返回值。因此,RISC V 具有更有用的寄存器集。
除了一些伪指令之外,您可以在 RISC V 中执行与在 MIPS 中相同的操作。加载伪指令可以工作,使用加载目标作为中间寄存器来连接两条指令,但一些汇编程序也不会接受它。但是没有可用的临时寄存器供汇编器用于存储伪指令扩展,因此不支持。
因此,您必须避免sw
伪指令。您可以改用直接指针,它也更有效,因为(在我的示例中,在循环内)这些只是直接指令而不是多指令序列。然后,您可以将 与 分开la
,sw
例如将其移出循环。
la t0, array
...
loop:
sw t1, 0(t0) # or sw t1, (t0)
addi t0, t0, 4
...
beqz t2, loop
此外,不要$
在某些 RISC V 汇编器中使用寄存器名称。
如果您想使用sw
带有全局数组和寄存器偏移量的 MIPS 伪指令:
sw $t1, array($t0) # expands to three instructions, also sets & uses `$at`
addi $t0, $t0, 4
...
您可以替换为以下内容:
la $t7, array # pick a free temp register
add $t7, $t7, $t0
sw $t1, 0($t7)
...
当然,这里的观察是,如果您有另一个寄存器可用于更长时间的使用,您可能会将数组的地址保留在该寄存器中一段时间,以便您可以根据需要重用它。
推荐阅读
- javascript - 字体加载和页面加载时如何避免页面跳转和FOUT
- java - 如何在终端中访问 Java 属性
- reporting-services - 更改行的背景颜色,同时排除隐藏的行
- c# - 如何让消费者从最后一条未消费的消息开始?
- filtering - 将 Algolia 中的建议限制为邮政编码
- javascript - 在javascript中命名它的最佳做法是什么?
- python - Keras 加权嵌入层
- entity-framework - 如果使用 $top,带有 EF Core 的 AutoMapper 不会正确返回 OData @count
- azure - 使用 IoT DPS 通过 CreateOrUpdateIndividualEnrollmentAsync 更新设备时出错
- android - 使用 gstreamer 在 android 上录制音频(使用 Qt5)