使用MIPS数组计数整除的元素数量由4 [英] Counting number of elements divisible by 4 in an array using MIPS

查看:247
本文介绍了使用MIPS数组计数整除的元素数量由4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

输入code在这里我想算上这阵列是由四个整除的元素的数量,目前它打印出的次数的程序循环次数。出于某种原因,程序调用MOD每次。任何人都可以找出为什么会是这样吗?

 。数据
改编:.word 5,4,8,12,13,16,18,20,24,23,0
味精:.asciiz元素被4整除:
四:.word 4
。文本
磅$ S4,四
.globl主主要:阿迪$ T0,$ 0,0#我清楚
阿迪$ T1,$ 0,0#明确总和
ORI $ T2,$ 0#11初始化t2到其恒定值10
LA $ T3,阵列的ARR#加载地址到T3循环:SLT $ T4,T0 $,$#T2相比,T4 $ = I<总和? 1:0
BEQ $ T4,$ 0#到底,如果我不是< 11,退出循环
LW $ T4,0($ T3)#负载电流数组元素为T4安迪$ T4,T4 $ 3
BEQ $ T4,$零,MOD
j循环mod:#如果其他出口加$ T1,$ T1,1#添加总结
加$ T0,T0 $ 1#我递增
加$ T3,T3 $,4#增量当前数组元素的指针
j循环结束:阿迪$ V0,$ 0,4#现在我们打印出的结果:string
LA $ A0,味精
系统调用阿迪$ V0,$ 0,1#后跟实际总和(这是在T1)
加$ A0,$ T1,$ 0个
LA $ T5,退出
系统调用出口:
 Ĵ退出

工作版

 。数据
ARR:.word 12,4,8,12,13,16,18,20,24,23,0
味精:.asciiz计数器
fourMod:.word 4。文本磅$ S1,fourMod.globl主主要:阿迪$ T0,$ 0,0#我清楚
阿迪$ T1,$ 0,0#明确总和
ORI $ T2,$ 0时,10#初始化t2到其恒定值10
LA $ T3,阵列的ARR#加载地址到T3循环:
SLT $ T4,T0 $,$#T2相比,T4 $ = I<总和? 1:0
BEQ $ T4,$ 0#到底,如果我不是< 10,退出循环
LW $ T4,0($ T3)#负载电流数组元素为T4安迪$ T4,T4 $ 3
BEQ $ T4,$零,MOD加$ T0,T0 $ 1#我递增
加$ T3,T3 $,4#增量当前数组元素的指针
j循环mod:
#将到被4整除柜台?
加$ S2,S2 $ 1
加$ T0,T0 $ 1#我递增
加$ T3,T3 $,4#增量当前数组元素的指针
j循环
结束:阿迪$ V0,$ 0,4#现在我们打印出的结果:string
LA $ A0,味精
系统调用阿迪$ V0,$ 0,1#后跟实际总和(这是在T1)
加$ A0,$ S2,$ 0个
LA $ T5,退出
系统调用出口:
 Ĵ退出


解决方案

您永远不会告诉你的程序不要在mod执行code >

 加$ T3,T3 $,4#增量当前数组元素的指针
    < ---这里什么都没有,以prevent的执行,继续下面的加
mod:
加$ S2,S2 $ 1

如果你想跳过一些code使用分支指令。或者在你的情况,你想要的东西可能是一个 j循环


另一件事是,你正在做不必要的分工,这往往是一个比较缓慢的操作。检查整数是否为四的倍数可以通过测试两个最低显著位来实现:

 安迪$ T4,T4 $,3#隔离两个最低显著位
BEQ $ T4,$为零,mod#我们有4的倍数,如果这两个位为零


编辑:使用更新后的code你还在递增你的整除在每次迭代计数器。它很可能是最好的,如果你倒你的分支条件,改变了code的那部分分为:

 安迪$ T4,T4 $ 3
BNE $ T4,$零,not_divisible
加$ T1,$ T1,1#添加总结not_divisible:#如果其他出口加$ T0,T0 $ 1#我递增
....#为简洁起见省略

enter code here I'm trying to count the number of elements in this array that are divisible by four, currently it prints out the number of times the program loops. For some reason the program calls mod every time. Can anyone identify why this might be happening?

.data
arr: .word 5, 4, 8,12, 13, 16, 18, 20, 24,23,0
msg: .asciiz "Elements Divisible By 4 :   "
four: .word 4
.text
lb $s4, four
.globl main

main:

addi $t0, $0, 0 # clear i
addi $t1, $0, 0 # clear sum
ori $t2, $0, 11 # Initializing t2 to its constant value 10
la $t3, arr # load address of array into t3

loop:

slt $t4, $t0, $t2 # compare, $t4 = i < sum ? 1 : 0
beq $t4, $0, end # if i is not < 11, exit the loop
lw $t4, 0($t3) # load current array element into t4

andi $t4, $t4, 3
beq $t4, $zero, mod
j loop



mod: # if-else exit 

add $t1, $t1, 1 # add it to sum
add $t0, $t0, 1 # increment i
add $t3, $t3, 4 # increment current array element pointer
j loop

end:

addi $v0, $0, 4 # Now we print out result: string
la $a0, msg
syscall

addi $v0, $0, 1 # followed by the actual sum (which is in t1)
add $a0, $t1, $0
la $t5, exit     
syscall

exit:
 j exit

Working version

.data
arr: .word 12, 4, 8, 12, 13, 16, 18, 20, 24, 23, 0
msg: .asciiz "Counter  "
fourMod: .word 4

.text

lb $s1, fourMod

.globl main

main:

addi $t0, $0, 0 # clear i
addi $t1, $0, 0 # clear sum
ori $t2, $0, 10 # Initializing t2 to its constant value 10
la $t3, arr # load address of array into t3

loop:
slt $t4, $t0, $t2 # compare, $t4 = i < sum ? 1 : 0
beq $t4, $0, end # if i is not < 10, exit the loop
lw $t4, 0($t3) # load current array element into t4

andi $t4, $t4, 3
beq $t4, $zero, mod

add $t0, $t0, 1 # increment i
add $t3, $t3, 4 # increment current array element pointer
j loop

mod: 
#add to the divisible by 4 counter?
add $s2, $s2, 1
add $t0, $t0, 1 # increment i
add $t3, $t3, 4 # increment current array element pointer
j loop


end:

addi $v0, $0, 4 # Now we print out result: string
la $a0, msg
syscall

addi $v0, $0, 1 # followed by the actual sum (which is in t1)
add $a0, $s2, $0
la $t5, exit     
syscall

exit:
 j exit

解决方案

You never tell your program not to execute the code after mod::

add $t3, $t3, 4 # increment current array element pointer
    <--- There's nothing here to prevent the execution to continue with the below add
mod:
add $s2, $s2, 1

Use a branch instruction if you want to skip over some code. Or in your case what you want is probably a j loop.


Another thing is that you're doing an unnecessary division, which often is a relatively slow operation. Checking whether an integer is a multiple of four can be done by testing the two least significant bits:

andi $t4, $t4, 3      # Isolate the two least significant bits
beq $t4, $zero, mod   # We've got a multiple of 4 if those two bits are zero


Edit: With your updated code you're still incrementing your "is divisible" counter on every iteration. It would probably be best if you inverted your branch condition and changed that part of the code into:

andi $t4, $t4, 3
bne $t4, $zero, not_divisible
add $t1, $t1, 1 # add it to sum

not_divisible: # if-else exit 

add $t0, $t0, 1 # increment i
....  # omitted for brevity

这篇关于使用MIPS数组计数整除的元素数量由4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆