【问题标题】:Is there an efficient way in MIPS to store floating point numbers in a dynamically allocated array?MIPS 中是否有一种有效的方法将浮点数存储在动态分配的数组中?
【发布时间】:2019-04-08 01:46:01
【问题描述】:

我正在尝试使用 MIPS 将浮点数列表存储在动态数组中。程序提示用户输入浮点数,然后在接收输入的同时循环。

对于整数,我知道如何做到这一点,但我很难让它与浮点数一起使用。这是我现在拥有的。

这将获取要输入的浮点数并相应地分配内存:

#get number of floats to be entered
li $v0, 5
syscall
move $t0, $v0      #t0 is number of floats

#allocate the memory required
sll $a0, $v0, 2
li $v0, 9
syscall

这是我收集花车的循环:

move $t1, $zero #idx for loop
move $t2, $v0 #t2 is address of dynamic memory

loop:
    bge $t1, $t0, done #idx check 

    li $v0, 4
    la $a0, prompt #prompt user input
    syscall

    # read in and store int
    li $v0, 6
    syscall
    sw $v0, 0($t2)

    addi $t1, $t1, 1   # ++idx
    addi $t2, $t2, 4   #add four to move to next memory location
    j loop

done:

对于输入的任何浮点数,此处的输出仅为 0.0,而它应该是用户输入的数字。我想我一定是把它们存储错了。有没有比这更好的方法来引入花车?

【问题讨论】:

  • v0 是系统调用存放读取结果的寄存器吗?这是什么系统?如果你一读取就打印数字,输出是什么?
  • v0 应该是系统调用放入结果的变量。这是 MIPS,在 MARS 模拟器上运行。在 MARS 中,您可以看到寄存器值,它似乎根本没有将浮点数存储在 v0 中。
  • MIPS 是指令集架构的名称。那只是“硬件”。它需要软件来做任何事情。 MARS 是一个模拟器,per its documentation 提供一些基本的类似操作系统的服务。因此,syscall 服务是 MARS 的一部分,而不是 MIPS。如答案所述,syscall #6 在f0 中返回结果,而不是v0
  • 啊,明白了,谢谢!

标签: arrays floating-point mips


【解决方案1】:

浮点数和双精度数不在普通整数寄存器中。他们有自己的寄存器$f0..$f31

syscall 6(和 syscall 7 对于双精度数)在 $f0(不是 $v0)中返回他们的结果,而打印浮点数和双精度数的 syscall 2syscall 3 期望它们在 $f12 中的参数。

使用lwsw 无法在浮点寄存器中复制操作数。您必须改用:

  • lwc1(加载字到协处理器 1)lwc1 ft, offset(base reg)
  • ldc1(加载双重到协处理器 1)ldc1 ft, offset(base reg)
  • swc1(存储来自协处理器 1 的字)swc1 ft, offset(base reg)
  • sdc1(将双精度存储到协处理器 1)sdc1 ft, offset(base reg)

所以你的代码应该是:

move $t1, $zero #idx for loop
move $t2, $v0 #t2 is address of dynamic memory

loop:
    bge $t1, $t0, done #idx check 

    li $v0, 4
    la $a0, prompt #prompt user input
    syscall

    # read in and store floats
    li $v0, 6
    syscall
    swc1 $f0, 0($t2)  # read float is in $f0 

    addi $t1, $t1, 1   # ++idx
    addi $t2, $t2, 4   #add four to move to next memory location
    j loop

done:

【讨论】:

    【解决方案2】:

    浮点值通常占用寄存器 $f0 到 $f31,它们与 $0(AKA $0)到 $31(AKA $ra)完全分开。

    您可以使用 lwc1/swc1(单精度)和 ldc1/sdc1(双精度)指令加载和存储这些浮点寄存器。这与使用 lw/sw 指令非常相似。

    还要注意,浮点寄存器在经典 MIPS 处理器上是 32 位的,因此双精度值占用相邻的寄存器(也就是说,在任何给定时间,浮点寄存器中的双精度值可能不超过 16 个) .当使用 ldc1/sdc1(和任何浮点算术指令)进行双精度时,您指定偶数的一个 ($f0, $f2, ..., $f30) 和下一个 ($f1, $f3, . .., $f31) 是隐含的。

    【讨论】:

      猜你喜欢
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      相关资源
      最近更新 更多