如何使用 MIPS Assembly 从数组中提取整数?

问题描述 投票:0回答:1

我正在尝试使用 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
        

我添加了一些测试打印语句。感谢您的帮助。

assembly mips mars-simulator
1个回答
0
投票

.word 100
保留一个初始化为 100 的存储字,而不是您想要的数组。


.word 0:100
保留 100 个字的存储空间,初始化为 0。当然,您可以在那里使用不同的值进行初始化..


    .align 2
    .space 400

还保留 100 个字(400 个字节),正确对齐并初始化为默认值 (0)。对齐指令很有用,因为

.space
以字节为单位工作并且不提供任何对齐(而
.word
自动提供字对齐)。

© www.soinside.com 2019 - 2024. All rights reserved.