Assembly 维纳斯RISC-V如何循环、比较和打印?
我试图循环通过一个数组,如果该数字大于X,则打印 我试着在网上找到教程,但我只是被困在为什么它不能工作/输出任何东西上。我的评论可以解释我想做什么Assembly 维纳斯RISC-V如何循环、比较和打印?,assembly,riscv,Assembly,Riscv,我试图循环通过一个数组,如果该数字大于X,则打印 我试着在网上找到教程,但我只是被困在为什么它不能工作/输出任何东西上。我的评论可以解释我想做什么 .data arrayOfNums: .word 0 .word 1 .word 122 .word 1112 .word 4294967295 .word 22 .word 234234 .word 23332 .word 42 .word 23423 K: .word 2237 .text .globl main main: ####
.data
arrayOfNums:
.word 0
.word 1
.word 122
.word 1112
.word 4294967295
.word 22
.word 234234
.word 23332
.word 42
.word 23423
K: .word 2237
.text
.globl main
main:
#### *** vv My problem starts here vv *** ####
la t0 K #set t0 to K
la t1 arrayOfNums #set t1 pointer to array
addi a1 t0 0 #add t0 deallocated to a1
addi a2 t1 0 #add t1 deallocated to a2
loop:
addi a0 x0 1 # print_int ecall
addi a1 t1 0 # add t1 value to print
ecall
addi t1, t1, 4 # Increments t1 to move to the next element
jal x0, loop
exit:
####Exit using environmental calls####
addi a1 x0 0 # random exit 0
addi a0 x0 17 # print_int ecall
ecall
谢谢大家! 您发布的代码存在一些问题 我试图循环通过一个数组,如果该数字大于X,则打印 我在你的代码中找不到任何X符号。你是说
K
评论是错误的。将K的地址加载到t0
中。如果要将存储在该地址的值加载到t0
中,则必须将该地址加载到另一个寄存器中,并将该地址解引用到t0
,即使用lw
或lwu
指令加载该地址
“转让给”是什么意思?您将t0
复制到a1
并将t1
复制到a2
。同样可以使用mv
伪指令归档。但是,这两行是多余的,因为您会立即覆盖以下行中的a1
和a2
寄存器
您可以在此处使用li
/mv
伪指令。这将无条件地打印t1
-的值,这是一个地址。如果要打印实际数组元素,必须使用t1
-cf.中存储的地址加载它。参见lw
/lwu
说明
这样,您就可以无条件跳转到循环的头部(使用伪指令:j loop
),也就是说,这意味着您读取了数组的末尾,并且永远不会退出循环。要解决此问题,必须使用条件分支指令,如bnez
。这意味着您将寄存器(作为计数器)设置为数组大小,并将其递减至零。或者将寄存器设置为最后一个数组元素和分支后的地址,直到t1
等于它
这绝对不是随机的。注释不正确,您正在调用Venus exit2系统调用,而不是print_int。此外,Venus还提供了一个不需要参数的exit系统调用(10
)
代码中完全缺少的是一个位置,您实际上正在尝试比较数字,然后根据比较结果打印它们。值得一提的是,
Venus
是一个RISC-V模拟器,提供一些自定义系统调用:
la t0 K #set t0 to K
addi a1 t0 0 #add t0 deallocated to a1
addi a2 t1 0 #add t1 deallocated to a2
addi a0 x0 1 # print_int ecall
addi a1 t1 0 # add t1 value to print
ecall
addi t1, t1, 4 # Increments t1 to move to the next element
jal x0, loop
addi a1 x0 0 # random exit 0
addi a0 x0 17 # print_int ecall
ecall