首页 文章

MIPS,递归

提问于
浏览
1

我试图编写一个MIPS程序,它获取无符号整数作为参数,并以递归方式返回整数中所有十进制数字的总和 . 例如,如果参数是75080,那么要返回的总和是20(7 5 0 8 0) . 到目前为止,这是我的代码 . 任何帮助,将不胜感激 .

我的想法是将数字除以10,留下数字中的最后一个整数,使用mfhi添加提醒 .

.data
prompt: .asciiz "Enter a string of integer: "
output: .asciiz "\nThe total sum is: "
    .text
    .globl main
main:
    la $a0, prompt
    li $v0, 4
    syscall

    li $v0, 5
    syscall

    move $t2, $v0

    la $a0, output
    li $v0, 4
    syscall

Loop:
    div $t2, $t2, 10
    mflo, $t1
    mfhi, $t3
    beqz $t1, Exit
    add $t1, $t1, 0
    b additive

additive:
    add $t0, $t1, $t1
    j Loop

Exit:   
        la $a0, output
            li $v0, 4
            syscall
            la $v0, 10
            syscall

2 回答

  • 0
    • 这应该是做什么的?将0添加到寄存器不会更改其值:

    add $t1, $t1, 0

    • 分割并复制到 $t1$t3 后,商在 $t1 中,余数在 $t3 中 . 当你加入总数时,你会反过来对待它 .

    • 这实际上会给你 $t0 = 2 * $t1 :你将 $t1 添加到自身并将结果存储在 $t0 中 .

    add $t0, $t1, $t1

    你可能真的想要:

    add $t0, $t0, $t3

    • 在将余数添加到总数之前,您正在检查 $t1 == 0 ,因此最重要的数字将永远不会被添加 . 你真的不需要一个子程序来增加总数 . 您也可以使用 bnez Loop 而不是 beqz Exit - > b Loop . 最后,你甚至不需要 $t1 ,因为商已经在 $t2 .

    摆脱 additive 并将 Loop 替换为:

    Loop:
        div $t2, $t2, 10
        mfhi, $t3
        add $t0, $t0, $t3
        bnez $t2, Loop
    
    • 你的 Exit 很奇怪:你是第二次打印 output 字符串而不是打印整数 .

    把它改成这个:

    Exit:
        move $a0, $t0
        la $v0, 1
        syscall
    
        la $v0, 10
        syscall
    
  • 0

    方法很简单 . 你需要递归函数,我把它命名为SumDigits,它将采用参数中所有数字的最后一个数字和重复过程 . 递归调用返回后,您将向前一个结果添加数字 . 对代码进行了评论以便于理解 . 代码如下:

    .text
    
    #calculates sum of digits recursively
    SumDigits:
    
        sub     $sp,    $sp,    12                  #alloocate 12B on stack
        sw      $ra 0($sp)                      #save return address
        sw      $a0,    4($sp)                      #save argument
    
        beq     $a0,    $0, exit_sumdigits      #when there is no more digits return 0
        rem     $t0,    $a0,    10                  #get last digit
        sw      $t0,    8($sp)                      #save it on stack
        div     $a0,    $a0,    10                  #divide argument by 10
        jal     SumDigits                       #repeat procedure
        lw      $t0,    8($sp)                      #read digit from stack
        add     $v0,    $v0,    $t0             #add digit to previous result
        lw      $ra,    0($sp)                      #load return address
        addi    $sp,    $sp,    12                  #free stack
        jr      $ra                             #return
    
    exit_sumdigits:
        li      $v0,    0                           #there are no more digits, return 0
        lw      $ra,    0($sp)                      #load return address
        addi    $sp,    $sp,    12                  #free stack
        jr      $ra                             #return
    
    main:
        li      $a0,    75080                       #load number in $a0
        jal     SumDigits                           #call SumDigits
    
        move    $a0,    $v0                         #set a0 = result of SumDigits
        li      $v0,    1                           #set $v0 for print int system call
        syscall
    
        li      $v0,    10                          #set $v0 for exit system call
        syscall
    
    .data
    

相关问题