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.