我知道如何在MIPS中创建一个接收4个参数的函数,因为我知道我可以将参数放入寄存器$ a0- $ a3。但是假设你想要超过4个参数,你如何解决MIPS中只有4个参数寄存器的事实($ a0- $ a3)?
答案 0 :(得分:0)
有几种不同的方法可以做到这一点,每种方法都有自己的权衡:(1)使用mip ABI,(2)使用自己的内部寄存器约定,或(3)使用类似C的结构
mips ABI:
mips ABI [和大多数其他拱门一样],当你用完参数寄存器时,剩下的参数被压入堆栈。
考虑以下C程序:
params.map ( p => FutureWhichWontStartUnlessAskedWhichWrapsOtherFuture { dbQuery(p) }).findFirst(!_.isEmpty())
等效的mip ABI看起来像:
void
callee(int a,int b,int c,int d,int e,int f)
{
}
void
caller(void)
{
int a;
int b;
int c;
int d;
int e;
int f;
callee(a,b,c,d,e,f);
}
自包含功能:
如果您的功能是自包含在程序中的[即你没有调用外部ABI符合函数],你可以在你希望的任何寄存器中传递参数:
caller:
addiu $sp,$sp,-8 # space for e,f
lw $t0,f
sw $t0,4($sp)
lw $t0,e
sw $t0,0($sp)
lw $a3,d
lw $a2,c
lw $a1,b
lw $a0,a
jal callee
addiu $sp,$sp,8 # remove space for e,f
jr $ra
callee:
addiu $sp,$sp,-4
sw $ra,0($sp)
move $t0,$a0 # get a
move $t1,$a1 # get b
move $t2,$a2 # get c
move $t3,$a3 # get d
lw $t4,4($sp) # get e
lw $t5,8($sp) # get f
# ...
lw $ra,0($sp)
addiu $sp,$sp,4
jr $ra
使用C结构:
就像在C中一样,你可以在结构中传递很多东西:
caller:
lw $s7,f
lw $s6,e
lw $a3,d
lw $a2,c
lw $a1,b
lw $a0,a
jal callee
jr $ra
callee:
addiu $sp,$sp,-4
sw $ra,0($sp)
move $t0,$a0 # get a
move $t1,$a1 # get b
move $t2,$a2 # get c
move $t3,$a3 # get d
move $t4,$s6 # get e
move $t5,$s7 # get f
# ...
lw $ra,0($sp)
addiu $sp,$sp,4
jr $ra
C结构的asm等价物用于等同于基址寄存器的偏移量:
struct args {
int a;
int b;
int c;
int d;
int e;
int f;
};
void
callee(struct args *av)
{
int tmp;
tmp = av->a;
tmp = av->b;
tmp = av->c;
tmp = av->d;
tmp = av->e;
tmp = av->f;
}
void
caller(void)
{
struct args args;
args.a = 1;
args.b = 2;
args.c = 3;
args.d = 4;
args.e = 5;
args.f = 6;
callee(&args);
}