MIPS中Pascal的三角形

时间:2014-03-14 09:10:37

标签: assembly mips pascals-triangle

我需要在MIPS组装方面提供一些认真的帮助。这个程序应该做两件事。这两件事是:

  1. 计算C(n,k)= n!/((n-k)!k!)
  2. 输入:spim -f 90.s 4 6

    输出:
    6 4
    720 24
    15

    2.显示Pascal三角形的行n,其中k = 0到n
    输入: 与之前相同(spim -f 90.s 4 6)

    输出: 6 4 720 24 15 1 6 15 20 15 6 1 (这是最终输入应该是什么。)

    我基本上需要编写一个函数displayRow,它显示Pascal三角形的行n,其中k = 0到n。忽略传入的k的值。由于displayRow函数调用Cnk,我必须构造一个堆栈帧。在displayRow中,我需要编写一个从k = 0到n的循环。在循环体内显示Cnk(n,k)的返回值。我卡住了,我的输出看起来像这样:

    spim :(解析器)解析文件90.s的第174行的错误           bgtz $ v0 以下符号未定义: 的atoi

    6 4 720 24 24

    我不知道从哪里开始。一些认真的帮助将不胜感激! 这是我的代码......

         # Display Row n of Pascal's Triangle for k=0 to n
         # usage: spim -f 90.s 4 6
    
        .data
        newline: .asciiz "\n"
        space: .asciiz " "
    
        .text
        .globl main
    
        main:
        # hard coded
        li $t0 6
        li $t1 4
    
        # grab command line stuff - a0 is arg count and a1 points to list of args
        move $s0 $a0
        move $s1 $a1
    
        # zero out these registers just to be safe
        move $s2 $zero
        move $s3 $zero
        move $s4 $zero
    
        # check if less than three arguments are given
        li $t3 2
        blt $a0 $t3 default
        bgt $a0 $t3 default
    
        # parse the first number
        lw $a0 4($s1)
        jal atoi
        move $s2 $v0
    
        # parse the second number
        lw $a0 8($s1)
        jal atoi
        move $s3 $v0
    
        # load a0 and a1 with two integers
        move $a0 $s2
        move $a1 $s3
    
        move $t0, $a0
        move $t1, $a1
    
    
        # swap if n < k
        slt $t3 $t0 $t1
        beq $t3 $0 done
        move $t2 $t0
        move $t0 $t1
        move $t1 $t2
    
        done:
        # move the result from t0 to v0 to print it
        move $a0 $t0
        li $v0 1
        syscall
    
        la $a0 space
        li $v0 4
        syscall
    
        move $a0 $t1
        li $v0 1
        syscall
    
        la $a0 newline
        li $v0 4
        syscall
    
        move $t8 $t0
        jal factorial
    
        move $a0 $t9
        li $v0 1
        syscall
        move $s2 $t9
    
        la $a0 space
        li $v0 4
        syscall
    
        move $t8 $t1
        jal factorial
    
        move $a0 $t9
        li $v0 1
        syscall
        move $s3 $t9
    
        la $a0 newline
        li $v0 4
        syscall
    
        move $a0 $s3
        li $v0 1
        syscall
    
        la $a0 newline
        li $v0 4
        syscall
    
        li $v0 10  # 10=exit
        syscall
    
        default:
        move $a0 $t0
        move $a1 $t1
        j done
    
        pascal:
        addi $sp, $sp, -16             # create stack frame
        sw $ra, 12($sp)                # save return address
        sw $s0, 8($sp)                 # save three registers
        sw $s1, 4($sp)
        sw $s2, 0($sp)
    
        beq $a1, $zero, one            # branch if col == 0
        beq $a1, $a0, one              # branch if col == row
    
        add $s0, $a0, $zero            # save argument values
        add $s1, $a1, $zero
        addi $a0, $a0, -1              # compute args for first recursion
        addi $a1, $a1, -1
        jal pascal                     # pascal(row-1, col-1)
        add $s2, $v0, $zero            # save returned value
    
        addi $a0, $s0, -1              # compute args for second recursion
        add $a1, $s1, $zero
        jal pascal                     # pascal(row-1, col)
        add $v0, $v0, $s2              # add the two values
    
        #done:
        lw $ra, 12($sp)                # restore registers
        lw $s0, 8($sp)
        lw $s1, 4($sp)
        lw $s2, 0($sp)
        addi $sp, $sp, 16
        jr $ra                         # return
    
        one:
        addi $v0, $zero, 1 # return constant 1
        j done
    
        #---------------------Factorial
        factorial:
        li $t9 1
    
        fac:
        beqz $t8 return
        mul $t9 $t9 $t8
        addi $t8 $t8 -1
        j fac
    
        return:
        move $v0 $t8
        jr $ra
    
        #---------------
        Cnk:
        addi $sp, $sp, -32  # Stack frame is 32 bytes long
        sw   $ra, 20($sp)   # Save return address
        sw   $fp, 16($sp)   # Save frame pointer
        addi $fp, $sp, 28   # Set up frame pointer
        sw   $a0, 0($fp)    # Save argument (n)
    
        lw $v0 0($fp)
        bgtz $v0
        # --------- ATOI FUNCTION
        atoi:
        move $v0, $zero
    
        # detect sign
        li $t0, 1
        lbu $t1, 0($a0)
        bne $t1, 45, digit
        li $t0, -1
        addu $a0, $a0, 1
    
        digit:
        # read character
        lbu $t1, 0($a0)
    
        # finish when non-digit encountered
        bltu $t1, 48, finish
        bgtu $t1, 57, finish
    
        # translate character into digit
        subu $t1, $t1, 48
    
        # multiply the accumulator by ten
        li $t2, 10
        mult $v0, $t2
        mflo $v0
    
        # add digit to the accumulator
        add $v0, $v0, $t1
    
        # next character
        addu $a0, $a0, 1
        b digit
    
        finish:
        mult $v0, $t0
        mflo $v0
        jr $ra
        #----------------------------------------
    

1 个答案:

答案 0 :(得分:1)

答案在错误消息中:

spim: (parser) parse error on line 174 of file 90.s 
          bgtz $v0
                  ^ 
The following symbols are undefined: 
atoi

btgz需要一个目标而你没有给出任何目标。弄清楚你希望它分支到哪里并分配目标。