1

我正在编写一个 MiPS 程序,它将检查 15 个测试分数的列表。它将从终端输入。嗯,通过标准是50分。终端的输出将包括每个类别的分数以及通过和失败的学生人数。带有输入提示和输出语句...下面是我编写的程序,但它没有工作..请我需要..我不知道我是否做错了..

.globl main
.text

main: li $t0, 0 #通过分数计数器 la $t1, pass #pointer for pass 数组
li $t2, 0 #counter 分数不及格 la $t3, fail #pointer for pass array li $t4, 0 #overall counter li $t5, 0 li $t6, 0

loop: li $v0, 4 #system call for print string la $a0, prompt #load string syscall

li $v0, 5           #system call for read integer
syscall             #read integer

bltu $v0, 50, else      #if $v0 < 50 branch to else (failing grade)
sw $v0, 0($t1)          #store word in pass array
addi $t1, $t1, 4        #t1 = t1 + 4 (increment pass pointer)
addi $t0, $t0, 1        #t0 = t0 + 1 (increment pass counter)
b l_end             #branch over else statement

else: sw $v0, 0($t3) #store word in fail array addi $t3, $t3, 4 #t3 = t3 + 4 (递增失败指针) addi $t2, $t2, 1 #t1 = t1 + 1 (递增失败计数器)

l_end: addi $t4, $t4, 1 #增量总计数器 bltu $t4, 15, loop #if t4 <= 15 分支到循环

输出计数

li $v0, 4           #system call for print string
la $a0, o_pasc          #load string
syscall             #output "Number of Passing Scores:

la $v0, 1           #system call for print integer
add $a0, $t0, 0         #load value of pass counter into $a0
syscall             #output value

li $v0, 4           #system call for print string
la $a0, o_fasc          #load string
syscall             #output "Number of Failing Scores: "

la $v0, 1           #system call for print string
add $a0, $t2, 0         #load value of fail counter into $a0
syscall             #output value

输出及格分数

li $v0, 4           #setup output   
la $a0, o_pass          #setup text
syscall             #output string o_pass

la $t1, pass            #load address of pass pointer to t1
lw $a0, 0($t1)          #load word at $t1 into $a0
li $v0, 1           #system call for print integer

loop_a: bleu $t0, $t5, lp_a_end #if t0 <= t5 branch to lp_a_end syscall #output single score

li $v0, 4           #system call for print string
la $a0, o_coma          #load string
syscall             #ouput comma and space

li $v0, 1           #setup output
addi $t1, $t1, 4        #move pointer down by 1 word
lw $a0, 0($t1)          #move word at pointer into $a0
addi $t5, $t5, 1        #add 1 to counter

b loop_a            #branch to top

lp_a_end:

输出失败分数

la $t5, 0           #clear t5 (counter)
li $v0, 4           #setup output
la $a0, o_fail          #setup text
syscall             #output string o_fail

la $t3, fail            #load address for fail pointer into $t3
lw $a0, 0($t3)          #load word at mem addy $t3 into $a0
li $v0, 1           #system call for print integer

loop_b: bleu $t2, $t5, lp_b_end #if t2 <= t5 branch to lp_a_end syscall #output single score

li $v0, 4           #system call for print string
la $a0, o_coma          #load string
syscall             #output comma and space

li $v0, 1           #setup output
addi $t3, $t3, 4        #move pointer down by 1 word
lw $a0, 0($t3)          #load word from mem addy $t3 to $a0
addi $t5, $t5, 1        #add 1 to counter

b loop_b            #branch to top

lp_b_end:

结尾

li $v0, 4           #setup output
la $a0, o_brk           #setup text
syscall             #output line break

li $v0, 10          #loads 10 to $v0
syscall             #ends program
4

1 回答 1

3

“似曾相识通常是《黑客帝国》中的一个小故障”

很确定我已经看到了这个:

MIPS 程序确定测试成绩的通过/失败

编辑:一些建议:尝试简化事情。一点一点地构建你的程序。例如,尽量避免系统调用,使用硬编码输入来测试您的比较逻辑。然后,进行系统调用。您是否正确使用数组?我已经看到您保留了两个单独的计数器来索引数组,并保持其中元素的计数。我认为这很容易出错。也许您应该使用计数器来索引数组(将其乘以 4)。点击链接,如果出现任何具体疑问,我将很乐意提供帮助。

我不太喜欢 SPIM 模拟器。我知道许多大学将它用于他们的课程,但我认为这是一个错误,因为它是一个非常有限的环境。

另一个编辑(通过“流行”需求):我已经阅读了你的代码一段时间,我注意到了一些事情。

  • 您将值加载到寄存器中以与零进行比较。不要这样做,使用 $zero 寄存器。

    李$t5,0

    李$t6.0

用于

bleu $t0,$t5,lp_a_end       #if t0 <= t5 branch to lp_a_end 

应该

bleu $t0,$zero,lp_a_end
  • 指令的使用

    bltu $v0, 50, else #if $v0 < 50 分支到 else(不及格)

分支指令采用两个寄存器和一个标签。不注册,中介,标签

应该:

   li   $t5,50
   bltu $v0,$t5,else

我的猜测是,您徒劳地使用系统调用使自己复杂化。当你不能让它工作时,你为什么喜欢你的输出?除此之外,一旦您开始准备系统调用,就执行它。不要在中间放置分支指令,例如

        la $t3, fail                    #load address for fail pointer into $t3
        lw $a0, 0($t3)                  #load word at mem addy $t3 into $a0
        li $v0, 1        
loop_b: bleu $t2, $t5, lp_b_end         #if t2 <= t5 branch to lp_a_end 
        syscall                         #output single score

这很令人困惑。也许您应该尝试以下方法:

#Is there anything to print in the array? If not, goto lp_b_end
bleu $t2,$zero,lp_b_end

#Ok, we know we are not pointing at an invalid position of the array.       
la $t3, fail                    #load address for fail pointer into $t3
lw $a0, 0($t3)                  #load word at mem addy $t3 into $a0
li $v0, 1 
syscall

最后,在使用系统调用时尽量保持约定。例如,仅将寄存器 $a0 和 $v0 用于系统调用。不要将它们用于其他任何事情。如果您将一个整数读入 $v0,则在执行其他任何操作之前将其移至 $t0。

这就是我现在能想到的。正如有人在欺骗帖子(Rob Kennedy)中所说,也请尝试询问您的教练,这就是他获得报酬的原因(我不是您的教练,只是帮手)。

于 2009-05-04T03:41:58.587 回答