我正在尝试使用 MIPS 汇编语言从数组中提取整数,然后将它们相加并打印它们。我正在使用 MARS IDE 编写此代码,并且我对 MIPS 非常陌生。看来用户输入的值已正确存储在堆中。但是,我不知道如何提取这些值并将它们相加来计算总和。这是我的代码:
.data
numsArray: .word 100
prompt1: .asciiz "Enter an int n (# of integers): "
prompt2: .asciiz "Input "
prompt3: .asciiz " \nwith a space between each value, then press enter: "
newLine: .asciiz " \n"
inputString: .word 100
.text
main:
# Display enter n
li $v0, 4
la $a0, prompt1
syscall
# Get n from user input
li $v0, 5
syscall
move $t0, $v0 # Store n in $t0 instead of $v0 (we will need $v0 later)
# Calculate number of bytes needed for 0
move $a0, $t0 # move n to arg0
li $t4, 4 # 4 is size of an int (one word)
mul $a0, $a0, $t4 # multiply n by 4
mflo $t1 # move result from lo to $t1
# Allocate memory for 0 based on n * 4 ($t1)
li $v0, 9
move $a0, $t1
syscall
move $t2, $v0
# Display prompt for getting n values from user input
li $v0, 4
la $a0, prompt2
syscall # print prompt2
li $v0, 1
move $a0, $t0
syscall # print n
li $v0, 4
la $a0, prompt3
syscall # print prompt3
# Get the input string (containing n ints) from user
li $v0, 8 # syscall for read string
la $a0, inputString # load address of inputString
li $a1, 100 # set $a1 to max number of chars to read
syscall
la $t3, inputString # load address of word stored at inputString
# Loop to get n ints from user and put in memory
li $t4, 0 # start counter for getNIntsLoop
# Begin loop
getNIntsLoop:
# Currently:
# t0=n: Number of integers to retrieve
# t1=bytes_for_arr: Number of bytes needed for the array (4 * n)
# t2=addr_for_arr: Address where the integers will be stored
# t3=input_word_containing_nums: Address of the word stored at inputString
# t4=loop_counter: Counter for the number of integers retrieved so far
# t5=last_loaded_byte: Last byte loaded from the input string
# t6=uncalculated_sum: Variable to temporarily store the sum of integer
# Check if loop should end ($t4 == n)
beq $t4, $t0, endGetNIntsLoop # exit loop when all ints retrieved
# Load byte and check if it is a space or enter key
lb $t5, 0($t3) # load byte from input string at address stored in $t3
beq $t5, 31, skipFirstByte # check for unexpected control character (ASCII 31)
beq $t5, 32, saveLastInt # skip this parse and save int if char is a space (ASCII 32)
beq $t5, 10, saveLastInt # skip this parse and save int if char is an enter (ASCII 10)
# Not a space, continue parsing
subi $t5, $t5, 48 # convert ASCII to int
mul $t6, $t6, 10 # multiply current parsed int by 10
add $t6, $t6, $t5 # add current digit to current int
addi $t3, $t3, 1 # move to next byte in input string
j getNIntsLoop
skipFirstByte:
addi $t3, $t3, 1 # move to next byte (skip the control character)
j getNIntsLoop
saveLastInt:
# Save the parsed int to the array (assuming $t6 holds complete int)
sw $t6, 0($t2)
# TEST PRINTING VALS
li $v0, 1
move $a0, $t6
syscall
li $v0, 1
lw $a0, 0($t2)
syscall
li $v0, 4
la $a0, newLine
syscall
# TEST PRINTING VALS
addi $t2, $t2, 4 # move to next memory location in array
addi $t3, $t3, 1 # move to next byte in word
li $t6, 0 # reset $t5 to 0
addi $t4, $t4, 1 # increment count
j getNIntsLoop
endGetNIntsLoop:
la $t2, 0 # $t2 needs to be reset to base address of numsArray
# TEST PRINTING VALS
# PRINT THE ADDRESS TO ARRAY
li $v0, 34
la $a0, 0
syscall
li $v0, 4
la $a0, newLine
syscall
# TRY TO PRINT THE FIRST NUM IN ARR
li $v0, 1
la $t3, 0($t2)
srl $a0, $t3, 30
syscall
li $v0, 4
la $a0, newLine
syscall
# TRY TO PRINT ADDRESS FOR FIRST INT
li $v0, 34 # System call code for printing integer address
move $a0, $t3 # Load the address of the most significant byte
syscall
li $v0, 4
la $a0, newLine
syscall
# TRY TO PRINT THE 2nd INT IN ARR
lw $t3, 4($t2)
li $v0, 1
move $a0, $t3
syscall
# TEST PRINTING VALS
li $t5, 0 # $t5 will store the sum
getSumLoop:
beq $t4, $zero, endSumLoop # exit loop after all ints added to sum
lw $t6, 0($t2) # load int from memory
add $t5, $t5, $t6 # add int to sum stored in $t5
subi $t2, $t2, 4 # move to next int in numsArray
addi $t4, $t4, -1 # decrement loop counter (reusing old loop counter!)
j getSumLoop # call loop again
endSumLoop:
# Print sum stored at $t5
li $v0, 1 # syscall 1 == print integer
move $a0, $t5 # move sum stored in $t5 to $a0
syscall # print sum
# Exit program
li $v0, 10
syscall
我添加了一些测试打印语句。感谢您的帮助。
.word 100
保留一个初始化为 100 的存储字,而不是您想要的数组。
.word 0:100
保留 100 个字的存储空间,初始化为 0。当然,您可以在那里使用不同的值进行初始化..
.align 2
.space 400
还保留 100 个字(400 个字节),正确对齐并初始化为默认值 (0)。对齐指令很有用,因为
.space
以字节为单位工作并且不提供任何对齐(而 .word
自动提供字对齐)。