提问人:JG98 提问时间:11/29/2022 更新时间:11/29/2022 访问量:27
MIPS 程序集中读取的文件卡在无限循环中
File Read in MIPS Assembly Stuck in Infinite Loop
问:
我正在用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
答: 暂无答案
上一个:如何清除EOF指标?
评论
$descriptor
$t1
la $t1, keyBuffer
0xffffffff
-1
readFile