【问题标题】:How to print a full array in MIPS, and sum certain integers of an array如何在 MIPS 中打印一个完整的数组,并对数组的某些整数求和
【发布时间】:2012-02-08 09:01:21
【问题描述】:

我在使用以下代码进行作业时遇到问题。请注意,我不希望任何人只给我代码,我真的想了解 MIPS。我正在使用 QTSimp 模拟器来运行我的 MIPS 代码。

以下代码应该允许用户从键盘输入 10 个整数,然后将这些整数与小于第一个输入整数的整数相加(即 10、9、8、7、6、5 , 4, 3, 2, 1 将把除 10 之外的所有数字相加,等于 45)。然后,程序应该按照给定的顺序输出数组。目前,我的代码允许用户输入 10 个整数,但随后发生了有趣的事情。它以我无法遵循的方式对数字求和(最常见的总和不知何故是 0、4 和 50),然后只会打印出数组列表的 4 个整数(似乎如下:firstNumber、secondNumber、 lastNumber, 10) 我真的很困惑为什么会发生这种情况。此外,对于某些整数实例,它会创建一个输出 0 的无限循环。

我已经做了几个小时了,有人可以给我一些建议或指示吗? 感谢所有帮助。谢谢!

# DATA DECLARATION

    .data
request:    .asciiz "Enter an integer:\n"
sumLine:    .asciiz "The sum is: "
aList:      .asciiz "The array contains the following: \n"
return:     .asciiz "\n"
array:      .word 0
aLength:    .word 10
input:      .word 0
count:      .word 0
count2:     .word 0
count3:     .word 0
sum:        .word 0
next:       .word 0
first:      .word 0
one:        .word 1

# PROGRAM CODE

    .text
    .globl main

# PROGRAM EXECUTION

#--------------------------------------------------------------------------
# Procedure main
# Description: Initializes registers and prints the final sum.
# parameters: $s0 = address of array, $t0 =  length
# return value: $v0 = sum
# registers to be used: $s0, $t0, $t1, $t2, $t4, $t5, $v0
#--------------------------------------------------------------------------
main:

la  $s0, array          # s0 = array
lw  $t0, aLength            # t0 = aLength
lw  $t1, count          # t1 = count
lw  $t2, input          # t2 = input
lw  $t3, count2         # t3 = count2
lw  $t4, count3         # t4 = count3
lw  $t5, sum            # t5 = sum
lw  $t6, first          # t6 = first
lw  $t7, next           # t7 = next
lw  $t9, one            # t9 = one

beq $t1, $zero, readArray       # if count=0, goto readArray procedure

la  $a0, sumLine            # load line to print
li  $v0, 4              # print sum output line
syscall
lw  $a0, sum            # load sum to print
li  $v0, 1              # print sum
syscall
la  $a0, return         # load line to print
li  $v0, 4              # print return line
syscall
la  $a0, aList          # load line to print
li  $v0, 4              # print the array list line
syscall

j printArray


#--------------------------------------------------------------------------
# Procedure readArray
# Description: Reads integers from the keyboard.
# parameters: $s0 = address of array, $t0 =  length
# return value: --------
# registers to be used: $v0, $a0, $t0, $t1, $t2, $s0
#--------------------------------------------------------------------------
readArray:

beq $t1, $t0, sumSmallerThanFirst   # if t1=t0 (count = aLength) goto sum procedure
la  $a0, request            # load line to print
li  $v0, 4              # print request line
syscall
li  $v0, 5              # read integer from keyboard
syscall
sw  $v0, input          # store integer to input
lw  $t2, input          # t2 = input
sw  $t2, 0($s0)         # array[i] = t2
addi    $s0, $s0, 4         # increment array (i++)
addi    $t1, $t1, 1         # increment count (count+1)
sw  $t1, count          # store count to t1
beq $t1, $t9, store         # if t1=t9 (count = one) goto store 

j readArray

store:

lw  $t6, 0($s0)         # t6 = array[i]
sw  $t6, first          # t6 = first    

j readArray

#--------------------------------------------------------------------------
# Procedure sumSmallerThanFirst
# Description: Sums the inputted integers if they are < the first integer.
# parameters: $s0 = address of array, $t0 =  length
# return value: ----------
# registers to be used: $s0, $t0, $t3, $t5, $t6, $t7, $t8, $0
#--------------------------------------------------------------------------
sumSmallerThanFirst:

la  $s0, array
beq $t3, $t0, main          # if count=length, goto main
lw  $t7, 0($s0)         # t7 = array[i]
sw  $t7, next           # t7 = next
slt $t8, $t7, $t6           # if t7<t6, t8=1
addi    $s0, $s0, 4         # array[i++]
addi    $t3, $t3, 1         # count+1
sw  $t3, count2         # store count2 to t3

beq $t8, $zero, sumSmallerThanFirst # if t8=0, goto top sum

add $t5, $t5, $t7           # t5=t5+t6 (sum = sum + array[i]) 
sw  $t5, sum            # store sum to t5

j sumSmallerThanFirst


#--------------------------------------------------------------------------
# Procedure printArray
# Description: Prints out the array of inputted integers.
# parameters: $s0 = address of array, $t0 =  length
# return value: -------------
# registers to be used: $v0, $t0, $t4, $t6, $s0
#--------------------------------------------------------------------------
printArray:

beq $t4, $t0, Exit          # if count=length, goto Exit
lw  $t7, 0($s0)         # t7 = array[i]
sw  $t7, next           # t7 = next
lw  $a0, next           # load array[i] to print
li  $v0, 1              # print array[i]
syscall
la  $a0, return         # load line to print
li  $v0, 4              # print return line
syscall
addi    $s0, $s0, 4         # array[i++]
addi    $t4, $t4, 1         # count+1
sw  $t4, count3         # store count3 to t4

j printArray

Exit:

jr $ra                  # return

【问题讨论】:

  • 我没有查看所有代码,但您的数组只有一个单词的空间 (array: .word 0)。您可能正在寻找做例如array: .space 40 为 10 个 4 字节字腾出空间。
  • 实际上我最初将数组设置为 .space 40 并且它的工作方式相同,所以我将其更改为现在的样子,但没有运气。我同意它应该是 .space 40,但我会改回来。
  • 进一步看,您似乎希望在系统调用中保留临时寄存器(例如 readArray 使用 $t1 作为其循环变量) - 虽然它们可能是,但我不会不要指望它。另外,您不能使用 SPIM 跟踪执行或单步执行代码吗?这应该可以帮助您找出问题所在。
  • 您应该将寄存器 $s0,..,$s7 用于您希望在系统调用中保留的变量。
  • 将t寄存器切换到s寄存器后,程序依旧运行。我还尝试了两种类型的数组,.word 0 和 .space 40,但没有运气......我确实有 SPIM,当单步执行数组时,它会很好地通过 readArray 序列,将通过 sum 序列十次(尽管给出错误的总和),但只通过 printArray 4 次......我不知道为什么。

标签: arrays assembly integer sum mips


【解决方案1】:

在我认为完全相同的任务上与你处于相同的位置。

关于数组....

如果你将数组定义为空间,它会给你一些奇怪的问题......如果你将它定义为单词。你不会有这样的问题。我猜这是因为内核中空格和单词的对齐方式不同,因为我确实注意到内核级别的不同操作。

然而……关于总和……我不断得到荒谬的答案,主要是 0、1 或 -1。

【讨论】:

  • 是的,当我将数组定义为空间时,它甚至不会开始运行程序。我真的不知道从哪里开始调试这个东西。它将运行 sum 循环和 readArray 循环十次,但只有 printArray 循环四次。真的很奇怪..
  • 是的,.word 在 MARS 使用的传统 MIPS 程序集中具有隐式对齐。所以使用.align 2.space 40 之前对齐2^2。但这并不是真正的答案。 (我之所以看到它,是因为 Stack Overflow 决定提出这个未解决的老问题以引起注意。)
猜你喜欢
  • 1970-01-01
  • 2019-09-03
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多