我正在使用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。我应该如何使用浮点值实现相同的过程?
答案 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。)