Рекурсивная программа в сборке RISC-V - PullRequest
0 голосов
/ 19 октября 2018

Я пытаюсь создать рекурсивную программу в RISC-V, но не могу получить ее, чтобы получить правильный результат.Похоже, что он вызывает себя только в два раза максимум, но я попытался запустить его на бумаге, и все кажется правильным:

addi x31, x0, 4
addi x30, x0, 2

addi x2, x0, 1600               //initialize the stack to 1600, x2= stackpointer
ecall x5, x0, 5                 //read the input to x5
jal x1, rec_func
ecall x0, x10, 2                //print the result
beq x0, x0, end

rec_func:
addi x2, x2, -16               //make room in stack
sd x1, 0(x2)                   //store pointer and result in stack
sd x10, 8(x2)
bge x5, x31, true             // if i > 3, then go to true branch
addi x10, x0, 1              // if i <= 3, then return 1
addi x2, x2, 16              // reset stack point
jalr x0, 0(x1)

true:
addi x5, x5, -2                // compute i-2
jal x1, rec_func                // call recursive func for i-2
ld x1, 0(x2)                    // load the return address
ld x10, 8(x2)                  // load result from last function call
addi x2, x2, 16                // reset stack point
mul x10, x10, x30               // multiply by 2
addi x10, x10, 1               // add 1
jalr x0, 0(x1)                 // return

end:

Это оригинальная логика программы:

if i<= 3 return 1
else return 2 * rec_func(i-2) +1

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

У меня сейчас работает.Внесенные мною изменения:

  • В той части, где я возвращал 1, я не загружал указатель стека обратного вызова
  • Я удалил сохранение x10в память, как @Michael указал, что я возвращал это, и мне это не нужно.

Финальный код выглядит так:

addi x31, x0, 4
addi x30, x0, 2

addi x2, x0, 1600               // initialize the stack to 1600, x2= stackpointer
ecall x5, x0, 5                 // read the input to x5
jal x1, rec_func
ecall x0, x10, 2                // print the result
beq x0, x0, end

rec_func:
    addi x2, x2, -8                 // make room in stack
    sd x1, 0(x2)                    // store pointer and result in stack
    bge x5, x31, true               // if i > 3, then go to true branch
    ld x1, 0(x2)
    addi x10, x0, 1                 // if i <= 3, then return 1
    addi x2, x2, 8                  // reset stack point
    jalr x0, 0(x1)

true:
    addi x5, x5, -2                 // compute i-2
    jal x1, rec_func                // call recursive func for i-2
    ld x1, 0(x2)                    // load the return address
    addi x2, x2, 8                  // reset stack point
    mul x10, x10, x30               // multiply by 2
    addi x10, x10, 1                // add 1
    jalr x0, 0(x1)                  // return

end:
0 голосов
/ 20 октября 2018

У меня недостаточно репутации, чтобы добавить комментарий, но вы пробовали запустить его с отладчиком (GDB?) Вместо бумаги?Это должно показать, что на самом деле находится в регистрах и почему они не разветвляются, как вы могли ожидать.Я недостаточно знаком с этими инструкциями (изучаю сборку x86), чтобы выяснить источник на данный момент.

...