You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MIPS函数如何传入超过4个参数?含C++转MIPS实操疑问

MIPS中处理4个以上函数参数的方案及代码补全

先解答核心问题:MIPS中如何传递超过4个的函数参数?

在MIPS遵循的System V ABI标准调用约定里,函数参数的传递规则很明确:

  • 前4个参数直接用$a0到$a3这四个寄存器传递,这也是你已经完成的部分
  • 当参数数量超过4个时,剩下的参数必须从右往左依次压入栈中(这是因为C/C++采用的cdecl调用约定要求参数从右到左求值入栈)
  • 额外注意:压栈前一定要先调整栈指针$sp,预留足够的栈空间,同时要保证栈是8字节对齐的(MIPS32环境下至少4字节对齐,64位则需8字节,根据你的场景调整)

针对你的代码补全:把C++调用转成完整MIPS汇编

你的目标调用是:

funcArr2(12, a2, a3, a4, used1, used2, &used3, &used4);

前4个参数已经处理完毕,剩下的第5到8个参数依次是used1、used2、&used3、&used4。按照规则,我们需要从最右边的&used4开始,往左依次压栈。

假设你的代码里:

  • used1、used2是栈上的局部变量(或你已用寄存器保存了它们的值)
  • &used3、&used4是对应的地址(比如存在$t1、$t0寄存器里,或者是栈偏移地址)

完整的汇编代码如下(附详细注释):

# 前4个参数:你已经完成的部分
li      $a0, 12          # 第一个参数:常量12
addi    $a1, $sp, 280    # 第二个参数:a2的地址
addi    $a2, $sp, 328    # 第三个参数:a3的地址
addi    $a3, $sp, 376    # 第四个参数:a4的地址

# 步骤1:预留栈空间存储剩余4个参数(每个参数4字节,共16字节;同时保证栈对齐)
addi    $sp, $sp, -16

# 步骤2:从右往左压入剩余参数
# 第8个参数:&used4 → 存在栈的最高偏移位置(12($sp))
# 若&used4是栈上变量,可替换为 addi $t0, $sp, xxx(注意此时$sp已减16,偏移需调整)
sw      $t0, 12($sp)

# 第7个参数:&used3 → 偏移8($sp)
sw      $t1, 8($sp)

# 第6个参数:used2的值 → 偏移4($sp)
# 若used2是栈变量,需先通过 lw $t2, offset($sp) 取出值再压栈
sw      $t2, 4($sp)

# 第5个参数:used1的值 → 偏移0($sp)
sw      $t3, 0($sp)

# 调用目标函数
jal     funcArr2

# 步骤3:调用完成后恢复栈指针(cdecl约定由调用者清理栈)
addi    $sp, $sp, 16

几个关键注意点:

  • 压栈顺序绝对不能错:必须从最右边的参数开始往左压,否则函数内部取栈上参数时会拿到错误的值
  • 栈对齐:如果你的栈原本不是8字节对齐,调整$sp时要多减几个字节(比如减20而非16)来保证对齐,避免运行异常
  • 参数类型区分:如果是指针(比如&used3),压栈的是地址;如果是普通变量(比如used1),压栈的是变量的值,别搞混

内容的提问来源于stack exchange,提问作者gotj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:36:49