Mips-打印到文件
Mips- print to file
我想将一些内容(字符串和浮点数)打印到文件中。
这就是我到目前为止实施的内容:
.data:
line_break: .asciiz "\n"
buffer: .space 1024
.text:
main:
addi $t0, $zero, -1
jal open_file # open the file to write to
beq $v0, $t0, create_file # if return value -1 --> file not available --> create the file
move $s6, $v0 # save the file descriptor
[...]
ulw $t0, print_initiaton_message # save the print_initiaton_message in a temp
sw $t0, buffer # put print_initiaton_message on buffer
li $v0, 15 # syscall to write to file
move $a0, $s6 # move file descriptor to $a0
la $a1, buffer # target to write from
li $a2, 1024 # amount to be written
syscall # syscall to write in file
[...]
s.s $f12, buffer
li $v0, 15 # syscall to write to file
move $a0, $s3 # move file descriptor to $a0
la $a1, buffer # target to write from
li $a2, 4 # amount to be written
syscall # syscall to write in file
[...]
基本思路是将必要的信息放入缓冲区,然后进行系统调用。
它似乎可以工作 - 因为文件已正确创建、打开和关闭。里面也有内容,但是没有预期的结果:
’®)@
PÀ<@
[...]
第一个位置应该是一个字符串,然后是一个换行符,然后是一个浮点数。
现在我的问题是:
- 如何实现输出的正确格式?
- 缓冲区大小代表什么?如果我的输入超过缓冲区大小,会发生什么情况?
- 写入的数量是什么意思?
我尝试浏览了几个系统调用参考(即 this one), looked for examples (and found this, or that),但主要问题是它们只提供代码而没有涵盖我上面的问题。
sw $t0, buffer
这行代码会将缓冲区的前 32 位设置为 print_initiaton_message
的地址。我不熟悉文件 I/O 系统调用;但是,我想知道你是否真的想这样做:
li $v0, 15 # syscall to write to file
move $a0, $s6 # move file descriptor to $a0
la $a1, print_initiation_message # target to write from
li $a2, <actual length of initiation message>
syscall # syscall to write in file
我终于找到了解决方案:
我将numbers/strings的大小设置为1024打印出来。因此,我的程序从缓冲区的地址中获取内容,并从堆(或数据)部分打印额外的 1023 个字符。我通过计算字符串中的字符数量来解决这个问题(因为这是一个用于教育目的的项目,这没关系)并将大小设置为字符数量;而 \n 是一个字节。
我的程序打印出的奇怪字符是ASCII符号,代表它们对应的十六进制值。我的错误是假设我必须从左到右阅读字符。由于 MIPS 使用 Big Endian format 必须从右到左读取 ASCII 字符。创建一个十六进制转储并计算相应的浮点数导致正确的结果。
为了避免混淆基于 ASCII 的输出,需要进行额外的字符串转换。想法是为每个数字计算其对应的 ASCII 字符,然后打印结果值。
我想将一些内容(字符串和浮点数)打印到文件中。
这就是我到目前为止实施的内容:
.data:
line_break: .asciiz "\n"
buffer: .space 1024
.text:
main:
addi $t0, $zero, -1
jal open_file # open the file to write to
beq $v0, $t0, create_file # if return value -1 --> file not available --> create the file
move $s6, $v0 # save the file descriptor
[...]
ulw $t0, print_initiaton_message # save the print_initiaton_message in a temp
sw $t0, buffer # put print_initiaton_message on buffer
li $v0, 15 # syscall to write to file
move $a0, $s6 # move file descriptor to $a0
la $a1, buffer # target to write from
li $a2, 1024 # amount to be written
syscall # syscall to write in file
[...]
s.s $f12, buffer
li $v0, 15 # syscall to write to file
move $a0, $s3 # move file descriptor to $a0
la $a1, buffer # target to write from
li $a2, 4 # amount to be written
syscall # syscall to write in file
[...]
基本思路是将必要的信息放入缓冲区,然后进行系统调用。
它似乎可以工作 - 因为文件已正确创建、打开和关闭。里面也有内容,但是没有预期的结果:
’®)@
PÀ<@
[...]
第一个位置应该是一个字符串,然后是一个换行符,然后是一个浮点数。
现在我的问题是: - 如何实现输出的正确格式? - 缓冲区大小代表什么?如果我的输入超过缓冲区大小,会发生什么情况? - 写入的数量是什么意思?
我尝试浏览了几个系统调用参考(即 this one), looked for examples (and found this, or that),但主要问题是它们只提供代码而没有涵盖我上面的问题。
sw $t0, buffer
这行代码会将缓冲区的前 32 位设置为 print_initiaton_message
的地址。我不熟悉文件 I/O 系统调用;但是,我想知道你是否真的想这样做:
li $v0, 15 # syscall to write to file
move $a0, $s6 # move file descriptor to $a0
la $a1, print_initiation_message # target to write from
li $a2, <actual length of initiation message>
syscall # syscall to write in file
我终于找到了解决方案:
我将numbers/strings的大小设置为1024打印出来。因此,我的程序从缓冲区的地址中获取内容,并从堆(或数据)部分打印额外的 1023 个字符。我通过计算字符串中的字符数量来解决这个问题(因为这是一个用于教育目的的项目,这没关系)并将大小设置为字符数量;而 \n 是一个字节。
我的程序打印出的奇怪字符是ASCII符号,代表它们对应的十六进制值。我的错误是假设我必须从左到右阅读字符。由于 MIPS 使用 Big Endian format 必须从右到左读取 ASCII 字符。创建一个十六进制转储并计算相应的浮点数导致正确的结果。
为了避免混淆基于 ASCII 的输出,需要进行额外的字符串转换。想法是为每个数字计算其对应的 ASCII 字符,然后打印结果值。