assembly - 从 MIPS 程序集中的用户输入读取文件名

标签 assembly mips mars-simulator

我正在编写一个 MIPS 汇编代码,它将询问用户文件名,并生成有关文件内容的一些统计信息。

但是,当我从一开始就将文件名硬编码到变量中时它工作得很好,但是当我要求用户输入文件名时它不起作用。

经过一些调试,我发现该程序在内存中用户输入的末尾添加了 0x00 字符和 0x0a 字符(检查 asciitable.com),这就是它不会根据用户输入打开文件的原因。

任何人都知道如何摆脱那些额外的字符,或者如何在从用户那里获得文件名后打开文件?

这是我的完整代码(除了来自用户事物的文件名外,它工作正常,任何人都可以自由地将它用于他/她想要的任何目的):

        .data
fin:   .ascii ""      # filename for input
msg0:   .asciiz "aaaa"
msg1:   .asciiz "Please enter the input file name:"
msg2:   .asciiz "Number of Uppercase Char: "
msg3:   .asciiz "Number of Lowercase Char: "
msg4:   .asciiz "Number of Decimal Char:   "
msg5:   .asciiz "Number of Words:          "
nline:  .asciiz "\n"
buffer: .asciiz ""
        .text

#-----------------------
    li $v0, 4
    la $a0, msg1
    syscall

    li $v0, 8
    la $a0, fin
    li $a1, 21
    syscall

    jal fileRead            #read from file

    move $s1, $v0           #$t0 = total number of bytes

    li $t0, 0   # Loop counter
    li $t1, 0   # Uppercase counter
    li $t2, 0   # Lowercase counter
    li $t3, 0   # Decimal counter
    li $t4, 0   # Words counter

loop:
    bge $t0, $s1, end           #if end of file reached OR if there is an error in the file
    lb $t5, buffer($t0)         #load next byte from file

    jal checkUpper              #check for upper case
    jal checkLower              #check for lower case
    jal checkDecimal            #check for decimal
    jal checkWord               #check for words


    addi $t0, $t0, 1            #increment loop counter

j loop

end:

    jal output
    jal fileClose

    li $v0, 10
    syscall







fileRead:
    # Open file for reading
    li   $v0, 13       # system call for open file
    la   $a0, fin      # input file name
    li   $a1, 0        # flag for reading
    li   $a2, 0        # mode is ignored
    syscall            # open a file 
    move $s0, $v0      # save the file descriptor 

    # reading from file just opened
    li   $v0, 14       # system call for reading from file
    move $a0, $s0      # file descriptor 
    la   $a1, buffer   # address of buffer from which to read
    li   $a2, 100000   # hardcoded buffer length
    syscall            # read from file

jr $ra

output:
    li $v0, 4
    la $a0, msg2
    syscall

    li $v0, 1
    move $a0, $t1
    syscall

    li $v0, 4
    la $a0, nline
    syscall

    li $v0, 4
    la $a0, msg3
    syscall

    li $v0, 1
    move $a0, $t2
    syscall

    li $v0, 4
    la $a0, nline
    syscall

    li $v0, 4
    la $a0, msg4
    syscall

    li $v0, 1
    move $a0, $t3
    syscall

    li $v0, 4
    la $a0, nline
    syscall

    li $v0, 4
    la $a0, msg5
    syscall

    addi $t4, $t4, 1
    li $v0, 1
    move $a0, $t4
    syscall

jr $ra

checkUpper:
    blt $t5, 0x41, L1           #branch if less than 'A'
    bgt $t5, 0x5a, L1           #branch if greater than 'Z'
    addi $t1, $t1, 1            #increment Uppercase counter

    L1:
jr $ra

checkLower:
    blt $t5, 0x61, L2           #branch if less than 'a'
    bgt $t5, 0x7a, L2           #branch if greater than 'z'
    addi $t2, $t2, 1            #increment Lowercase counter

    L2:
jr $ra

checkDecimal:
    blt $t5, 0x30, L3           #branch if less than '0'
    bgt $t5, 0x39, L3           #branch if greater than '9'
    addi $t3, $t3, 1            #increment Decimal counter

    L3:
jr $ra

checkWord:
    bne $t5, 0x20, L4           #branch if 'space'
    addi $t4, $t4, 1            #increment words counter

    L4:
jr $ra

fileClose:
    # Close the file 
    li   $v0, 16       # system call for close file
    move $a0, $s0      # file descriptor to close
    syscall            # close file
jr $ra

注意:我正在使用 MARS Simulator,如果这有什么不同的话

更新:
我已经通过编写和调用以下过程解决了这个问题:
nameClean:
    li $t0, 0       #loop counter
    li $t1, 21      #loop end
clean:
    beq $t0, $t1, L5
    lb $t3, fin($t0)
    bne $t3, 0x0a, L6
    sb $zero, fin($t0)
    L6:
    addi $t0, $t0, 1
j clean
L5:
jr $ra

最佳答案

字符 10 (0xa) 是换行符的 Ascii 代码,许多 *nix 操作系统将其用作行终止符。它不应该是文件名的一部分。剥掉就行了此外,此类操作系统使用 0 作为字符串终止符。它应该在文件名的末尾,除非 open 调用采用多个字符参数。

解决办法是取用户的回复,找到第10个字符,用0代替。使用结果作为打开的文件名。

关于assembly - 从 MIPS 程序集中的用户输入读取文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2575867/

相关文章:

assembly - MARS MIPS 模拟器执行窗口不会展开

assembly - x86-64 规范地址?

assembly - ldr 和 ldr.w 的区别

binary - 计算数字的二进制表示形式中 1 的数量的最佳方法。 (MIPS)

c - 错误 : conflicting types for ‘whatever’

C++ 内联汇编错误

macos - 在 Mac 上使用汇编

algorithm - 用mips写俄罗斯农民乘法

assembly - 为什么我不能在 MARS 中使用 li.s?