【问题标题】:Is there a way to store a series of strings into an array with a specific offset in Mips?有没有办法将一系列字符串存储到 Mips 中具有特定偏移量的数组中?
【发布时间】:2023-03-16 17:19:01
【问题描述】:

(我对 Mips 很陌生,我知道我的一些语法和/或逻辑可能看起来很奇怪或不正确。感谢您的理解)。

我被要求从用户那里读取一系列字符串到通过在程序中分配空间创建的数组中。在我的 get_input 函数中,当我使用系统调用 8 读取字符串时,我传递了数组的地址和字符缓冲区大小。

get_input 函数存储输入的字符串,(最多 32 个字符),然后将其传递给 strtrunc 函数以截断字符串末尾的 $zero 值。 strtrunc 函数还计算单词的大小并将值保存到 $v0。

此时,程序返回 get_input 函数并将 $v0 中的值保存到长度数组中,然后增加所用数组的偏移量。

我在存储输入的单词并稍后访问它时遇到了一系列问题 - 最初,我使用四个偏移量作为我的单词数组来存储单词,但是,输入的单词超过了四个字符会将剩余的字符推到下一个偏移量上。

示例(输入感谢):[n a h T][ \0 \0 s k],输入“Again”时的循环与前面的字符重叠:示例(再次输入后):[n a h T][ i a g A] [\0 \0 \0 n] 这就是为什么我为我们在 strtrunc 函数中添加的 $zero 添加了前一个单词大小的偏移量 + 1。

我想这个问题更适合我选择如何将用户输入的字符串保存到数组中。我做错了吗?我稍后应该向后读取输入的字符串,但是,我只能正确读取输入到程序中的第一个字符串。 (我不包括该功能,因为该问题可以很容易地解决)。最后,我可以正确访问长度数组和偏移量为 4 的存储值。这只是我无法正确访问的字符/字符串数组。我希望字符串的地址具有相同的四个偏移量,同时仍然存储整个字符串而不会被以下单词覆盖。

[s k n a h T][n i a g A]

0x0000 0x0004


.data
prompt: .asciiz "Please enter up to 16 strings (max 31 characters) 1 per line\nEnter a blank line to finish inputing the strings.\n"
prompt1: .asciiz "Next string: "

.align 2
strings: .space 512  #16 strings of up to 32 characters each including the null character

.align 2
lengths: .space 64 #Space for 16 values for the length

.text
main:
    # Step 1: Read user-inputted strings
    la $a0, prompt
    li $v0, 4
    syscall
    #Call get_input
    la $a0, prompt1
    la $a1, strings
    li $a2, 32
    jal get_input
    
    # Step 2: Calculate string lengths
    #Already done from get_input and stored into the Lengths Array
    
exit_main:
    li   $v0, 10            # 10 is the exit program syscall
    syscall             # execute call


###############################################################
# Grabs the inputted strings and saves to strings array.
#$a0 - address of prompt to print
#$a1 - address to store string
#$a2 - Max string length
#$s0 - Loop counter
#$t3 - Offset to store information
#$t4 - Load the byte for exit loop
#$t5 - Lengths Array Offset
get_input:
    subi $sp, $sp, 4 #Push return address onto the stack to save it
    sw $ra, ($sp)
    li $s0, 0   #initalize counter variable
    li $t3, 0   #initalize offset variable
    li $t5, 0   #Initalize offset variable
    
get_input_loop:
    beq $s0, 16, end_get_input #Loop statement check
    la $a0, prompt1
    li $v0, 4   #Syscall for prompt text
    syscall
    
    la $a0, strings($t3)    #$a1 has the location to store the string, move that into $a0 for the read word syscall
    move $a1, $a2       #$a2 has the maximum character buffer, move that into $a1 for the read word syscall
    li $v0, 8
    syscall
                #$a0 now has the inputted word—We want to manipulate. Trucnate and then store the word inside of the array.
    lbu $t4, ($a0)      #Check to see if the inputted word is null or just a space
    beq $t4, $zero, end_get_input   #If so, exit loop
    
                #Trunc the string
    jal strtrunc
    beq $t4, 0x20, end_get_input #If the inputted byte is a space, exit the loop
    
                #At this point $v0 has the length of the string and the truncatted string has been saved 
    sw $v0, lengths($t5)    #Store the length found in $v0 to lengths
    addi $t5, $t5, 4    #Add 4 to the lengths offest
    add $t3, $t3, $v0   #Add whatever the length of the last string was to the word offest 
    addi $t3, $t3, 1    #Add one more for the $zero we added in the strtrunc function
    addi $s0, $s0, 1    #Add one to the total count of the strings array

    j get_input_loop
end_get_input:
    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra
###############################################################
#Truncate string at newline character.
#$a0 - address of string
#Returns
#$v0 - Length of string
strtrunc:
    move $t0, $zero
    move $t1, $a0
str_loop:
    lbu $t2, ($t1)          #Character at a spot in the word
    beq $t2, 0x20 end_strtrunc  #If the byte is a space
    beq $t2, 0xA end_strtrunc
    beq $t2, 0x0 end_strtrunc
        addi $t0, $t0, 1    #Length of string
        addi $t1, $t1, 1    #Byte offset
    j str_loop
    
end_strtrunc:
    sb $zero, ($t1)
    move $v0, $t0
    jr $ra

【问题讨论】:

  • 您将所有字符串打包到字符串空间中。因此,要访问第二个字符串,您必须添加第一个字符串的长度(+1 表示 null),要访问第三个字符串,您必须知道第二个字符串的地址并添加其长度 +1,或从第一个开始,并添加第一个字符串的长度和第二个字符串的长度(+nulls)。
  • 但是jal get_input 之后没有显示任何代码,那么您的问题是什么?
  • 与字符数据分开,您可以存储一个指向每个字符串开头的指针数组,以便您可以随机索引到它。赞 Cchar *argv[]

标签: arrays string assembly mips


【解决方案1】:

Erik Eidt 为我提供了一个非常直接的答案——我希望我不必根据前一个字符串的大小/长度进行迭代,但是,这是我可以在以我目前的知识。 由于我将所有字符串存储到我的数组中,我可以根据第一个字符串的大小 +1 迭代到第二个字符串。要到达第三个字符串,我必须知道第二个字符串的地址并根据第二个字符串的大小进行迭代。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2021-09-23
    • 1970-01-01
    相关资源
    最近更新 更多