MIPS - 子程序有问题

MIPS - Having trouble with subroutines

我在 class 的实验室工作,我完全理解这里的概念,但我认为我在某个地方犯了一个小错误,很可能是在第二个子例程中。我很难调试这个,希望有人能给我指明正确的方向。另外,要清楚,它正确地编译和接受输入,这与我的计算有关。它输出错误的总成本数额。 谢谢!

Directions & Sample Output:

Write a program for a grocery store to calculate the total charge for customers.

In the main:

Your program should ask customer the number of items that he/she is purchasing and it should check to see it is less than or equal to 20 items , then your program should pass than number to FillPriceArray subroutine and call FillPriceArray subroutine.

FillPriceArray subroutine fills the array, accumulate the prices and return the sum to main.

In the main you get the number of coupons form user (it should be the same as the number of items) and pass the coupon number to FillCouponArray sub and call FillCouponArray to fill the CouponArray.

FillCouponArray sub gets the coupon amount. The coupon should be less than item price and coupon should not be more than </code> if the coupon is more than item price or exceed <code> then you place 0 in the CouponArray for that coupon. Also the FillCouponArray sub accumulates the coupons and return it to main.

Finally your main program should calculate the total charge by subtracting the total price from total discount coupons and out put the total charge with a thank you message on the screen.

示例输出:


Please enter the number of item you are purchasing(should be less than or equal to 20) 
21
Sorry too many items to purchase!! Please enter number of items you are purchasing
3

Please enter the price of item 1    
10
Please enter the price of item 2    
10
Please enter the price of item 3    
20

Please enter the number of coupons that you want to use.
4       
Too many Coupons!! Please enter the number of coupons that you want to use.
3

Please enter the amount of coupon 1
15
This coupon is not acceptable
Please enter the amount of coupon 2


Please enter the amount of coupon 3

Your total charge is:     

Thank you for shopping with us.

到目前为止我的代码:

    .data
str:    .asciiz "\n Please enter the number of items you are purchasing (should be less than or equal to 20): "
str1:   .asciiz "\n Sorry too many items to purchase! Please enter number of items you are purchasing"
str2:   .asciiz "\n Please enter the price of item "
str3:   .asciiz "\n Please enter the number of coupons that you want to use. "
str4:   .asciiz "\n Too many coupons! Please enter the number of coupons that you want to use."
str5:   .asciiz "\n Please enter the amount of coupon "
str6:   .asciiz "\n This coupon is not acceptable"
str7:   .asciiz "\n Your total charge is: $"
str8:   .asciiz "\n Thank you for shopping with us."
str9:   .asciiz ":\t"
priArr: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
couArr: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    .text

main:       li $t1, 20          #input can't be greater than 20 items
            li $t2, 1           #item counter (starting at 1)
            li $t3, 0           #loop counter
            li $t5, 10          #laods 10 into t5
            la $s0, priArr          #loads address of Price Array to $s0
            la $s1, couArr          #loads address of Coupon Array to $s1

            li $v0, 4           #asks for input
            la $a0, str
            syscall

            li $v0, 5           #load integer
            syscall

            add $s3, [=11=], $v0        #adds input to $s3

            bgt $s3, $t1, error1        #if $s3 > $t1 --> error1

            add $a1, $s3, [=11=]        #adds input to $a1 (limit)

            jal FillPriceArray      #jumps to subroutine to fill array with prices

            add $s2, [=11=], $v1        #adds price sum to s2

            #################################################################################

            la $s0, priArr          #points pointer to first location of arr1

            li $v0, 4           #asks for how many coupons
            la $a0, str3
            syscall

            li $v0, 5           #loads integer into $v0
            syscall

            bgt $v0, $s3, error2        #if input > limit, go to error

            add $t4, $v0, 0         #adds input to t4

            add $a3, $t4, [=11=]        #adds input to a3

            jal FillCouponArray     #jumps to subroutine to fill array with coupon

            add $s5, $v1, [=11=]        #adds coupon input to s5

            sub $t7, $s2, $s5       #subtracts price sum and coupons and puts it into t7

            li $v0, 4           #prints output
            la $a0, str7
            syscall

            li $v0, 1           #prints dollar amount
            add $a0, $t7, [=11=]
            syscall


exit:       li $v0, 10
            syscall

FillPriceArray:li $t0, 10           #adds limit($a1) to $t0
               li $t1, 1            #adds counter to $t1
               li $t2, 0            #adds loop counter to $t2
               add $t3, $a1, [=11=]     #adds input to t3


        read:   beq $t3, $t2, end       #if $a1 (counter) = $t2 , return to the previous address in main

            li $v0, 4           #asks for price of item
            la $a0, str2
            syscall

            li $v0, 1           #prints counter
            add $a0, $t1, [=11=]
            syscall

            li $v0, 4           #prints colon and tab
            la $a0, str9
            syscall

            li $v0, 5           #loads integer into $v0
            syscall

            sw $v0, 0($s0)          #stores the integer into array1

            add $t1, $t1, 1         #adds 1 to counter
            add $t2, $t2, 1         #adds 1 to loop counter
            add $s0, $s0, 4         #increments array
            add $t4, $t4, $v0       #adds number to sum

            j read

        end:add $v1, $t4, [=11=]
            jr $ra


FillCouponArray:    li $t0, 10          #adds 10 into t0
                    li $t1, 1           #adds counter to $t1
                    li $t2, 0           #adds loop counter to $t2
                    add $t4, $a3, [=11=]        #adds coupon input to t4

        read1:  beq $t4, $t2, end1      #beg of loop

            lw $v0, 0($s0)          #stores word from price array into $v0 // might have to move outside loop

            add $t5, [=11=], $v0        #stores price into $t5

            li $v0, 4           #outputs please enter amount of coupon
            la $a0, str5
            syscall

            li $v0, 1           #prints counter
            add $a0, $t1, [=11=]
            syscall

            li $v0, 4           #prints colon and tab
            la $a0, str9
            syscall

            li $v0, 5           #loads integer into $v0
            syscall

            add $t3, $v0, [=11=]        #adds input to t3

            bgt $t3, $t0, error3        #if input is > 10, go to error

            bgt $t3, $t5, error3        #if input is > price number

            sw $t3, 0($s1)          #stores the integer into array1

            add $t3, $t3, $v0       #adds number to sum

       increment:   add $t1, $t1, 1         #adds 1 to counter
                    add $t2, $t2, 1         #adds 1 to loop counter
                    add $s0, $s0, 4         #increments array
                    add $s1, $s1, 4         #increments array 2

                    j read1

        end1:   add $v1, $t3, [=11=]        #adds coupon sum to v2

                jr $ra                  #returns back to addresss




error1:     li $v0, 4           #outputs too many items to purchase
            la $a0, str1
            syscall

            j main  

error2:     li $v0, 4           #outputs too many coupons
            la $a0, str4
            syscall

            jr $ra

error3:     li $v0, 4           #outputs coupon is not acceptable
            la $a0, str6
            syscall

            sw [=11=], 0($s1)

            j increment

失败

所以,问题出在FillCouponArray。其中有一些无关的代码可以简化,但这不是主要问题。您的代码未能保持正确的累计总和。

我们来看最后一部分:

li $v0, 5               #loads integer into $v0
syscall

add $t3, $v0, [=10=]        #adds input to t3
bgt $t3, $t0, error3    #if input is > 10, go to error
bgt $t3, $t5, error3    #if input is > price number
sw $t3, 0($s1)          #stores the integer into array1
add $t3, $t3, $v0       #adds number to sum

读取优惠券值后,将其存储在$v0中。然后,将其存储在 $t3 中。乍一看,这看起来不错。这两个错误检查也很好。保存到数组也正常

然而,最后一行是它首先崩溃的地方。 add $t3, $t3, $v0 等同于 $t3 = $t3 + $v0。因此,对于 9 的输入,如果所有检查都通过,则 $t3 = 9 + 9 = 18。不行。你的累计金额已经翻倍了。

但这是一个两阶段的失败。当循环返回到下一个输入时,它会 add $t3, $v0, [=18=]$t3 = $v0 + 0。您现在正在用新输入覆盖 $t3,破坏了累积总和。

最后,您最有可能看到的是您的商品总额减去上一张优惠券的两倍。你可能不想要。

解决方案

我写 MIPS 已经 3 年了,因为这是一项作业,我想说完成这项工作的最快方法是在 [=14] 中替换你的累积和跟踪器 $t3 =] 与另一个可用寄存器,以及 return 该寄存器。

如果您想进一步清理它,我建议您进行一些更改:

  1. 无需将 $v0 移动到 $t3。您可以只使用 $v0 进行检查。

  2. 如果您只是对输入进行简单的求和,则不需要数组。

就是这样。希望有用。