可以从文本文件中读取 2 个整数并将它们相乘的 MIPS 汇编程序
MIPS Assembly program that can read 2 integers from a text file and multiply them
我正在 MARS 中开发一个 MIPS 汇编程序,它只需要能够从用户那里请求一个文件名,然后在该文本文件中乘以 2 个整数。整数必须在不同的行上。该程序还必须将结果输出为 "num1 * num2 = result"。这是我目前拥有的:
.data
file: .asciiz "" #filename for input
prompt: .asciiz "Please enter the file name.\n"
buffer: .asciiz ""
newline: .asciiz "\n"
multi: .asciiz "*"
equals: .asciiz "="
.text
li $v0, 4
la $a0, prompt #display prompt
syscall
li $v0, 8 #save entered string
la $a0, file
li $a1, 200
syscall
li $v0, 13 # system call for open file
la $a0, file # input file name
li $a1, 0 # flag for reading
li $a2, 0 # mode is ignored
syscall # open a file
move $s0, $v0 # save the file descriptor
# reading from file just opened
li $v0, 14 # system call for reading from file
move $a0, $s0 # file descriptor
la $a1, buffer # address of buffer from which to read
li $a2, 1000 # hardcoded buffer length
syscall # read from file
move $s1, $v0 #$t0 = total number of bytes
#where I am stuck:
#
#
#
#
jal output
jal closeFile
li $v0, 10
syscall
output:#needs to have the form: integer1 * integer2 = result
li $v0, 1
move $a0, $t5
syscall
li $v0, 4
la $a0, multi
syscall
li $v0, 1
move $a0, $t6
syscall
li $v0, 4
la $a0, equals
syscall
li $v0, 1
move $a0, $s7
syscall
jr $ra
closeFile:
# Close the file
li $v0, 16 # system call for close file
move $a0, $s0 # file descriptor to close
syscall # close file
jr $ra
向用户请求文件名和opening/reading文件没有问题。但我不知道如何存储这 2 个整数,所以我可以执行乘法并保存结果。我假设一个循环逐个字符地存储在一个数组中,但我不确定如何在 MIPS 中执行此操作。我还研究了一个 atoi 程序,认为它可能有用吗?感谢您的帮助!
啊,这是一种有趣的情况,MARS 具有用于从键盘输入整数的系统调用,但您不能将其重定向到从文件中读取(让人欣赏来自 C 和 std 的 fscanf
in/out/file 分享想法)。
据我所知,你必须自己编写 atoi
,即将文件的全部内容读入某个更大的缓冲区,然后逐个字符地读取它,只要这些是数字, 转换它们 (tempvalue = tempvalue*10 + (char_digit-'0');
).
当您到达 <EOL>/<EOF>
或非数字字符时,tempvalue
将字符串转换为整数,将其存储在某处并稍后用于普通整数运算。也可能检查溢出情况。
那我会怎么做:
将文件内容读入足够大的缓冲区——你确实这样做了,但你没有为 buffer
分配内存。执行 buffer: .asciiz ""
将仅保留单个字节(以零终止空字符串)。而是使用 .space 1000
。在调试器中尝试,并在加载文件内容后检查您的 .data
内存,它是如何覆盖您的 newline
数据的。
在文件的最后一个字节之后放置额外的零终止符(以防文件在最后一个数字之后结束)(确保您的缓冲区足够大!即如果缓冲区为 1000,则仅读取 999 个字节) .
创建过程将字符串转换为整数,字符串在地址 a0
,returns 整数值在 v0
和下一个字符的地址在 a0
.
创建程序跳过非数字字符,地址a0
,结束地址a1
(buffer + 1000
当文件不包含任何数字字符时终止完全) (returns 修改了 a0
...这不是正确的 MIPS 调用约定,但在这种特殊情况下使用起来很方便,我已经习惯了,使用我自己的自定义- 过程调用规则,仅在创建某些 public 过程时使用官方调用约定 .. 但随后保留大量注释,指定过程的作用以及它期望输入的位置以及它 returns 输出的位置以及其他内容已修改)。
然后从 main 我会调用 skip 非数字(检查是否到达缓冲区末尾 -> 错误输入),读取 int,将 v0
保存在某处(s0
或内存),跳过非数字,检查地址,读取 int,将 v0
保存在别处(作为第二个值)。
那么你就用普通的方式使用这两个值。
进一步编辑:
您可以在读取文件后立即关闭它(只需将读取的字节数保存在某处即可)。除非有特殊原因,否则最好在不需要时立即释放资源。当您一次读取整个文件时,您可以关闭它并忘记它。
我正在 MARS 中开发一个 MIPS 汇编程序,它只需要能够从用户那里请求一个文件名,然后在该文本文件中乘以 2 个整数。整数必须在不同的行上。该程序还必须将结果输出为 "num1 * num2 = result"。这是我目前拥有的:
.data
file: .asciiz "" #filename for input
prompt: .asciiz "Please enter the file name.\n"
buffer: .asciiz ""
newline: .asciiz "\n"
multi: .asciiz "*"
equals: .asciiz "="
.text
li $v0, 4
la $a0, prompt #display prompt
syscall
li $v0, 8 #save entered string
la $a0, file
li $a1, 200
syscall
li $v0, 13 # system call for open file
la $a0, file # input file name
li $a1, 0 # flag for reading
li $a2, 0 # mode is ignored
syscall # open a file
move $s0, $v0 # save the file descriptor
# reading from file just opened
li $v0, 14 # system call for reading from file
move $a0, $s0 # file descriptor
la $a1, buffer # address of buffer from which to read
li $a2, 1000 # hardcoded buffer length
syscall # read from file
move $s1, $v0 #$t0 = total number of bytes
#where I am stuck:
#
#
#
#
jal output
jal closeFile
li $v0, 10
syscall
output:#needs to have the form: integer1 * integer2 = result
li $v0, 1
move $a0, $t5
syscall
li $v0, 4
la $a0, multi
syscall
li $v0, 1
move $a0, $t6
syscall
li $v0, 4
la $a0, equals
syscall
li $v0, 1
move $a0, $s7
syscall
jr $ra
closeFile:
# Close the file
li $v0, 16 # system call for close file
move $a0, $s0 # file descriptor to close
syscall # close file
jr $ra
向用户请求文件名和opening/reading文件没有问题。但我不知道如何存储这 2 个整数,所以我可以执行乘法并保存结果。我假设一个循环逐个字符地存储在一个数组中,但我不确定如何在 MIPS 中执行此操作。我还研究了一个 atoi 程序,认为它可能有用吗?感谢您的帮助!
啊,这是一种有趣的情况,MARS 具有用于从键盘输入整数的系统调用,但您不能将其重定向到从文件中读取(让人欣赏来自 C 和 std 的 fscanf
in/out/file 分享想法)。
据我所知,你必须自己编写 atoi
,即将文件的全部内容读入某个更大的缓冲区,然后逐个字符地读取它,只要这些是数字, 转换它们 (tempvalue = tempvalue*10 + (char_digit-'0');
).
当您到达 <EOL>/<EOF>
或非数字字符时,tempvalue
将字符串转换为整数,将其存储在某处并稍后用于普通整数运算。也可能检查溢出情况。
那我会怎么做:
将文件内容读入足够大的缓冲区——你确实这样做了,但你没有为
buffer
分配内存。执行buffer: .asciiz ""
将仅保留单个字节(以零终止空字符串)。而是使用.space 1000
。在调试器中尝试,并在加载文件内容后检查您的.data
内存,它是如何覆盖您的newline
数据的。在文件的最后一个字节之后放置额外的零终止符(以防文件在最后一个数字之后结束)(确保您的缓冲区足够大!即如果缓冲区为 1000,则仅读取 999 个字节) .
创建过程将字符串转换为整数,字符串在地址
a0
,returns 整数值在v0
和下一个字符的地址在a0
.创建程序跳过非数字字符,地址
a0
,结束地址a1
(buffer + 1000
当文件不包含任何数字字符时终止完全) (returns 修改了a0
...这不是正确的 MIPS 调用约定,但在这种特殊情况下使用起来很方便,我已经习惯了,使用我自己的自定义- 过程调用规则,仅在创建某些 public 过程时使用官方调用约定 .. 但随后保留大量注释,指定过程的作用以及它期望输入的位置以及它 returns 输出的位置以及其他内容已修改)。然后从 main 我会调用 skip 非数字(检查是否到达缓冲区末尾 -> 错误输入),读取 int,将
v0
保存在某处(s0
或内存),跳过非数字,检查地址,读取 int,将v0
保存在别处(作为第二个值)。那么你就用普通的方式使用这两个值。
进一步编辑:
您可以在读取文件后立即关闭它(只需将读取的字节数保存在某处即可)。除非有特殊原因,否则最好在不需要时立即释放资源。当您一次读取整个文件时,您可以关闭它并忘记它。