简体   繁体   English

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

[英]reading the file name from user input in MIPS assembly

I'm writing a MIPS assembly code that will ask the user for the file name and it will produce some statistics about the content of the file. 我正在编写一个MIPS汇编代码,它会询问用户文件名,并会生成一些有关文件内容的统计信息。

However, when I hard code the file name into a variable from the beginning it works just fine, but when I ask the user to input the file name it does not work. 但是,当我从头开始将文件名硬编码到一个变量中时它工作得很好,但是当我要求用户输入文件名时它不起作用。

after some debugging, I have discovered that the program adds 0x00 char and 0x0a char (check asciitable.com) at the end of user input in the memory and that's why it does not open the file based on the user input. 经过一些调试后,我发现程序在内存中的用户输入结束时添加了0x00 char和0x0a char(检查asciitable.com),这就是为什么它不能根据用户输入打开文件的原因。

anyone has any idea about how to get rid of those extra chars, or how to open the file after getting its name from the user?? 任何人都知道如何摆脱那些额外的字符,或如何从用户获取其名称后打开文件?

here is my complete code (it is working fine except for the file name from user thing, and anybody is free to use it for any purpose he/she wants to): 这是我的完整代码(它正常工作,除了来自用户的文件名,任何人都可以自由地将它用于他/她想要的任何目的):

        .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

Note: I'm using MARS Simulator, if that makes any different 注意:我正在使用MARS Simulator,如果这有任何不同

Update: I have solved the problem by writing and calling the following procedure: 更新:我已通过编写并调用以下过程解决了该问题:


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

Character 10 (0xa) is the Ascii code for linefeed, which many *nix operating systems use for line terminator. 字符10(0xa)是换行符的Ascii代码,许多* nix操作系统用于行终止符。 It should not be part of the filename. 它不应该是文件名的一部分。 Just strip it off. 把它脱掉。 Also, such operating systems use 0 for a string terminator. 此外,这种操作系统使用0作为字符串终止符。 It should be at the end of the filename unless the open call takes a number of characters parameter. 它应该在文件名的末尾,除非打开调用需要多个字符参数。

The solution is to take the user's reply, find character 10 and replace it with zero. 解决方案是获取用户的回复,找到字符10并将其替换为零。 Use the result as the filename to open. 使用结果作为文件名打开。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM