Mips汇编语言递归程序:我猜从堆栈中继续收到错误的地址

时间:2014-11-12 18:45:18

标签: assembly recursion stack mips

我正在尝试创建一个程序,列出所有递归数字,直到他们输入的数字。问题是它运行不正常。我不断收到不好的地址。顺便说一下,这是MIPs汇编语言。 提前谢谢。

    .data
    NUM_LIST:   .space 800
    BIN_VECT:   .space 800
    PROMPT1: .asciiz    "\nEnter a Number from (2-200)\n"
    PROMPT2: .asciiz    "What is the square root of the number?\n"
    ERROR_PROMPT: .asciiz   "Number is not between 2-200\n"
    DISPLAY_MSG:  .asciiz   "The primes in the specified space are: /n"
     SPACE_MSG:    .asciiz  " "

    .text
    .globl main

    main:

    li $s3, 2           #set $s3 to constant 2 number we are checking and first prime
    li $s4, 200         #set $s4 to constant 200 maximum number allowed
    li $s5, 1           #set $s5 to constant 1
    li $t5, 1           #set $t5 to constant 1
    li $s6, 0           #set $t6 to constant 0(NULL)


    la $a1, NUM_LIST        #loads NUM_LIST
    la $a2, BIN_VECT        #loads BIN_VECT

    sw $s5, ($a1)           #removes constant 1 from NUM_LIS
    sw $s0, ($a2)           #removes 1 from BIN_VECT

    addiu $a1, $a1, 4       #adjusts offset for insertion in NUM_LIST
    addiu $a2, $a2, 4       #adjusts offset for insertion in BIN_VECT

    j fill_list         #jumps to fill_list

    get_n:

    li $v0, 4
    la $a0, PROMPT1
    syscall             #print PROMPT1

   li $v0, 5
   syscall              #read in user input
   move $s0, $v0            #save N in register $s0

   j error_check            #check for error

   get_n_squared: 

   li $v0, 4
   la $a0, PROMPT2
   syscall              #print PROMPT2

   li $v0, 5
   syscall              #read in user input
   move $s1, $v0            #save N squared in register $s1

   error_check:

   blt $s0, $s3, error_occurred #jump to error if N < 2
   bgt $s0, $s4, error_occurred #jump to error if N > 200

   j get_n_squared          #else continue with getting user input


################################
   error_occurred:
################################
   li $v0, 4
   la $a0, ERROR_PROMPT
   syscall              #print ERROR_PROMPT

   li $v0, 5
   syscall              #read in user input
   move $s0, $v0            #save in register $s0

   j error_check            #check for error again
######################
   fill_list:
######################
   addiu $s5, $s5, 1

   sw $s5, ($a1)            #stores 1 to N into NUM_LIST
   sw $t5, ($a2)            #stores 1 in BIN_VECT

   addiu $a1, $a1, 4        #adjust for offset
   addiu $a2, $a2, 4

   beq $s1, $s5, create_stack

   j fill_list
#######################
   create_stack:
#######################
    addi    $sp,$sp,-4          # dec sp
    sw  $ra,($sp)           # save return address on stack
    addi    $sp,$sp,-4          # dec sp
    sw  $fp,($sp)           # save fp on stack
    addi    $sp,$sp,-4          # dec sp
    sw  $s2,($sp)           # save s2 on stack
    addi    $sp,$sp,-4          # dec sp
    sw  $s3,($sp)           # save s3 on stack
    addi    $sp,$sp,-4          # dec sp
    addi    $fp, $sp, 32            # set $fp


    restore_regs:           

    lw $s0, 28($sp)         #restore
    lw $ra, 8($sp)          #restore ra for caller
    lw $fp, 4($sp)          #restore fp for caller

    addu $sp,$sp, 32        #restore caller’s stack pointer

    jr $ra


    test_prime:

    subu $a1, $a1, $t3      #set offset of NUM_LIST = 0
    subu $a2, $a2, $t3      #set offset of BIN_VECT = 0

    addiu $t7, $t7, 1       #increments x++

    mul $t8, $t7, $s6       #multiplies x*k and stores in $t8

    blt $t8, $s1, recursion     #applies recursive step

    mul $t9, $t8, $t2       #multiplies result in $t8*offset

    addu $a2, $a2, $t9      #finds index

    sw $t6, ($a2)           #set offset in BIN_VECT = 0 (not prime)  

    j restore_regs          #jump back to restore the registers

    print_out:

    add $s7, $s7, 1         #counter++

    lw $t1, ($a1)           #load $t1 with elem at a1 in NUM_LIST
    lw $t4, ($a2)           #load $t4 with elem at a2 in BIN_VECT

    addu $a1, $a1, 4
    addu $a2, $a2, 4

    beq $t4, $t6, print_out     #if $t4 = 0 it won’t print

    li $v0, 4
    la $a0, DISPLAY_MSG
    syscall             #prints DISPLAY_MSG    

    li $v0, 1
    move $a0, $t1
    syscall             #prints element

    li $v0, 4
    la $a0, SPACE_MSG
    syscall             #prints space between elements

    beq $s7, $s1, ending        #if values equal, jump to end

     j print_out

    exit_prime:
    addi    $sp,$sp,4           # inc sp
    lw  $s3,($sp)           # get old s3 off stack
    addi    $sp,$sp,4           # inc sp
    lw  $s2,($sp)           # get old s2 off stack
    addi    $sp,$sp,4           # inc sp
    lw  $fp,($sp)           # get old fp off stack
    addi    $sp,$sp,4           # inc sp
    lw  $ra,($sp)           # get return address off stack
    addi    $sp,$sp,4           # inc sp back to where we expect it to start
    jr  $ra             # go back to caller+4

    recursion:

   jal test_prime

    ending:

   jr$31                #end program

0 个答案:

没有答案