MIPS 程序集中读取的文件卡在无限循环中

File Read in MIPS Assembly Stuck in Infinite Loop

提问人:JG98 提问时间:11/29/2022 更新时间:11/29/2022 访问量:27

问:

我正在用MIPS编写一个程序来加密一个简单的文本文件。目前我被卡住了,因为每当我阅读文本块时,它似乎不会停在文件末尾,而是继续以无限字节读取,直到它四舍五入。我不确定为什么会发生这种情况,但 v0 返回读取的0xffffffff字节。我想知道我的程序中是否有逻辑错误,或者我是否使用了错误的文件。任何帮助将不胜感激。

        .include "SysCalls.asm"
        
        .eqv    $key            $a2
            .eqv    $filename   $a3 
        .eqv    $descriptor $t1
        .eqv    textBufSize 1024
        .eqv    maxKeySize  60
        .eqv    fnameSize   255
        .eqv    readOnly    0
        .eqv    writeOnlyCreate 1
        .eqv    writeOnlyAppend 9
        .eqv    sframe      16              
                            
        .data 
encryptOption:  .asciiz  "1: Encrypt the File \n"
decryptOption:  .asciiz  "2: Decrypt the File \n"
exitOption:     .asciiz  "3: Exit \n"

keyPrompt:  .asciiz  "Enter a key (up to 60 characters): \n"
filenamePrompt: .asciiz  "Enter a filename (up to 255 characters): \n"

notFound:   .asciiz  "File Error! \n"

filenameBuf:    .space   fnameSize
keyBuffer:  .space   maxKeySize
textBuffer:     .space   textBufSize
        
        .align  2
keySize:    .word   0
    
        .text
        
        .eqv    Encrypt     1
        .eqv    Decrypt     2
        .eqv    Exit        3
printMenu:  
    la  $a0, encryptOption
    li  $v0, SysPrintString
    syscall
    la  $a0, decryptOption
    li  $v0, SysPrintString
    syscall
    la  $a0, exitOption
    li  $v0, SysPrintString
    syscall
        
getMenuOption:  
    li  $v0, SysReadInt
    syscall
    beq     $v0, Encrypt, startEncrypt
    beq     $v0, Decrypt, startDecrypt  
    beq     $v0, Exit, exit
    j   getMenuOption
    
startEncrypt:
    la  $a0, filenamePrompt
    la  $a1, filenameBuf
    li  $a2, fnameSize
    jal getString
    
    li  $a1, readOnly
    li  $a2, 0   
    la  $a0, filenameBuf
    jal     openFile

    bltz    $descriptor, printMenu      # go to file error if it's not found

    la  $a0, keyPrompt
    la  $a1, keyBuffer
    li  $a2, maxKeySize
    jal getString
        
    beqz    $a3, fileError      # making sure key isn't empty (0 length) by checking # of bytes read
    sw  $a3, keySize
    
    la  $t0, textBuffer     # temp ptr to text
    la  $t1, keyBuffer      # temp ptr to key
    li  $t2, 0      # loading data counter w/ 0
    li  $t3, 0      # loading key counter
    lw  $t4, keySize
getData:
    move    $a0, $descriptor    # move the file descriptor to argument reg to pass during jal
    la  $a1, textBuffer
    li  $a2, textBufSize
    li  $t2, 0          # loading data counter w/ 0
    jal     readFile
    beq $a3, 0, printMenu

    
encrypt:
    beq     $t2, $a3, getData   # if read in 1024 bytes, get next data block
    beq     $t3, $t4, resetKey  # if read in full key, go to reset key data pointer
    lb  $s0, 0($t0)     # store first byte of text into $s0
    beq     $s0, '\n', skipNL   # if this byte is NL skip it and return
    lb  $s1, 0($t1)     # get next key byte
    addu    $s0, $s1, $s0       # encrypt s0 data with key
    sb  $s0, 0($t0)     # store encrypted data back into text buffer
    addi    $t0, $t0, 1     # increment text buffer data pointer
    addi    $t1, $t1, 1     # increment key buffer data pointer
    addi    $t2, $t2, 1     # increment data counter 
    addi    $t3, $t3, 1     # increment key counter 
    j   encrypt

resetKey:
    la  $t0, keyBuffer
    subu    $t3, $t3, maxKeySize 
    j   encrypt
    
skipNL:
    addi    $t0, $t0, 1
    addi    $t3, $t3, 1
    j   encrypt

startDecrypt:
    j   printMenu

#------------------------------------------------------------------------------
#  void readFile(int descriptor, char[] buffer, int maxSize)    
#
#  - routine to open a file with name "filename"
#
#  input:  $a0 --> file descriptor
#      $a1 --> address of input buffer
#   `  $a2 --> max number of characters to read
#
#  return: $a3 --> number of bytes read in  
#------------------------------------------------------------------------------     
readFile:
    subi    $sp, $sp, 4 # reserving space on stack and preserving state                 
        sw  $ra, 0($sp)
        
        li  $v0, SysReadFile
    syscall
        
        move    $a3, $v0        
    lw  $ra, 0($sp)
    addi    $sp, $sp, 4    
    jr  $ra         # return to calling function
        

#------------------------------------------------------------------------------
#  void openFile(string filename, int flags, int mode)  
#
#  - routine to open a file with name "filename"
#
#  input:  $a0 --> filename buffer - null terminated
#      $a1 --> flags
#   `  $a2 --> mode
#
#  return: $t1 --> file descriptor  
#------------------------------------------------------------------------------     
openFile:
    subi    $sp, $sp, sframe    # reserving space on stack and preserving state
    sw  $a0, 0($sp)                             
    sw  $a1, 4($sp)                         
    sw  $a2, 8($sp)                     
        sw  $ra, 12($sp)
        
    li  $v0, SysOpenFile    
    syscall
    move    $descriptor, $v0    # save file descriptor from v0  
    bltz    $v0, fileError      # go to file error if it's not found
    j   retOpenFile
    
fileError: 
    la  $a0, notFound
    li  $v0, SysPrintString
    syscall

retOpenFile:
    lw  $a0, 0($sp)     # restore state and remove stack frame
    lw  $a1, 4($sp) 
    lw  $a2, 8($sp)         
    lw  $ra, 12($sp)
    addi    $sp, $sp, sframe    
    jr  $ra         # return to calling function
                            
#------------------------------------------------------------------------------
#  void getString(char[] buffer, int maxSize, String prompt)    
#
#  - routine to read in string and strip out ending "\n"
#
#  input:  $a0 --> prompt
#      $a1 --> location of where to store the string
#      $a2 --> max size of the string to read in
#
#  return: $a3 --> # of bytes stored in the "buffer"    
#------------------------------------------------------------------------------ 
        .eqv    $aRetValue  $a3
        .eqv    $tPrompt    $t0 
        .eqv    $tCounter   $t1
        .eqv    $tBuffer    $t2
        .eqv    $tMaxSize   $t3
                
getString:
    subi    $sp, $sp, sframe    # reserving space on stack and preserving state
    sw  $a0, 0($sp)                                 
    sw  $a1, 4($sp)                             
    sw  $a2, 8($sp)                     
        sw  $ra, 12($sp)

    move    $tPrompt, $a0
    move    $tBuffer, $a1
    move    $tMaxSize, $a2
    
    li  $v0, SysPrintString
    syscall
    
    move    $a0, $tBuffer
    move    $a1, $tMaxSize
    li  $v0, SysReadString
    syscall
        
# removes NL character from the end of the string and replace it will null  
            
    move    $a0, $tBuffer       # put filename address in a0 for cleaning
    li  $tCounter, 0        # initializing counter to 0
nextChar:   
    lb  $t0, 0($a0)
    addi    $tCounter, $tCounter, 1     # incrementing counter      
    bne     $t0, '\n', skipChar     # if it is not new line character, then skip the character 
    li  $t0, 0          # if it is new line character, change it to null terminator
    sb  $t0, 0($a0)     # putting the null terminator into place where NL is
    j   retGetString        # return to caller
        
skipChar:   
    addi    $a0, $a0, 1     # increment filename data pointer
    j   nextChar
    
retGetString:
    move    $aRetValue, $tCounter   # return the number of bytes in the string buffer
    lw  $a0, 0($sp)     # restore state and remove stack frame
    lw  $a1, 4($sp)     
    lw  $a2, 8($sp)     
    lw  $ra, 12($sp)
    addi    $sp, $sp, sframe    
    jr  $ra         # return to calling function

#------------------------------------------------------------------------------
#  EXIT from Program
#------------------------------------------------------------------------------                 
exit: 
    li  $v0, SysExit
        syscall 

The error

registers

程序集 文本 文件- IO MIPS

评论

0赞 Jester 11/29/2022
您别名,然后与其他用途(例如 .请注意,这是并指示错误(即指示器无效),并且第一次也不应该工作。因此,整个读取多个块并点击文件末尾是一条红鲱鱼。$descriptor$t1la $t1, keyBuffer0xffffffff-1readFile
0赞 JG98 11/29/2022
好的,感谢您提供的信息,这至少缩小了范围。希望修复数据冲突将使我能够正确读取文件。
0赞 Erik Eidt 11/29/2022
此外,您可以尝试让零件首先在他们自己的程序中工作,然后将它们组合到您的项目中。我要说的是,仅仅为了读取文件,就需要大量的代码(进行调试)。
0赞 JG98 11/29/2022
@ErikEidt 这是个好主意,尽管我不确定我现在是否有时间。不幸的是,解决冲突没有奏效。现在我在打开文件时没有收到错误,但是在读取它时读取了 0 字节。

答: 暂无答案