I know how to make a function in MIPS that takes in 4 arguments because I know I can just put the arguments into the registers $a0-$a3. But suppose you want more than 4 arguments, how do you get around the fact that there is only 4 argument registers in MIPS ($a0-$a3)?
            Asked
            
        
        
            Active
            
        
            Viewed 7,224 times
        
    1 Answers
4
            
            
        There are a few different ways to do this, each with its own tradeoffs: (1) using the mips ABI, (2) using your own internal register conventions, or (3) using a C-like struct
The mips ABI:
The mips ABI [like most other arches], when you run out of argument registers, the remaining arguments are pushed onto the stack.
Consider the following C program:
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);
}
The mips ABI equivalent would look like:
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
Self contained functions:
If your functions are self contained within the program [i.e. you aren't calling external ABI conformant functions], you can pass arguments in just about any register you wish:
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
Using a C struct:
Like in C, you can pass many things around in a struct:
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);
}
The asm equivalent of a C struct is to use equates to offsets from a base register:
# offsets within "struct"
a = 0
b = 4
c = 8
d = 12
e = 16
f = 20
caller:
    la      $a0,args
    li      $t0,1
    sw      $t0,a($a0)
    li      $t0,2
    sw      $t0,b($a0)
    li      $t0,3
    sw      $t0,c($a0)
    li      $t0,4
    sw      $t0,d($a0)
    li      $t0,5
    sw      $t0,e($a0)
    li      $t0,3
    sw      $t0,f($a0)
    jal     callee
    jr      $ra
callee:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)
    lw      $t0,a($a0)              # get a
    lw      $t1,b($a0)              # get b
    lw      $t2,c($a0)              # get c
    lw      $t3,d($a0)              # get d
    lw      $t4,e($a0)              # get e
    lw      $t5,f($a0)              # get f
    # ...
    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra
        Craig Estey
        
- 30,627
 - 4
 - 24
 - 48
 
- 
                    Thank you this was very helpful. – Struggling Jun 09 '16 at 20:09
 - 
                    Is addiu with -8 possible? – Gertjan Brouwer Jan 08 '21 at 23:18
 - 
                    @GertjanBrouwer I think _this_ answer of mine may be what you're looking for: https://stackoverflow.com/questions/40090168/andi-vs-addi-instruction-in-mips-with-negative-immediate-constant/40118189#40118189 – Craig Estey Jan 08 '21 at 23:27