可以从文本文件中读取 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,结束地址a1buffer + 1000当文件不包含任何数字字符时终止完全) (returns 修改了 a0 ...这不是正确的 MIPS 调用约定,但在这种特殊情况下使用起来很方便,我已经习惯了,使用我自己的自定义- 过程调用规则,仅在创建某些 public 过程时使用官方调用约定 .. 但随后保留大量注释,指定过程的作用以及它期望输入的位置以及它 returns 输出的位置以及其他内容已修改)。

  • 然后从 main 我会调用 skip 非数字(检查是否到达缓冲区末尾 -> 错误输入),读取 int,将 v0 保存在某处(s0 或内存),跳过非数字,检查地址,读取 int,将 v0 保存在别处(作为第二个值)。

  • 那么你就用普通的方式使用这两个值。

进一步编辑:

您可以在读取文件后立即关闭它(只需将读取的字节数保存在某处即可)。除非有特殊原因,否则最好在不需要时立即释放资源。当您一次读取整个文件时,您可以关闭它并忘记它。