(C в MIPS) Я не знаю, почему я не могу распечатать весь вывод, например код C. - PullRequest
0 голосов
/ 27 мая 2020

Я изо всех сил старался превратить код C в код mips. Я не могу понять, почему я не могу распечатать весь вывод, например код C. Думаю, проблема в $ ra, но я не могу ее исправить. Мне нужна помощь. спасибо за такого хорошего парня, как вы.

Мне нужен такой вывод

1 2 3

1 2 4

1 2 5

1 3 4

1 3 5

1 4 5 *

2 3 4

2 3 5

2 4 5

3 4 5

но код MIPS завершится в *.

C

#include <stdio.h>
static int cl[3];
static int n=5;
static int k=3;
void dfs(int cur, int s ){
    int i;
    if (cur==k) {
        for (i=0; i<k; i++){
            printf("%d ",cl[i]);
        }
        printf("\n");
    }
    else{
        int p=n-k+cur+1;
        for (i=s; i<=p; i++){
            cl[cur]=i;
            dfs(cur+1,i+1);
        }
    }
}
int main(){
            dfs(0,1);

}

ASM

.data
cl: .word 0,0,0 #cl[3]
n: .word 5  #n=5
k: .word 3  #k=3
space:  .asciiz  " "
enter:  .asciiz "\n"
.text
main:   li  $s0, 0  #cur = 0
    li  $s1, 1  #s = 1
    jal dfs
    j   exit


dfs:    addi    $sp, $sp, -12
    sw  $ra, 0($sp)
    li  $t3, 0  #i=0
    lw  $t0, k  #k=3
if: bne $s0, $t0, else  #if(cur==k)
    la  $t0, cl     #get address of cl[i]
loop:   
    lw  $a0, ($t0)  #printf
    li  $v0, 1
    syscall
    la      $a0, space       # load address of spacer for syscall
        li      $v0, 4           # specify Print String service
        syscall 
    addi    $t3, $t3, 1 # i++
    addi    $t0, $t0, 4 # cl[i++]
    lw  $t1, k
    blt $t3, $t1,loop   #i<k 

    la      $a0, enter          # load address of enter for syscall
        li      $v0, 4              # specify Print String service
        syscall

    j   done

else:   lw  $s2, n      # n
    lw  $t0, k      # k
    sub $s2, $s2, $t0   #n-=k
    add $s2, $s2, $s0   #+=cur
    addi    $s2, $s2, 1 # +=1
    move    $t0, $s1    #i=s

loop2:  la  $t1, cl     #load address from cl
    sll $t2, $s0, 2 #t2=cur*4
    add $t1, $t1, $t2   #t1=*cl+cur*4
    sw  $t0, ($t1)  #cl[cur]=i

    addi    $s0, $s0, 1 #cur++
    addi    $s1, $t0, 1 #s=i+1
    sw  $t0, 4($sp)
    sw  $s2, 8($sp)
    jal dfs
    addi    $s0, $s0, -1    
    addi    $s1, $s1, -1    
    addi    $t0, $t0, 1
    ble $t0, $s2, loop2 #i<=s2 


done:   
    addi    $sp, $sp, 12
    lw  $ra, 0($sp)
    lw  $t0, 4($sp)
    lw  $s2, 8($sp)
    jr  $ra     #return void
exit:

1 Ответ

0 голосов
/ 27 мая 2020

Вы увеличиваете указатель стека - выталкиваете его - слишком рано в эпилоге функции. Чтобы перевернуть пролог, мы меняем знак немедленного при добавлении к указателю стека и перемещаем его в конец , а в противном случае меняем sw на lw.

done:   
    addi    $sp, $sp, 12          <--- this is too early
    lw  $ra, 0($sp)
    lw  $t0, 4($sp)
    lw  $s2, 8($sp)
                                  <--- it belongs here
   jr  $ra     #return void
...