简体   繁体   中英

Code using RISC-V a program that gives the largest value in a sequence

The question is:

Given a sequence of non-zero integers followed by 0, find the biggest integer in the sequence and place the result in x5 . Use the DD assembler command to store in the beginning of the memory the initial test sequence of -1, 55, -3, 7, 0.

I have tried multiple variations of this:

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

however, nothing is working and I need some help on how to answer this question and how RISC-V works.

I think your intended use of the registers is:

  • x5 contains the current value read from the sequence .
  • x6 contains the index into the sequence .
  • x7 contains the maximum value seen so far .

There is no need to store x7 in memory since the maximum value is a single value at any moment. The register x7 should be initialized at the very beginning.

x7 could be initialized with the lowest possible value it can hold, ie, -2 63 :

addi x7, x0, 1
slli x7, x7, 63

Any value read from the sequence other than this lowest possible value would cause the current maximum to be updated.

Alternatively, you can directly load the first element of the sequence into x7 since there is always one element available for loading (the terminating 0 if it's an empty sequence):

ld x7, sr(x6)

The following branch instruction in your code:

        bge x5, x7, skip
skip:   addi x6, x6, 8

Regardless of whether or not the condition holds ( x5 >= x7 ), the next instruction executed is always addi x6, x6, 8 . What is missing between these two instructions, after the skip label, is the code for updating the current maximum value seen so far, ie, an instruction for moving the contents from x5 to x7 . The operands x5 and x7 of the bge instruction must also be swapped since you want to skip the code for updating the maximum when x7 >= x5 holds (ie, the maximum isn't updated when the maximum is already greater or equal to the current value ):

        bge x7, x5, skip # skip the update of the maximum?
        addi x7, x5, 0   # update new maximum value
skip:   addi x6, x6, 8

Therefore, if the branching condition does hold, ie, if x7 (the maximum) is greater or equal to x5 (the current value read), the code for updating the maximum is skipped.


Instead of having two branch instruction in the loop: the beq x5, x0, end that terminates the loop if the zero value has been reached in the sequence, and the unconditional jump beq x0, x0, loop as the last instruction of your loop for repeating the loop, you could rearrange your code so that the loop's last instruction is:

bne x5, x0, loop   # is the end of the sequence not reached yet?

This would replace both beq x5, x0, end and beq x0, x0, loop : if the terminating value of the sequence (ie, zero) has been reached it falls through, otherwise, it iterates the loop again.


Keeping all these things in mind, your code could look like:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM