MIPS:确定测试分数列表是否通过/失败

发布于 2024-07-19 00:20:58 字数 3652 浏览 2 评论 0原文

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

.globl main
.text

主要: li $t0, 0 #通过成绩计数器 la $t1,传递 #pointer 传递数组
li $t2, 0 #不及格成绩计数器 la $t3,失败 #pointer for pass 数组 li $t4, 0 #整体计数器 李$t5, 0 li $t6, 0

循环: li $v0, 4 #打印字符串的系统调用 la $a0,提示#load string 系统调用

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

其他: sw $v0, 0($t3) #将单词存储在失败数组中 addi $t3, $t3, 4 #t3 = t3 + 4(增加失败指针) addi $t2, $t2, 1 #t1 = t1 + 1(递增失败计数器)

l_end: addi $t4, $t4, 1 #increment 整体计数器 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 分支到 lp_a_end 系统调用#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 分支到 lp_a_end 系统调用#输出单分

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:

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

I am writing a MiPS program that will examine a list of 15 test scores. And it is going to input from the terminal.Well, the passing criterion is the score of 50. the ouptuts to the terminal will include the scores in each category and the number of students passing and failing. with input prompts and output statements...Below is the program i wrote but it didnt work....Please i need....i dont know if i m doing it wrong..

.globl main
.text

main:
li $t0, 0 #counter for passing grades
la $t1, pass #pointer for pass array
li $t2, 0 #counter for failing grades
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 (increment fail pointer)
addi $t2, $t2, 1 #t1 = t1 + 1 (increment fail counter)

l_end:
addi $t4, $t4, 1 #increment overall counter
bltu $t4, 15, loop #if t4 <= 15 branch to loop

output counts

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

output passing scores

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:

output failing scores

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:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

韶华倾负 2024-07-26 00:20:58

“似曾相识通常是矩阵中的一个小故障”

很确定我已经看到过这种情况:

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

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

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

另一次编辑(根据“大众”需求)
我读过你的代码有一段时间了,我注意到了一些事情。

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

    李$t5,0

    li $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。

我现在能想到的就是这些。 正如有人在欺骗帖子(罗布·肯尼迪)中所说,也尝试询问您的教练,这就是他获得报酬的原因(我不是您的教练,只是伸出援助之手)。

"A deja vu is usually a glitch in the Matrix"

Pretty sure i've seen this around:

MIPS program to determine pass/fail for test grades

EDIT: Some advice: Try to simplify things. Build your program bit by bit. For example, try to avoid syscalls, use hardcoded inputs to test your comparing logic. Then, go for syscalls. Are you using arrays correctly? I've seen that you keep two separate counters for indexing the array, and keeping count of the elements inside it. I think that that is error prone. Maybe you should use the counter to index the array (multiplying it by 4). Follow the link, i'll be happy to help if any specific doubts appear.

I don't like SPIM simulator much. I know that many universities use it for their courses, but i think that is a mistake, since it is a very limited environment.

ANOTHER EDIT (by "popular" demand):
I've read your code for a while, and i noticed some things.

  • You load values into registers for comparison against zero. Don't do this, use the $zero register.

    li $t5,0

    li $t6.0

are used in

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

should be

bleu $t0,$zero,lp_a_end
  • Usage of instructions

    bltu $v0, 50, else #if $v0 < 50 branch to else (failing grade)

branch instructions take two registers and a label. Not register, inmediate, label

Should be:

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

My guess is that you are complicating yourself in vain with the syscalls. Why are you fancying your output when you cant get it to work? In addition to that, once you start preparing for a syscall, execute it. Dont put a branch instruction in the middle, like in

        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

This is quite confusing. Maybe you should try something like:

#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

Finally, try to keep a convention when you use syscalls. For example, use registers $a0 and $v0 only for syscalls. Dont use them for anything else. If you read an integer into $v0, then move it to $t0 before doing anything else.

That's all i can think of right now. As someone said in the dupe post (Rob Kennedy), try asking your instructor as well, that's why he gets paid (i'm not your instructor, just a helping hand).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文