我正在研究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
从用户请求文件名并打开/读取文件没问题。但我无法弄清楚如何存储2个整数,所以我可以执行乘法并保存结果。我假设一个循环逐个字符并存储在一个数组中,但我不知道如何在MIPS中这样做。我也研究了atoi程序并认为它可能有用吗?谢谢你的帮助!
答案 0 :(得分:0)
啊,这是一种有趣的情况,MARS有从键盘输入整数的系统调用,但是你不能重定向它来从文件中读取(让一个人从C和std中欣赏fscanf
输入/输出/文件流的想法)。
据我所知,你必须编写自己的atoi
,即将文件的全部内容读入更大的缓冲区,然后逐个字符地读取,只要这些是数字,转换他们(tempvalue = tempvalue*10 + (char_digit-'0');
)。
当您到达<EOL>/<EOF>
或非数字字符时,tempvalue
将字符串转换为整数,将其存储在某处,稍后用于普通整数运算。也可能检查溢出情况。
那我该做什么:
将文件内容读取到足够大的缓冲区 - 您实际执行此操作,但不为buffer
分配内存。执行buffer: .asciiz ""
将仅保留单个字节(零终止空字符串)。请使用.space 1000
。在调试器中试用,并在加载文件内容后检查.data
内存,以及它如何覆盖newline
数据。
在文件的最后一个字节之后放置额外的零终止符(如果文件在最后一个数字后面结束)(确保你的缓冲区足够大!即如果缓冲区是1000则只读取999个字节)。
创建过程将字符串转换为整数,字符串在地址a0
,返回v0
中的整数值和a0
中下一个字符的地址。
创建过程以跳过非数字字符,地址a0
,结束地址a1
(buffer + 1000
以便在文件根本不包含任何数字字符时终止()返回修改后的a0
...这不是正确的MIPS调用约定,但是对于这种特殊情况使用方便,我已经习惯了,使用我自己的自定义调用规则,使用官方调用约定只在创建一些公共过程时...但是请保留广泛的注释,然后指定过程的作用以及它预期输入的位置以及返回输出的位置以及修改的内容。
然后从main我会调用skip非数字(检查缓冲区是否到达 - >输出错误),读取int,保存v0
某处(s0
或内存),跳过非数字,检查地址,读取int,在其他地方保存v0
(作为第二个值)。
然后你只需要以普通的方式使用这两个值。
进一步编辑:
您可以在读取文件后立即关闭文件(只需将读取的字节数量保留在某处)。除非您有特殊理由不这样做,否则在您不需要资源时尽快释放资源是一种很好的做法。当您一次性阅读整个文件时,您可以在之后将其关闭并忘记它。