如何在 MIPS 中通过 $a0 传递浮点数?
How can I pass floating point numbers through $a0 in MIPS?
我正在编写一个 MIPS 库,我计划在其中通过 $aX
寄存器传递所有参数,并通过 $vX
寄存器传递 return 所有值。
我写了下面的函数:
# PrintFloat - prints a float
# arguments:
# $a0 = arress of the float
# return value:
# n/a
PrintFloat:
move $f12, $a0
li $v0, 2
syscall
# return
jr $ra
此函数未在 MARS 中编译。
我这里有三个问题:
- 根本不可能通过
$a
寄存器传递浮点数吗?
- 我是否应该将库设计为通过
$sp
传递参数(使用 $sp
比较混乱)?
- 我是否需要在像这样的每个微不足道的函数中创建堆栈帧以使其成为非叶安全的?
Is it not possible to pass floats through $a registers at all?
有可能。但在 MIPS 中,由于历史原因,FP 被视为协处理器,您必须使用特定指令在处理器和协处理器之间复制移动数据:MFC
(从协处理器移动)和 MTC
(移动到协处理器). FP单元为协处理器1,对应指令为mfc1
和mtc1
.
mfc1 rt, fs # copy data from fp register fs to gp register rt
与复制到 fp 寄存器类似,使用 mtc1
mtc1 rs, ft # copy data from gp register rs to fp register ft
所以你只需要使用
mfc1 $a0, $f12
将 $f12 放入 $a0。
Should I design the library to pass the arguments through $sp instead (using $sp is comparatively messy)?
不,它没有用,除非你有大量的参数。
Do I need to create stack frames in every trivial functions like this in order to make it non-leaf safe?
没有。但是如果你需要在调用者或被调用者中保存寄存器,当然需要堆栈帧。如果您的函数调用另一个函数,则保存 $ra。
我正在编写一个 MIPS 库,我计划在其中通过 $aX
寄存器传递所有参数,并通过 $vX
寄存器传递 return 所有值。
我写了下面的函数:
# PrintFloat - prints a float
# arguments:
# $a0 = arress of the float
# return value:
# n/a
PrintFloat:
move $f12, $a0
li $v0, 2
syscall
# return
jr $ra
此函数未在 MARS 中编译。
我这里有三个问题:
- 根本不可能通过
$a
寄存器传递浮点数吗? - 我是否应该将库设计为通过
$sp
传递参数(使用$sp
比较混乱)? - 我是否需要在像这样的每个微不足道的函数中创建堆栈帧以使其成为非叶安全的?
Is it not possible to pass floats through $a registers at all?
有可能。但在 MIPS 中,由于历史原因,FP 被视为协处理器,您必须使用特定指令在处理器和协处理器之间复制移动数据:MFC
(从协处理器移动)和 MTC
(移动到协处理器). FP单元为协处理器1,对应指令为mfc1
和mtc1
.
mfc1 rt, fs # copy data from fp register fs to gp register rt
与复制到 fp 寄存器类似,使用 mtc1
mtc1 rs, ft # copy data from gp register rs to fp register ft
所以你只需要使用
mfc1 $a0, $f12
将 $f12 放入 $a0。
Should I design the library to pass the arguments through $sp instead (using $sp is comparatively messy)?
不,它没有用,除非你有大量的参数。
Do I need to create stack frames in every trivial functions like this in order to make it non-leaf safe?
没有。但是如果你需要在调用者或被调用者中保存寄存器,当然需要堆栈帧。如果您的函数调用另一个函数,则保存 $ra。