Upload
charlyevil
View
1
Download
0
Embed Size (px)
DESCRIPTION
LLamadas a rubrutina MIPS 32
Citation preview
0
Convenio de llamada a subrutina
Katia Leal Algara Septiembre 2012
[email protected] http://gsyc.escet.urjc.es/~katia/
Departamento de Sistemas Telemticos y Computacin (GSyC)
GSyC 2012 - Convenio llamada a procedimiento
GSyC 2012 - Convenio llamada a procedimiento 1
!q Las subrutinas son el equivalente que ofrecen las
instrucciones mquina a los procedimientos y funciones de los lenguajes de alto nivel!
q En C, una funcin proporciona varias abstracciones:!q Mapeo de parmetros actuales a parmetros
formales!q Alojamiento e inicializacin del almacenamiento
local temporal. Esto es importante en lenguajes que permiten recursin: cada llamada a la misma funcin debe obtener su propia copia de cualquier variable local para evitar que los datos se sobrescriban entre las distintas llamadas!
Subrutinas
Concepto de procedimiento o funcin
GSyC 2012 - Convenio llamada a procedimiento 2
!q El contexto de una funcin es toda aquella
informacin que describe el estado de una funcin durante su ejecucin:!q parmetros actuales!q valor de las variables locales!q instruccin que est siendo ejecutada!
q Para un programa en lenguaje ensamblador MIPS, el contexto de una funcin consiste en los valores de todos los registros a los que se hace referencia desde la funcin!
q La mayora de las arquitecturas, incluida la de MIPS, utiliza la pila como medio para salvar y restaurar el contexto de una subrutina!
Subrutinas
Contexto de una funcin
GSyC 2012 - Convenio llamada a procedimiento 3
Subrutinas
Invocacin
fact:
jr $ra
jal fact
jal fact
GSyC 2012 - Convenio llamada a procedimiento 4
!qjal target!qSalto incondicional a la instruccin objetivo!qAlmacenamiento de la direccin de la siguiente
instruccin en el registro $ra 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!
Subrutinas
Instrucciones para la llamada y el retorno de subrutina
GSyC 2012 - Convenio llamada a procedimiento 5
!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
Pasos llamada a subrutina (1)
GSyC 2012 - Convenio llamada a procedimiento 6
!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
Pasos llamada a subrutina (2)
GSyC 2012 - Convenio llamada a procedimiento 7
!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
Pasos llamada a subrutina (3)
GSyC 2012 - Convenio llamada a procedimiento 8
!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
Convenio
Pasos llamada a subrutina (4)
GSyC 2012 - Convenio llamada a procedimiento 9
!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!qLugar donde se van a pasar los parmetros:!
q Registros ($a0-$a3)!q Pila!
qEl ensamblador del MIPS establece el siguiente convenio para realizar el paso de parmetros:!
q Los 4 primeros parmetros de entrada se pasarn a travs de los registros ($a0-$a3). A partir del quinto parmetro se pasar a travs de la pila!
q Los valores de retorno se devuelve en los registros $v0 y $v1, el resto a travs de la pila!
Parmetros por valor Vs parmetros por referencia
Paso de parmetros
GSyC 2012 - Convenio llamada a procedimiento 10
!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 caller-saved ($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!
Convenio almacenamiento en pila
Convenio para salvar registros en la pila
GSyC 2012 - Convenio llamada a procedimiento 11
Ejemplo: clculo del factorial del nmero 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)); }
GSyC 2012 - Convenio llamada a procedimiento 12
Ejemplo: clculo del factorial del nmero 10
Factorial en ensamblador (main) ## Arquitectura de Computadores curso 2012-2013 ## fact.asm -- A program to compute the factorial of 10 ## main-- ## Registers used: ## $a0 - syscall parameter -- the number to print ## $v0 - syscall parameter and return value
.data msg: .asciiz "The factorial of 10 is: "
.text
main: subu $sp, $sp, 32 # Stack frame is 32 bytes long sw $ra, 20($sp) # Save return address sw $fp, 16($sp) # Save old frame pointer addiu $fp, $sp, 28 # Set up frame pointer la $a0, msg li $v0, 4 # Load syscall print-string into $v0 syscall # Make the syscall li $a0,10 # Put argument (10) in $a0 jal fact # Call factorial function move $a0, $v0 # Move fact result in $a0 li $v0, 1 # Load syscall print-int into $v0 syscall # Make the syscall li $v0, 10 # Load syscall exit into $v0 syscall # Make the syscall
GSyC 2012 - Convenio llamada a procedimiento 13
Ejemplo: clculo del factorial del nmero 10
Factorial en ensamblador (fact) ## fact ## Registers used: ## $a0 - initially 10
.text fact:
subu $sp, $sp, 32 # Stack frame is 32 bytes long sw $ra, 20($sp) # Save return address sw $fp, 16($sp) # Save frame pointer addiu $fp, $sp, 28 # Set up frame pointer sw $a0, 0($fp) # Save argument (n) lw $v0, 0($fp)
bgtz $v0, fact_recurse # fact(n-1) li $v0, 1 b return fact_recurse:
lw $v1, 0($fp) # Load n subu $v0, $v1, 1 # Compute n - 1 move $a0, $v0 # Move value to $a0 jal fact lw $v1, 0($fp) # Load n mul $v0, $v0, $v1 # Compute fact(n-1) * n return:
lw $ra, 20($sp) lw $fp, 16($sp) addiu $sp, $sp, 32 jr $ra