MIPS:解析和修改字符串
MIPS : parsing and modifying a string
我必须在 MIPS 中编写程序,我必须使用 MARS 模拟器打开用户输入名称的文件并解析它。
但是,由于系统调用 8(从用户输入中读取字符串)遵循 C 函数 fgets 的语义,我必须先从字符串中删除换行符 \n,然后才能尝试打开文件。
我能够解析字符串(这里我打印每个字符的 ASCII 代码以用于调试目的)。
但是,当我尝试使用行
将换行符更改为 NULL 字符时
sb $zero 0($t1)
Mars在执行过程中遇到异常:
"Runtime exception at 0x00400050: address out of range 0x00000000"
如果我注释掉这一行,程序运行良好并打印字符串的每个 ascii 代码。
.data
prompt : .asciiz "enter filename:\n"
lf : .asciiz "\n"
space : .asciiz " "
.text
la $a0 prompt # asking user for filename
jal print_string
jal read_string
la $t0 ($a0) #copying the string address
lb $t1 0($t0) #loading the first byte
parsing_string : #loop
beq $t1 0 remove_line_feed # reaching the NULL character '[=11=]'
move $a0 $t1 #printing the ascii code
li $v0 1
syscall
la $a0 space #printing a space
li $v0 4
syscall
add $t0 $t0 1 # loading
lbu $t1 ($t0) # the next byte
j parsing_string
remove_line_feed :
sb $zero 0($t1) # runtime exception if i uncomment this line
j end
end :
li $v0 10 # syscall 10 : end program
syscall
read_string : #read a string in $a0
li $a1 100 # $a1 = maximum number of characters to read
li $v0 8 # syscall 8 : fgets()
syscall
jr $ra
print_string : #print string in $a0
li $v0 4 # syscall 4 : print string
syscall
jr $ra
我不明白我在这里做错了什么,在程序的这一点上,寄存器 $t1 应该包含写入换行符的地址。
但是我可能误解了指令保存字节和加载字节的实际工作方式。
非常感谢任何帮助或建议:)
在汇编代码中
sb $zero 0($t1) # runtime exception if i uncomment this line
你使用$t1
作为你要清除的字节的地址。
但事实并非如此。
你用过
la $t0 ($a0) #copying the string address
并且您的所有访问都使用 $t0
。
在 parsing_string
函数的末尾,您读取地址 $t0
处的字符并 将其放入 $t1
:
lbu $t1 ($t0) # the next byte
然后你回到parsing_string
,测试t1是否为0
beq $t1 0 remove_line_feed # reaching the NULL character '[=13=]'
转到remove_line_feed
remove_line_feed :
sb $zero 0($t1) # runtime exception if i uncomment this line
j end
您尝试在地址 0+$t1
处写入零(您刚刚测试为等于零)。
并且模拟器正确地告诉您您尝试在地址 0 处写入并生成错误。
如果您将代码更改为
remove_line_feed :
sb $zero 0($t0) # runtime exception if i uncomment this line
j end
这将消除运行时错误。
但是,它不会使您的代码正确。你想要做的是清除 之前 [=25=]
的 '\n' 并且你的代码应该是
remove_line_feed :
sb $zero -1($t0)
j end
或者,您可以更改比较,而不是搜索字符串的最后 [=25=]
,而是搜索 10(ascii 换行符)并将相同的字符替换为 0。
我必须在 MIPS 中编写程序,我必须使用 MARS 模拟器打开用户输入名称的文件并解析它。 但是,由于系统调用 8(从用户输入中读取字符串)遵循 C 函数 fgets 的语义,我必须先从字符串中删除换行符 \n,然后才能尝试打开文件。
我能够解析字符串(这里我打印每个字符的 ASCII 代码以用于调试目的)。 但是,当我尝试使用行
将换行符更改为 NULL 字符时sb $zero 0($t1)
Mars在执行过程中遇到异常:
"Runtime exception at 0x00400050: address out of range 0x00000000"
如果我注释掉这一行,程序运行良好并打印字符串的每个 ascii 代码。
.data
prompt : .asciiz "enter filename:\n"
lf : .asciiz "\n"
space : .asciiz " "
.text
la $a0 prompt # asking user for filename
jal print_string
jal read_string
la $t0 ($a0) #copying the string address
lb $t1 0($t0) #loading the first byte
parsing_string : #loop
beq $t1 0 remove_line_feed # reaching the NULL character '[=11=]'
move $a0 $t1 #printing the ascii code
li $v0 1
syscall
la $a0 space #printing a space
li $v0 4
syscall
add $t0 $t0 1 # loading
lbu $t1 ($t0) # the next byte
j parsing_string
remove_line_feed :
sb $zero 0($t1) # runtime exception if i uncomment this line
j end
end :
li $v0 10 # syscall 10 : end program
syscall
read_string : #read a string in $a0
li $a1 100 # $a1 = maximum number of characters to read
li $v0 8 # syscall 8 : fgets()
syscall
jr $ra
print_string : #print string in $a0
li $v0 4 # syscall 4 : print string
syscall
jr $ra
我不明白我在这里做错了什么,在程序的这一点上,寄存器 $t1 应该包含写入换行符的地址。 但是我可能误解了指令保存字节和加载字节的实际工作方式。
非常感谢任何帮助或建议:)
在汇编代码中
sb $zero 0($t1) # runtime exception if i uncomment this line
你使用$t1
作为你要清除的字节的地址。
但事实并非如此。 你用过
la $t0 ($a0) #copying the string address
并且您的所有访问都使用 $t0
。
在 parsing_string
函数的末尾,您读取地址 $t0
处的字符并 将其放入 $t1
:
lbu $t1 ($t0) # the next byte
然后你回到parsing_string
,测试t1是否为0
beq $t1 0 remove_line_feed # reaching the NULL character '[=13=]'
转到remove_line_feed
remove_line_feed :
sb $zero 0($t1) # runtime exception if i uncomment this line
j end
您尝试在地址 0+$t1
处写入零(您刚刚测试为等于零)。
并且模拟器正确地告诉您您尝试在地址 0 处写入并生成错误。
如果您将代码更改为
remove_line_feed :
sb $zero 0($t0) # runtime exception if i uncomment this line
j end
这将消除运行时错误。
但是,它不会使您的代码正确。你想要做的是清除 之前 [=25=]
的 '\n' 并且你的代码应该是
remove_line_feed :
sb $zero -1($t0)
j end
或者,您可以更改比较,而不是搜索字符串的最后 [=25=]
,而是搜索 10(ascii 换行符)并将相同的字符替换为 0。