使用 RISC-V 的代码 给出序列中最大值的程序
Code using RISC-V a program that gives the largest value in a sequence
问题是:
给定一个非零整数序列,后跟 0,找到最大的整数
在序列中并将结果放在 x5
中。
使用 DD
汇编命令存储在
内存的开始 -1、55、-3、7、0 的初始测试序列。
我试过多种变体:
src: DD -1, 5, -3, 7, 0
add x6, x0, x0
loop: ld x5, src(x6)
sd x7, dst(x6)
beq x5, x0, end
bge x5, x7, skip
skip: addi x6, x6, 8
beq x0, x0, loop
end: ebreak x0, x0, 0
dst: DM 1
但是,没有任何效果,我需要一些帮助来了解如何回答这个问题以及 RISC-V 的工作原理。
我认为您对寄存器的预期用途是:
x5
包含从序列 读取的当前值。
x6
包含 序列中的索引 .
x7
包含 目前看到的最大值。
不需要在内存中存储x7
,因为最大值在任何时刻都是单个值。寄存器x7
应该在一开始就初始化。
x7
可以用它可以容纳的最低可能值进行初始化,即 -263:
addi x7, x0, 1
slli x7, x7, 63
从序列中读取的任何值而不是这个最低可能值都会导致更新当前最大值。
或者,您可以直接将序列的第一个元素加载到 x7
中,因为总是有一个元素可用于加载(如果它是空序列,则终止 0
):
ld x7, sr(x6)
您的代码中的以下分支指令:
bge x5, x7, skip
skip: addi x6, x6, 8
无论条件是否成立(x5
>=x7
),下一条执行的指令总是addi x6, x6, 8
。在 skip
标签之后,这两条指令之间缺少的是更新目前看到的当前最大值的代码,即,将内容从 x5
移动到 x7
的指令. bge
指令的操作数 x5
和 x7
也必须交换,因为你想 跳过 更新最大值的代码 x7
>= x5
成立(即,当 maximum 已经大于或等于 当前值):
bge x7, x5, skip # skip the update of the maximum?
addi x7, x5, 0 # update new maximum value
skip: addi x6, x6, 8
因此,如果分支条件确实成立,即如果 x7
(最大值)大于或等于到x5
(当前值阅读),跳过更新最大值的代码。
而不是在循环中有两条分支指令:beq x5, x0, end
如果已经达到序列中的零值则终止循环,无条件跳转beq x0, x0, loop
作为循环的最后一条指令你的循环重复循环,你可以重新排列你的代码,使循环的最后一条指令是:
bne x5, x0, loop # is the end of the sequence not reached yet?
这将同时替换 beq x5, x0, end
和 beq x0, x0, loop
:如果已达到序列的终止值(即零),则它会失败,否则,它会再次迭代循环。
记住所有这些事情,您的代码可能如下所示:
src: DD -1, 5, -3, 7, 0
add x6, x0, x0 # initialize the index
ld x7, sr(x6) # initialize the maximum
addi x5, x7, 0 # initialize with the first value
beq x5, x0, end # is the sequence empty?
loop: bge x7, x5, skip # skip the update of the maximum?
addi x7, x5, 0 # update the maximum with the new value read
skip: addi x6, x6, 8 # update the index
ld x5, sr(x6) # load the next value from the sequence
bne x5, x0, loop # is the end of the sequence not reached yet?
end:
addi x5, x7, 0 # place the final result in x5 (your problem's assignment)
ebreak x0, x0, 0
问题是:
给定一个非零整数序列,后跟 0,找到最大的整数
在序列中并将结果放在 x5
中。
使用 DD
汇编命令存储在
内存的开始 -1、55、-3、7、0 的初始测试序列。
我试过多种变体:
src: DD -1, 5, -3, 7, 0
add x6, x0, x0
loop: ld x5, src(x6)
sd x7, dst(x6)
beq x5, x0, end
bge x5, x7, skip
skip: addi x6, x6, 8
beq x0, x0, loop
end: ebreak x0, x0, 0
dst: DM 1
但是,没有任何效果,我需要一些帮助来了解如何回答这个问题以及 RISC-V 的工作原理。
我认为您对寄存器的预期用途是:
x5
包含从序列 读取的当前值。x6
包含 序列中的索引 .x7
包含 目前看到的最大值。
不需要在内存中存储x7
,因为最大值在任何时刻都是单个值。寄存器x7
应该在一开始就初始化。
x7
可以用它可以容纳的最低可能值进行初始化,即 -263:
addi x7, x0, 1
slli x7, x7, 63
从序列中读取的任何值而不是这个最低可能值都会导致更新当前最大值。
或者,您可以直接将序列的第一个元素加载到 x7
中,因为总是有一个元素可用于加载(如果它是空序列,则终止 0
):
ld x7, sr(x6)
您的代码中的以下分支指令:
bge x5, x7, skip
skip: addi x6, x6, 8
无论条件是否成立(x5
>=x7
),下一条执行的指令总是addi x6, x6, 8
。在 skip
标签之后,这两条指令之间缺少的是更新目前看到的当前最大值的代码,即,将内容从 x5
移动到 x7
的指令. bge
指令的操作数 x5
和 x7
也必须交换,因为你想 跳过 更新最大值的代码 x7
>= x5
成立(即,当 maximum 已经大于或等于 当前值):
bge x7, x5, skip # skip the update of the maximum?
addi x7, x5, 0 # update new maximum value
skip: addi x6, x6, 8
因此,如果分支条件确实成立,即如果 x7
(最大值)大于或等于到x5
(当前值阅读),跳过更新最大值的代码。
而不是在循环中有两条分支指令:beq x5, x0, end
如果已经达到序列中的零值则终止循环,无条件跳转beq x0, x0, loop
作为循环的最后一条指令你的循环重复循环,你可以重新排列你的代码,使循环的最后一条指令是:
bne x5, x0, loop # is the end of the sequence not reached yet?
这将同时替换 beq x5, x0, end
和 beq x0, x0, loop
:如果已达到序列的终止值(即零),则它会失败,否则,它会再次迭代循环。
记住所有这些事情,您的代码可能如下所示:
src: DD -1, 5, -3, 7, 0
add x6, x0, x0 # initialize the index
ld x7, sr(x6) # initialize the maximum
addi x5, x7, 0 # initialize with the first value
beq x5, x0, end # is the sequence empty?
loop: bge x7, x5, skip # skip the update of the maximum?
addi x7, x5, 0 # update the maximum with the new value read
skip: addi x6, x6, 8 # update the index
ld x5, sr(x6) # load the next value from the sequence
bne x5, x0, loop # is the end of the sequence not reached yet?
end:
addi x5, x7, 0 # place the final result in x5 (your problem's assignment)
ebreak x0, x0, 0