2016-06-08 6 views
1

Я знаю, как сделать функцию в MIPS, которая принимает 4 аргумента, потому что я знаю, что могу просто поместить аргументы в регистры $ a0- $ a3. Но предположим, что вам нужно больше 4 аргументов, как вы обходите тот факт, что в MIPS ($ a0- $ a3) есть только 4 аргументарных регистра?Функция MIPS с несколькими аргументами

ответ

0

Есть несколько способов сделать это, каждый со своими компромиссами: (1) с использованием ПМО ABI, (2), используя собственные внутренние конвенции регистра, или (3) с помощью C-как-структурой


ПМО ABI:

ПМ ABI [как и большинство других арок], при запуске из регистров аргументов, остальные аргументы помещаются в стек.

Рассмотрим следующую программу C:

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 

Автономные функции:

Если функции самостоятельно содержащихся в программе [т.е. вы не вызывая внешние функции совместимую ABI], вы можете передать аргументы практически в любой зарегистрирует вас хочу:

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-структуру:

как и в C, вы можете пройти много вещей вокруг в структурах:

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); 
} 

АОМА эквивалент C структуры заключается в использовании приравнивает смещения из базового регистра:

# 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 
+0

Спасибо, что это было очень полезно. – Struggling

Смежные вопросы