温馨提示:本文翻译自stackoverflow.com,查看原文请点击:assembly - Code using RISC-V a program that gives the largest value in a sequence
assembly riscv

assembly - 使用RISC-V进行编码的程序可以在序列中提供最大值

发布于 2020-04-11 14:19:24

问题是:

给定一个非零整数序列,后跟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如何工作的帮助。

查看更多

提问者
Hani Salehi
被浏览
130
眠りネロク 2020-02-02 22:53

我认为您对寄存器的预期用途是:

  • x5包含从序列读取当前值
  • x6包含序列索引
  • x7包含到目前为止所看到最大值

x7由于最大值随时都是单个值,因此无需存储在内存中。寄存器x7应在开始时进行初始化。

x7可以使用它可以保持的最低值进行初始化,即-2 63

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, 8skip标签之后,这两个指令之间缺少的是用于更新到目前为止所看到的当前最大值的代码,即,用于将内容从x5移至的指令x7操作数x5x7的的bge指令也必须换,因为你想跳过的代码更新最大的时候x7 > = x5成立(即当没有更新最大最大的已经是大于或等于当前值):

        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, endbeq 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