2010-04-04 18 views
5

Estoy escribiendo un código ensamblador MIPS que le preguntará al usuario el nombre del archivo y generará algunas estadísticas sobre el contenido del archivo.leyendo el nombre del archivo de la entrada del usuario en el ensamblado MIPS

Sin embargo, cuando codifico el nombre del archivo en una variable desde el principio funciona bien, pero cuando le pido al usuario que ingrese el nombre del archivo, no funciona.

después de algunas depuraciones, he descubierto que el programa agrega 0x00 char y 0x0a char (ver asciitable.com) al final de la entrada del usuario en la memoria y es por eso que no abre el archivo basado en la entrada del usuario.

¿alguien tiene alguna idea sobre cómo deshacerse de esos caracteres adicionales, o cómo abrir el archivo después de obtener su nombre del usuario?

aquí es mi código completo (que está funcionando bien, excepto por el nombre de archivo que el usuario, y cualquiera es libre de usarlo para cualquier propósito que él/ella quiere):

 .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 

Nota: I 'm usando MARS simulador, si eso tiene diferentes

actualización: he resuelto el problema escribiendo y llamando al siguiente procedimiento:

 
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 

Respuesta

4

Characte r 10 (0xa) es el código Ascii para salto de línea, que muchos sistemas operativos * nix usan para el terminador de línea. No debería ser parte del nombre del archivo. Solo quítatelo. Además, dichos sistemas operativos usan 0 para un terminador de cadena. Debe estar al final del nombre de archivo a menos que la llamada abierta tome un número de caracteres parámetro.

La solución es tomar la respuesta del usuario, encontrar el carácter 10 y reemplazarlo por cero. Use el resultado como el nombre del archivo para abrir.

+0

Gracias que han resuelto el problema, escribiendo y llamando al siguiente procedimiento

 nameClean: \t li $t0, 0 \t \t #loop counter \t li $t1, 21 \t \t #loop end clean: \t beq $t0, $t1, L5 \t lb $t3, fin($t0) \t bne $t3, 0x0a, L6 \t sb $zero, fin($t0) \t L6: \t addi $t0, $t0, 1 j clean L5: jr $ra 

Cuestiones relacionadas