Код с использованием RIS C -V программы, которая дает наибольшее значение в последовательности - PullRequest
2 голосов
/ 02 февраля 2020

Вопрос в следующем:

Учитывая последовательность ненулевых целых чисел, за которой следует 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

однако ничего не работает, и мне нужна помощь, чтобы ответить на этот вопрос и как работает RIS C -V.

1 Ответ

0 голосов
/ 02 февраля 2020

Я думаю, что вы планируете использовать регистры:

  • 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, 8. Чего не хватает между этими двумя инструкциями после метки skip, так это кода для обновления текущего максимального значения, видимого на данный момент, то есть инструкции для перемещения содержимого с x5 на x7. Операнды x5 и x7 инструкции 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 (текущее значение считано), код для обновления максимума пропускается.


Вместо двух инструкций ветвления в l oop: beq x5, x0, end, который завершает l oop, если в последовательности было достигнуто нулевое значение, и безусловный переход beq x0, x0, loop как последняя инструкция вашего l oop для повторения l oop, вы можете переставить свой код так, чтобы последняя инструкция l oop была:

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

Это заменит оба beq x5, x0, end и beq x0, x0, loop: если завершающее значение последовательности (т. Е. Ноль) было достигнуто, оно проваливается, в противном случае снова выполняется итерация l oop.


Сохранение всех этих На ваш взгляд, ваш код может выглядеть так:

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
...