使用内存映射IO打印浮点值

时间:2017-12-08 17:10:09

标签: assembly mips mars-simulator

我正在使用MIPS构建计算器,结果需要以浮点数舍入到小数点后两位。 这是我在MIPS显示中打印任何内容的子程序:

mmOut:
lui $t0, 0xffff

mmOutLoop:  

lw      $t1, 8($t0)
andi    $t1, $t1,0x0001
beq     $t1, $zero, mmOutLoop
sw      $a0, 12($t0)    //$a0 has the result I wish to print
jr      $ra //return address of mmOut

目前我将结果(从计算中)存储到堆栈中,然后将其转换为ASCII。我应该如何使用浮点值实现相同的过程?

1 个答案:

答案 0 :(得分:1)

正如我评论的那样,将结果写入内存映射I / O与float->字符串转换问题无关。这些基本上是两个单独的步骤。对于按打印顺序生成结果的算法部分,您可以直接将它们发送到MMIO,而不是存储到内存中的字符串(如果需要)。

这可能会将计算所花费的时间与等待0xffff + 8的低位变为零的时间花费重叠,这显然意味着0xffff + 12处的MMIO寄存器已准备好接受另一个存储,根据循环在你的代码中。

相关:How to input and output real numbers in assembly language。不幸的是,我只回答了输入(string-> float)部分。

float->字符串可能更容易。可能你想分成整数和小数部分。

获取整数部分(作为浮点数,如果它对于32位整数来说太大)并且可能除以10的大幂,直到它适合int。然后你可以转换为int并对该数字块使用快速整数转换。我想使用FP余数/模数计算得到整数部分的最不重要部分,如果你必须除以10 ^ 9或其他东西使其适合。 (它可能需要多于一个除以10 ^ 9才能使其达到拟合2 ^ 32)。

对于小数部分,请在asm中实现:

print a '.'
while(frac != 0) {
    frac *= 10.0;
    double intpart = floor(frac);  // or trunc, frac should be non-negative
    frac -= intpart;
    store or print intpart (as a single ASCII decimal digit)
}

您可能想使用计数器来限制打印的位数(因为它可能是无限的.999999...或其他东西,我想)。

如果您不想在没有小数部分时打印do{}while而不是.0,请使用.结构。

大多数FPU通过一条指令直接支持所有这些操作。我不熟悉MIPS的FPU指令,但我认为至少通过转换为整数和后退,可以在硬件中使用floor或trunc。

您可以通过将frac乘以100或10000并使用更快的整数内容来加快速度。 (一个2位整数可以快速拆分using a multiplicative inverse with an integer multiply。)