Funciones_STACKKKKKKKKKKKKKKKKKKKKKKKKK.pdf

SantiSaldaa 8 views 49 slides Sep 08, 2025
Slide 1
Slide 1 of 49
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49

About This Presentation

Tecnicas digitales II


Slide Content

Técnicas Digitales II
Dr.Ing.Steiner Guillermo
Llamado a Funciones

●Bibliografía
Harris & Harris. Digital design and computer architecture:
ARM edition. Elsevier, 2015. Capítulo 6.
–Hoja 317 a 329
●Bibliografía Complementaria
William Hohl & Christopher Hinds. ARM assembly language.
Fundamentals and techniques. 2nd edition. CRC press, 2015.
Capítulo 13.

Funciones
●Una función, es un segmento de código en general
encargado de resolver una tarea especifica.
●Se encuentra separado del bloque principal y puede ser
llamado por este, por si mismo o por otra función.
●Útil para reutilizar código y hacer el programa mas modular y
legible.
●Recibe también el nombre de procedimiento, subrutina o
subprograma .

Funciones
●Elementos de una función
●Nombre único.
●Un valor de retorno (Salida).
●Una lista de parámetros (Entradas).
●El propio código.

Funciones en ARM
●Cuando una función llama a otra:
●La función que llama se denomina caller o llamadora
●La función que es llamada se denomina callee o llamada
int main() {
int y;
...
y=diffsums(2,3,4,5);
...
}
int diffsums(int f,int g,int h,int i) {
int result;
result=(f+g)−(h+i);
return result;
}
Función llamadora
Función llamada

Funciones
●Una función no debe interferir en el comportamiento de la
función que la llama, esto significa que:
–No podrá afectar registros o zona de memoria utilizada
por el programa que llamó a la función.
–Debe saber como regresar desde donde fue llamada
Por convención una función recibe parámetros en R0-R3 y
retorna el resultado en R0.
La función ”llamada” deberá guardar y recuperar antes de
finalizar los registros R4 a R11 y el LR.
Por convención una función recibe parámetros en R0-R3 y
retorna el resultado en R0.
La función ”llamada” deberá guardar y recuperar antes de
finalizar los registros R4 a R11 y el LR.
La Instrucción BL guarda en LR la dirección de retorno
La Instrucción BL guarda en LR la dirección de retorno

Llamado de función y retorno
●ARM utiliza el BL como instrucción para el llamado a
funciones.
●BL guarda el valor de retorno en LR permitiendo a la función
una vez finalizada regresar desde donde fue llamada.
0x00008000 MAIN: ...
... ...
0x00008020 BL SIMPLE
0x00008024 MOV R1,R0
...
...
...
0x0000902C SIMPLE: MOV PC, LR
BL guarda en el
registro LR el valor
0x00008024
BL modifica el PC
con el valor
0x0000902C
MOV modifica el PC
con el contenido de
LR (0x00008024)
Función
Llamadora
Función
Llamada

Argumentos y retorno de un valor
●En ARM las funciones utilizan la siguiente convención:
●Devuelven el valor en R0
●Utilizan R0-R3 (de izquierda a derecha) para enviar los
parámetros de entrada.

int main() {
int y;
...
y=diffsums(2,3,4,5);
...
}
int diffsums(int f,int g,int h,int i) {
int result;
result=(f+g)−(h+i);
return result;
}
MAIN: ...
MOV R0, #2
MOV R1, #3
MOV R2, #4
MOV R3, #5
BL DIFFSUMS
MOV R4, R0

DIFFSUMS:ADD R8, R0, R1
ADD R9, R2, R3
SUB R4, R8, R9
MOV R0, R4
MOV PC, LR

STACK
●Una función no debe afectar ningún registro o zona de
memoria utilizada por el programa que llamó a la función.
DIFFOFSUMS:ADD R8,R0,R1
ADD R9,R2,R3
SUB R4,R8,R9
MOV R0,R4
MOV PC,LR
R0, único registro que
debe ser modificado por
contener el valor de retorno
Problema a resolver
Registros modificados
dentro de la función

STACK
●Una función no debe afectar ningún registro o zona de
memoria utilizada por el programa que llamó a la función.
DIFFOFSUMS:ADD R8,R0,R1
ADD R9,R2,R3
SUB R4,R8,R9
MOV R0,R4
MOV PC,LR
Registros modificados
dentro de la función
R0, único registro que
debe ser modificado por
contener el valor de retorno
Solución
Toda función guardará en el STACK los registros utilizados dentro de la
misma para recuperar su valor antes de retornar el programa que la
llamó.
Solución
Toda función guardará en el STACK los registros utilizados dentro de la
misma para recuperar su valor antes de retornar el programa que la
llamó.

STACK
●El STACK, es una porción de memoria que se utiliza para
guardar información temporal dentro de una función o
programa.
●Esta porción de memoria se expande cuando se requiere
guardar información y se libera en el momento que esa
información no es mas necesaria.
●Además de guardar registros, puede tener otros usos:
●Los parámetros son enviados de izquierda a derecha en los
registros R0-R3, si se requiere mayor cantidad de parámetros,
utilizaremos el STACK
●Las variables locales de una función, son en general
guardadas en el STACK, liberando ese espacio al salir de esta.
●Los parámetros son enviados de izquierda a derecha en los
registros R0-R3, si se requiere mayor cantidad de parámetros,
utilizaremos el STACK
●Las variables locales de una función, son en general
guardadas en el STACK, liberando ese espacio al salir de esta.

STACK
●El STACK es una lista ordenada del tipo last-in-first-out (LIFO),
●Como en una pila, el nuevo dato se apila sobre el anterior y
cuando se extrae un dato es el último que se agregó.
●En ARM se utiliza el registro R13 o SP para el manejo del
STACK, este registro contendrá la dirección del último dato
guardado.
●Además por cada dato agregado,
el stack se expandirá a posiciones
de memoria mas bajas.
Push Pop

STACK
●Ejemplo simple de utilización del STACK
0xF..F
0x0..0
dato x
dato1
dato2
SP o R13
SP o R13
Al entrar a una función,
se crean dos variables
locales dato1 y dato2
Dentro de la función se
utilizan las variables
Al salir de la función
Se recupera el espacio
El Stack apunta a
un valor previamente
guardado.

Uso del Stack
●Un ejemplo de como guardar R4,R8 y R9 en el stack y luego
recuperarlos:
DIFFOFSUMS:

ADD R8,R0,R1
ADD R9,R2,R3
SUB R4,R8,R9
MOV R0,R4
MOV PC,LR
Función original, para
realizar la diferencia de
sumas
(R0+R1) - (R2+R3)
Función original, para
realizar la diferencia de
sumas
(R0+R1) - (R2+R3)

Uso del Stack
●Un ejemplo de como guardar R4,R8 y R9 en el stack y luego
recuperarlos:
DIFFOFSUMS:SUB SP,SP,#12

STR R9,[SP,#8]
STR R8,[SP,#4]
STR R4,[SP]
ADD R8,R0,R1
ADD R9,R2,R3
SUB R4,R8,R9
MOV R0,R4
LDR R4,[SP]
LDR R8,[SP,#4]
LDR R9,[SP,#8]
ADD SP,SP,#12
MOV PC,LR
1) Hacer espacio
en el stack
2) Guardar los registros
3) Ejecutar la función utilizando
los registros
4) Restaurar los valores originales
de los registros desde el stack
5) Desocupar el espacio en el
stack
0xF..F
0x0..0
dato_old
R9
R8
SP
SPR4

Uso del Stack
●El espacio ocupado por una función dentro del stack se
denomina Stack Frame.
●En el ejemplo anterior el stack frame de
la función es de 3 word.
●Cada función, solo puede acceder a su
stack frame y no al de otras funciones
(Principio de modularidad)
0xF..F
0x0..0
dato_old
R9
R8
SP
OLD
SP
NEWR4

Carga y Almacenamiento de Registros
Múltiples
●Para facilitar el almacenamiento y carga de los registros al
stack, ARM provee funciones de carga y almacenamiento de
múltiples registros.
DIFFOFSUMS:STMFD SP!,{R4,R8,R9}
ADD R8,R0,R1
ADD R9,R2,R3
SUB R4,R8,R9
MOV R0,R4
LDMFD SP!,{R4,R8,R9}
MOV PC,LR
Almacenamiento
Carga
LDM y STM Instrucciones de carga y
almacenamiento de múltiples registros
Configuración
de LDM y STM

Carga y Almacenamiento de Registros
Múltiples
Las Instrucciones LDM y STM poseen la siguientes
características:
●Como cualquier instrucción de load / store, requiere de un
registro como base para acceder a la posiciones de memoria
que interactúan con los registros.
●Permite leer o escribir múltiples registros, conteniendo la
propia instrucción la lista de registros a tratar.
●Por ser posible leer o guardar varios registros, se requiere
que la propia instrucción calcule las posiciones donde se
encuentran los restantes .

Carga y Almacenamiento de Registros
Múltiples
LDM (b20=1) / STM (b20=0)
Configuración: si es LDM
o STM y modo de
funcionamiento
Registro base
Registros a leer o escribir, cada bit
representa un registro
Ejemplo:
0000 0010 0000 0010 → R1 y R9
0001 0011 0000 0000 → R8, R9 y R12

Carga y Almacenamiento de Registros
Múltiples
El modo de funcionamiento de las instrucciones LDM y STM se
define mediante:
STMFD SP!,{R4,R8,R9}
●Un sufijo, que determina de que manera se
calcula la dirección de la próxima dirección de
memoria a leer o escribir.
●Un sufijo, que determina de que manera se
calcula la dirección de la próxima dirección de
memoria a leer o escribir.
●Un signo de “!” a continuación del registro base
indica que una vez concluido la operación el
registro base se actualizará con la última
dirección de memoria calculada.
●Un signo de “!” a continuación del registro base
indica que una vez concluido la operación el
registro base se actualizará con la última
dirección de memoria calculada.

Carga y Almacenamiento de Registros
Múltiples
●Según el sufijo elegido, se obtiene los siguientes modo de
direccionamiento.
Increment After (IA)
Decrement After (DA)
Increment Before (IB)
Decrement Before (DB)
STMxx R2!,{R0,R4,R5}
Nemónico según el modo de
direccionamiento (IA,IB,DA,DB)
Indica que el
registro base se
actualizará
No importa el orden, el registro mas
bajo corresponde a la dirección mas
baja.

Carga y Almacenamiento de Registros
Múltiples
●Los modos indicados, permiten usar las instrucciones de C y A
múltiples para una diversidad de aplicaciones.
●El principal uso en ARM es el STACK, para esto se dispone de
nemónicos específicos.
●Esto es requerido por ser una pila LIFO y la manera en que se
escriben los datos difiere de la manera en que se leen.
●Ejemplo:
–si escribo de manera ascendente, el puntero queda en la
última posición escrita.
–a continuación debo leer de manera descendente

Carga y Almacenamiento de Registros
Múltiples
●Combinando entonces estos modo de direcciones, se pueden
implementar 4 tipos o modelos de stack.
●Donde:
–Full/Empty: indica si el puntero apunta al último dato guardado
(full) o al lugar vacío donde se guardará el próximo (empty).
–Ascending/Descending: Se refiere a la manera que se
GUARDAN los datos en memoria.
Nombre Nemónico
Full Ascending FA
Empty Ascending EA
Full Descending FD
Empty DescendingED

STACK Full Descending
●Para el siguiente ejemplo de STACK, tomamos el modelo
FULL DESCENDING
●Esto significa:
–Full: El registro base siempre apunta a el último dato
guardado o lo que es lo mismo el próximo dato a leer.
–Descending: Los datos se guardan en posiciones
descendentes de memoria

STACK Full Descending
Increment After (IA)
Decrement After (DA)
Increment Before (IB)
Decrement Before (DB)
STMFD R2!,{R0,R4,R5}
STMDB R2!,{R0,R4,R5}
LDMFD R2!,{R0,R4,R5}
LDMIA R2!,{R0,R4,R5}
Guardar los registros
Recuperar los registros
R2 queda con el mismo
valor luego de la secuencia
STM , LDM
R2 queda con el mismo
valor luego de la secuencia
STM , LDM
V. Inicial
V. Final

STACK Full Descending
●PUSH y POP son sinónimos para las instrucciones STM y
LDM respectivamente, configuradas en el modo Full
Descending (FD) y utilizando el SP como registro base.
–PUSH {regs} → STMFD SP!,{regs}
–POP {regs} → LDMFD SP!,{regs}
●El Full Descending queda entonces como el modelo estándar
utilizado por ARM, y es utilizado en otras arquitecturas como
modo único de manejo del STACK (ejemplo x86)

Carga y Almacenamiento de Registros
Múltiples
●Los otros tres modelos (EA, FD y ED), quedan para usos
particulares.
●Quedando la tabla de equivalencias como sigue:
Nombre Nem.STACK Nemónico Equivalente
para LDMpara STM
Full Ascending FA LDMDA STMIB
Empty AscendingEA LDMDB STMIA
Full DescendingFD LDMIA STMDB
Empty DescendingED LDMIB STMDA

Reduciendo los registros salvados
●ARM divide a los registros, en registros preservados y no
preservados.
–Preservados: R4-R11,SP y LR, una función debe guardar estos
registros antes de ser modificados y restaurado su valor antes
de salir de la función.
El código que llama a una función supone que esta no va a
modificar estos registros.
–No preservados: R0-R3, R12 pueden ser cambiados
libremente, no se puede asumir que no serán modificados
luego de llamar a una función.
DIFFOFSUMS:PUSH {R4}
ADD R1, R0, R1
ADD R3, R2, R3
SUB R4, R1, R3
MOV R0, R4
POP {R4}
MOV PC, LR
No es necesario
guardarlos o se
encarga el
llamador de
hacerlo (caller-
save)
Único registro
a ser salvado
(callee-saved)

Reduciendo los registros salvados
●Tabla con resumen de los registros Preservados y No
Preservados.
Preservados No Preservados
R4 - R11 Registro temporal R12
Stack Pointer R13 (SP)
Esta implícito en el propio uso. Al entrar
a una función los datos guardados en el
stack son descargados al salir,
recuperando su valor inicial.
Registros de Argumentos R0 - R3
Dirección de Retorno R14 (LR)
Si una función llama a otra, se deberá
guardar la dirección de retorno de la
primera.
Current Program Status Register
(CPSR)
Las Banderas no son preservadas entre
llamado de funciones
Stack sobre el SP Stack por debajo del SP

Funciones leaf y nonleaf
●Leaf: función que no llama a otra función.
●Nonleaf: función que llama a otra función
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:
@ uso de reg. r5 y r8

bl function2

mov pc,lr
function2:
@ uso de reg. r6 y r9

mov pc,lr
Se sobrescriben
LR,R5 y R6
Nonleaf
Leaf

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
SP

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main
SP
Llamar function1

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main
Llamar function1
Copiar al STACK
LR fun1
R8 (??)
R5 (main)SP

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main
R8 = val fun1
Llamar function1
Copiar al STACK
Actualiza var en fun1
LR fun1
R8 (??)
R5 (main)SP
------ fun1

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main
R8 = val fun1
Llamar function1
Copiar al STACK
Actualiza var en fun1
Llamar a fun2
LR fun1
R8 (??)
R5 (main)SP
------ fun1
X 2

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main
R8 = val fun1
Llamar function1
Copiar al STACK
Actualiza var en fun1
Llamar a fun2
Copiar al STACK
LR fun1
R8 (??)
R5 (main)
R9(??)
R6(main)
------ fun1
X 2
SP

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main
R8 = val fun1
R9 = val fun2
Llamar function1
Copiar al STACK
Actualiza var en fun1
Llamar a fun2
Copiar al STACK
Actualiza var en fun2
LR fun1
R8 (??)
R5 (main)
R9(??)
R6(main)
------ fun1
X 2
SP
------ fun2

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main fun2
R8 = val fun1
R9 = val fun2
Llamar function1
Copiar al STACK
Actualiza var en fun1
Llamar a fun2
Copiar al STACK
Actualiza var en fun2
Recuperar del STACK
LR fun1
R8 (??)
R5 (main)
R9(??)
R6(main)
SP
------ fun1
X 2
-------------------
------

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main
R8 = val fun1
Llamar function1
Copiar al STACK
Actualiza var en fun1
Llamar a fun2
Copiar al STACK
Actualiza var en fun2
Recuperar del STACK
Retorno de function2
LR fun1
R8 (??)
R5 (main)
R9(??)
R6(main)
SP
------ fun1
X 2

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1 2
R5 = val main fun1
R6 = val main
R8 = val fun1
SP
Llamar function1
Copiar al STACK
Actualiza var en fun1
Llamar a fun2
Copiar al STACK
Actualiza var en fun2
Recuperar del STACK
Retorno de function2
Recupera del STACK
LR fun1
R8 (??)
R5 (main)
R9(??)
R6(main)
------
-------------------
X

Funciones leaf y nonleaf uso del STACK
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
reset:@ uso de reg. r5 y r6

bl function1
loop:b loop
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function1:push {r5,r8,lr}
@ uso de reg. r5 y r8

bl function2

pop {r5,r8,lr}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
function2:push {r6,r9}
@ uso de reg. r6 y r9

pop {r6,r9}
mov pc,lr
0xF..F
0x0..0
LR= ret call function1
R5 = val main
R6 = val main
SP
Llamar function1
Copiar al STACK
Actualiza var en fun1
Llamar a fun2
Copiar al STACK
Actualiza var en fun2
Recuperar del STACK
Retorno de function2
Recupera del STACK
Retorno de function1
LR fun1
R8 (??)
R5 (main)
R9(??)
R6(main)

Uso del STACK
int f1(int a,int b)
{
int i,x;
x=(a+b)*(a−b);
for (i=0;i<a;i++)
x=x+f2(b+i);
return x;
}
int f2(int p) {
int r;
r=p+5;
return r+p;
}
F2:PUSH {R4}
ADD R4,R0,5
ADD R0,R4,R0
POP {R4}
MOV PC,LR
PUSH {R0,R1}
F1: PUSH {R4,R5,LR}
ADD R5,R0,R1
SUB R12,R0,R1
MUL R5,R5,R12
MOV R4,#0
FOR:CMP R4,R0
BGE RETU
ADD R0,R1,R4
BL F2
ADD R5,R5,R0
ADD R4,R4,#1
B FOR
RETU:MOV R0,R5
POP {R4,R5,LR}
MOV PC,LR
LR debe ser
guardado en
toda función
nonleaf
Registro no
preservado
guardado por la
func. caller
POP {R0,R1}

Funciones Recursivas
●Son funciones nonleaf que se llaman a si mismas
●Son ambas llamador y llamada
●Se deben guardar los registros preservados, pero también los
no preservados.
FAC:PUSH {R0,LR}
CMP R0,#1
BGT ELSE
MOV R0,#1
ADD SP,SP,#8
MOV PC,LR
ELSE:SUB R0,R0,#1
BL FAC
POP {R1,LR}
MUL R0,R1,R0
MOV PC,LR
0xF..F
0x0..0
LR
R0(3)
LR
R0(2)
LR
R0(1)
SP ini/fin →
SP max →
R0 = 6
R0 = 3x2
R0 = 2x1
R0 = 1

Funciones Recursivas Ejemplo 1 (libro)
FAC:PUSH {R0,LR}
CMP R0,#1
BGT ELSE
MOV R0,#1
ADD SP,SP,#8
MOV PC,LR
ELSE:SUB R0,R0,#1
BL FAC
POP {R1,LR}
MUL R0,R1,R0
MOV PC,LR
FAC:PUSH {R0,LR}
CMP R0,#1
BGT ELSE
MOV R0,#1
ADD SP,SP,#8
MOV PC,LR
ELSE:SUB R0,R0,#1
BL FAC
POP {R1,LR}
MUL R0,R1,R0
MOV PC,LR
FAC:PUSH {R0,LR}
CMP R0,#1
BGT ELSE
MOV R0,#1
ADD SP,SP,#8
MOV PC,LR
ELSE:SUB R0,R0,#1
BL FAC
POP {R1,LR}
MUL R0,R1,R0
MOV PC,LR
LR
R0(3)
LR
R0(3)
LR
R0(2)
LR
R0(3)
LR
R0(2)
LR
R0(1)
R0=1R0=2x1=2R0=3x2=6
●Ejemplo con el calculo de 3!
R1
R1

Funciones Recursivas Ejemplo 2
FAC:PUSH {R4,LR}
MOV R4,R0
CMP R4,#1
BGT ELSE
MOV R0,#1
B SALIR
ELSE:SUB R0,R0,#1
BL FAC
MUL R0,R4,R0
SALIR:POP {R4,LR}
MOV PC,LR
FAC:PUSH {R4,LR}
MOV R4,R0
CMP R4,#1
BGT ELSE
MOV R0,#1
B SALIR
ELSE:SUB R0,R0,#1
BL FAC
MUL R0,R4,R0
SALIR:POP {R4,LR}
MOV PC,LR
FAC:PUSH {R4,LR}
MOV R4,R0
CMP R4,#1
BGT ELSE
MOV R0,#1
B SALIR
ELSE:SUB R0,R0,#1
BL FAC
MUL R0,R4,R0
SALIR:POP {R4,LR}
MOV PC,LR
LR
R4(X)
LR
R4(X)
LR
R4(3)
LR
R4(X)
LR
R4(3)
LR
R4(2)
R0=1
R4=2
R0=2x1=2
R4=3
R0=3x2=6
●Ejemplo con el calculo de 3!

Variables Locales
function1:PUSH{R5,R6,LR}
SUB SP,#12
STR R0,[SP,#+8]
@v_a
STR R1,[SP,#+4]
@v_b
STR R2,[SP]
@v_c
BL funcion2
...
...
ADD SP,#12
POP {R5,R6,LR}
MOV PC,LR
function1:PUSH{R5,R6,LR}
SUB SP,#12
STR R0,[SP,#+8]
@v_a
STR R1,[SP,#+4]
@v_b
STR R2,[SP]
@v_c
BL funcion2
...
...
ADD SP,#12
POP {R5,R6,LR}
MOV PC,LR
Stack
Frame
Variables Locales
●Las variables locales solo son accedidas por la propia
función.
●Se utiliza el stack para
guardarlas.
●Al salir se recupera la memoria

Parámetros por stack
main:...
LDR R1,=vector1
PUSH {R1}
LDR R1,=vector2
PUSH {R1}
BL fun1
ADD SP,#8
...
main:...
LDR R1,=vector1
PUSH {R1}
LDR R1,=vector2
PUSH {R1}
BL fun1
ADD SP,#8
...
●Cuando se debe enviar mas de
4 parámetros se utiliza el STACK
fun1:PUSH {FP,LR}
ADD FP,SP,#8
...
LDR R0,[FP,#0]
LDR R1,[FP,#4]
...
POP {FP,LR}
MOV PC,LR
fun1:PUSH {FP,LR}
ADD FP,SP,#8
...
LDR R0,[FP,#0]
LDR R1,[FP,#4]
...
POP {FP,LR}
MOV PC,LR
SP
FP
Stack
Frame
Param.
Antes de llamar
a fun1
Dentro de fun1

●Bibliografía
Harris & Harris. Digital design and computer architecture:
ARM edition. Elsevier, 2015. Capítulo 6.
William Hohl & Christopher Hinds. ARM assembly language.
Fundamentals and techniques. 2nd edition. CRC press, 2015.
Capítulo 13.

¿ Preguntas ?
Tags