Documentos de Académico
Documentos de Profesional
Documentos de Cultura
(GSyC)
Convenio de llamada a
subrutina
Katia Leal Algara
Septiembre 2012
katia@gsyc.es
http://gsyc.escet.urjc.es/~katia/
GSyC 2012 - Convenio llamada a
procedimiento
Subrutinas
Subrutinas
Subrutinas
Invocacin
fact:
jal fact
jr $ra
jal fact
Subrutinas
!
qjal target!
qjr rs !
qSalto incondicional a la instruccin cuya
direccin est en el registro rs!
qEn caso de retorno de subrutina debemos
indicar el registro $ra!
Convenio
!
1. El caller debe:!
a) Poner los argumentos en los registros
$a0-$a3. Si hay ms de 4 parmetros,
se deben pasar por la pila!
b) Salvar los registros caller-saved ($a0$a3 y $t0-$t9) que sean utilizados por
el caller!
c) Ejecutar la instruccin jal, la cual salta
a la primera instruccin de la subrutina y
almacena la direccin de retorno en el
registro $ra
Convenio
!
2. El callee debe:!
a) Crear un marco de pila, restando el
tamao del marco del puntero de pila
($sp). El tamao mnimo del marco de
pila es de 32 bytes!
b) Salvar los registros callee-saved ($s0$s7, $fp, $ra) que sean utilizados
por el callee!
c) Establecer el valor del puntero de marco
de pila sumando al puntero de pila el
tamao del marco de pila menos 4
Convenio
!
3. El callee ejecuta el cuerpo de la funcin.
Para retornar de la funcin, el calle debe:!
a) Meter el valor de retorno en el registro
$v0!
b) Restaurar los registros callee-saved
($s0-$s7, $fp, $ra) !
c) Eliminar el marco de pila aadiendo el
tamao del marco al puntero de pila!
d) Retornar saltando con jr a la direccin
indicada en el registro $ra
Convenio
!
4. Para restablecer el estado anterior a la
llamada a la subrutina, el caller debe:!
a) Restaurar los registros caller-saved !
b) Si se pas algn argumento por la pila,
sacarlo!
c) Extraer el valor de retorno del registro
$v0
Paso de parmetros
!
qTipo de parmetros:!
q Por valor: se pasa el valor del parmetro!
q Por referencia: se pasa la direccin de memoria
donde est almacenado el parmetro!
!
qPrimero almacenaremos el registro $fp,
seguido del registro $ra(si es que es
neceasrio) despus, cualquiera de los
registros callee-saved ($s0-$s7) y
finalmente, cualesquiera registros callersaved ($t0-$t9) !
qEl puntero de pila debe almacenar una
direccin doubleword aligned. Es decir, la
direccin de memoria tiene que ser divisible
por 8 (64 bits, 8 bytes) y, por lo tanto, dicha
direccin debe terminar en 000!
10
Factorial en C
main ()
{
printf ("The factorial of 10 is %d\n", fact (10));
}
int fact (int n)
{
if (n < 1)
return (1);
else
return (n * fact (n - 1));
}
11
msg:
.data
.asciiz "The factorial of 10 is: "
.text
main:
subu $sp, $sp, 32
sw $ra, 20($sp)
sw $fp, 16($sp)
addiu $fp, $sp, 28
#
#
#
#
la $a0, msg
li $v0, 4
syscall
li $a0,10
jal fact
li $v0, 10
syscall
12
#
#
#
#
#
lw $v0, 0($fp)
bgtz $v0, fact_recurse # fact(n-1)
li
$v0, 1
b return
fact_recurse:
lw $v1, 0($fp)
subu $v0, $v1, 1
move $a0, $v0
jal fact
lw $v1, 0($fp)
mul $v0, $v0, $v1
# Load n
# Compute n - 1
# Move value to $a0
# Load n
# Compute fact(n-1) * n
return:
lw $ra, 20($sp)
lw $fp, 16($sp)
addiu $sp, $sp, 32
jr $ra
13