我正在尝试用MIPS汇编语言编写简单的程序。我要做的是从键盘读取多个字符并将其保存到文件。我正在使用13个操作码创建文件并使用15个操作码保存字符。我不明白:如何动态分配字符数来写入15个操作码的$ a2(第37行,现在硬编码)。此外,我无法弄清楚如何打印写入我的文件的字符数($ v0包含此值后写入文件,第49行)。
现在程序抛出错误: 第49行:0x00400078处的运行时异常:地址超出范围0x0000002c
这是我的代码:
.data
handle_text:
.space 100 # buffor of 100 characters, bits, bytes?
out_file:
.asciiz "file_out.txt" # out file
asklabel:
.asciiz "\Please enter string to save\n"
countlabel:
.asciiz "\Characters typed:\n"
.text
main:
la $a0, asklabel # text to print
li $v0, 4 # opcode
syscall
la $a0, handle_text # Where to put text
la $a1, handle_text # Number of characters to write
li $v0, 8 # opcode
syscall
li $v0, 13 # system call for open file
la $a0, out_file # output file name
li $a1, 1 # Open for writing (flags are 0: read, 1: write)
li $a2, 0 # mode is ignored
syscall # open a file (file descriptor returned in $v0)
move $s6, $v0 # save the file descriptor
move $a0, $s6 # file handle
la $a1, handle_text # text to print
#line 37
li $a2, 44 # TEXT LENGTH
li $v0, 15 # opcode
syscall
move $t1, $v0 # move v0 to t1 so v0 won't be overwritten
la $a0, countlabel # show text
li $v0, 4 # op code
syscall
move $a0, $t1 # place characters amount in $a0
li $v0, 4 # opcode
syscall
# ERROR. Maybe it's becouse string should be null terminated?
li $v0, 16 # system call for close file
move $a0, $s6 # file descriptor to close
syscall # close file
li $v0, 10 # close app
syscall
答案 0 :(得分:1)
首先
# buffor of 100 characters, bits, bytes?
它们是字节,而不是位。 还有,字符串
la $a1, handle_text
第21行的是完全错误的,因为你必须加载一个数字,而不是一个地址。 你可以使用例如
.data
length: .word 100
[...]
lw $a1, length
另外,请记住,您可以有效地只读取99个字符,因为最后一个必须是'/0'
。
在第37行,您仍然可以使用
lw $a2, length
而不是硬编码的44。
关于这个
# ERROR. Maybe it's because string should be null terminated?
不,这是因为你想打印一个字符串,而$ t1 = $ v0是一个整数。要打印读取字符的数量,您必须调用系统调用1(而不是4)。
要回答你的问题,将普通数字传递给参数并不是很简单,因为你必须设置一个或另一个最大数字。例如,这样,即使输入10个字符,输出也始终为100。解决这个问题的最简单方法是使用“循环”,类似
li $t0, -1
loop:
addi $t0, $t0, 1
lw $t1, handle_text($t0)
bnez $t1, loop
addi $t0, $t0, -1
在代码的末尾,$ t0包含确切的字符数('\0'
和'\n'
除外)。