1

我正在尝试用 MIPS 汇编语言编写简单的程序。我想要做的是从键盘读取多个字符并将其保存到文件中。我正在使用 13 个操作码创建文件并使用 15 个操作码保存字符。我不明白:如何为 15 个操作码(第 37 行,现在硬编码)动态分配要写入 $a2 的字符数。此外,我不知道如何打印写入文件的字符数($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 
4

1 回答 1

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)。

要回答您的问题,将普通数字传递给参数并不是很简单,因为您必须以一种或另一种方式设置最大数字。例如,通过这种方式,您的输出始终为 100,即使您输入了 10 个字符。解决此问题的最简单方法是使用“循环”,例如

li $t0, -1
loop:
    addi $t0, $t0, 1
    lw $t1, handle_text($t0)
    bnez $t1, loop
addi $t0, $t0, -1

在代码的末尾, $t0 包含确切的字符数(不包括'\0'and '\n')。

于 2013-04-27T11:26:35.380 回答