Manejo de la memoria en tiempo de ejecución.

Anuncio
Tiempo de Compilación
Tiempo de Ejecución
Programa
fuente
Datos de
entrada
Secuencia
de caracteres
Máquina abstracta
Compilador
Secuencia
de símbolos
Datos de
entrada
Parser
Analizador
semántico
Máquina real
Datos de
entrada
Código
Programa
objeto
Datos de
salida
Descripción del comportamiento de un programa
dependiente de máquina (implementación)
Programa
objeto
Compiladores ( 04/11/2003 08:24)
Datos de
salida
Descripción del comportamiento de un programa
independiente de máquina pero fácil de implementar
(implementación interpretada)
Tabla de
símbolos
Generador
de código
- 6.1 -
Programa
objeto
Árbol
sintáctico
Árbol sintáctico
con atributos
Compiladores ( 04/11/2003 08:24)
Datos de
salida
Descripción abstracta del comportamiento de un programa
Scanner
ORGANIZACIÓN DE LA MEMORIA EN
TIEMPO DE EJECUCIÓN
Programa
fuente
- 6.2 -
Compiladores ( 04/11/2003 08:24)
- 6.3 -
1
Máquinas Abstractas y Paradigmas de
Programación
Máquina Abstracta
• Con una máquina abstracta se define el
ámbito de ejecución de los programas
La arquitectura de la máquina abstracta
depende de la forma de ejecución.
– Recursos necesarios para ejecutar un
programa
–
–
–
–
Segmento de código
Segmento de datos estático
Pila
Heap (memoria dinámica)
• Registros del procesador
–
–
–
–
Contador del programa
Apuntador a la pila
Acumulador
Etc.
–
–
–
–
Control de flujo
Operaciones aritméticas
Comparaciones
Guardar y recuperar datos de memoria
Etc.
Compiladores ( 04/11/2003 08:24)
Segmento de código
Segmento de datos
Pila
Heap
Pila
bloques de memoria
direccionados por
apuntadores
Segmento de código
Pila de argumentos
Pila de contexto
Heap
variables globales
y estáticas
código máquina,
constantes y
literales (solo lectura)
• Lenguajes lógicos
–
–
–
–
- 6.4 -
B
SP
Libre
• Lenguajes funcionales
• Instrucción del código máquina
–
–
–
–
–
variables locales y
resultados intermedios
• Lenguajes imperativos
• Organización de la memoria
–
–
–
–
Organización de Memoria de un Programa
Imperativo
Heap
Segmento de
datos estáticos
Segmento
de código
PC
Segmento de código
Pila de backtracking
Trail
Pila para la unificación
Compiladores ( 04/11/2003 08:24)
- 6.5 -
Compiladores ( 04/11/2003 08:24)
- 6.6 -
2
Asignación estática de memoria
Direcciones Simbólicas y Linkado
• Las variables cuyo tiempo de vida es todo
el programa se guardan en el segmento de
datos estático
–
–
–
–
variables globales
variables static
campos static de clases
etc.
• El acceso se realiza por dirección absoluta
de memoria.
• La asignación de direcciones se puede
realizar mediante un apuntador a la base
del segmento que se incrementa con el
tamaño de cada variable
• Problema:
en la compilación
separada no se conoce
el tamaño de los
segmentos
Fin
• Un fichero objeto es una secuencia de
trozos de segmento con
–
–
–
–
• Los datos compuestos son
–
–
–
–
una o más direcciones simbólicas
un tamaño
un tipo de segmento: código, datos, etc.
opcionalmente un contenido
struct
union
array
conjunto
• Para acceder a su contenido se necesita
• Una librería es un conjunto de ficheros
objeto
• El linkeador se encarga de
– Dirección base de la variable
– Desplazamiento para acceder a una de sus
componentes
– juntar todos los trozos de segmento de los
ficheros objeto incluyendo los que sean
necesarios de las librerías
– Transformar las direcciones simbólicas en
direcciones absolutas de memoria
• Ejemplo:
struct {
int a;
double b;
char c;
} v;
&v.c
&v.b
var3
var2
Base
Compiladores ( 04/11/2003 08:24)
Datos Compuestos
&v.a
var1
- 6.7 -
Compiladores ( 04/11/2003 08:24)
- 6.8 -
Compiladores ( 04/11/2003 08:24)
&v+12:
&v+11:
&v+10:
&v+9:
&v+8:
&v+7:
&v+6:
&v+5:
&v+4:
&v+3:
&v+2:
&v+1:
&v+0:
c
b
a
- 6.9 -
3
Struct y Union
Struct y Union
• Datos compuestos con desplazamiento
conocido en tiempo de compilación
• union (superposición de campos)
• struct (sin superposición de campos)
struct {
tipo1 c1;
tipo2 c2;
...
tipon cn;
} var;
c1,c2,...,cn
&var. c1=&var+sizeof(tipo1)+
sizeof(tipo2)+...+ sizeof(tipon-1)
&var. c2=&var+sizeof(tipo1)
• Alinear un dato supone que su dirección
base ha de ser un múltiplo de una cierta
potencia de 2.
• Los datos se alinean para acelerar su
acceso o por limitaciones de
direccionamiento del procesador.
• Ejemplo
union {
tipo1 c1;
tipo2 c2;
...
tipon cn;
} var;
– struct y union de C
– record de PASCAL
cn
Alineación
sizeof(tipon)
c2
sizeof(tipo2)
c1
sizeof(tipo1)
&var. c1= &var. c2 =
...= &var. cn
max {sizeof(tipo1),
sizeof(tipo2),...,
sizeof(tipon)
}
&v.c
&v.b
&var. c1=&var+0
Compiladores ( 04/11/2003 08:24)
struct {
char a;
int b;
int c;
} v;
&v.a
- 6.10 -
Compiladores ( 04/11/2003 08:24)
- 6.11 -
Compiladores ( 04/11/2003 08:24)
&v+11:
&v+10:
&v+9:
&v+8:
&v+7:
&v+6:
&v+5:
&v+4:
&v+3:
&v+2:
&v+1:
&v+0:
c
b
Espacio
ocupado
en un array
a
- 6.12 -
4
Arrays
⎛a
⎜ 1,1
⎜ a2 ,1
⎜
⎝ a3,1
a1,2
a2 ,2
a1,3
a2 , 3
a 3, 2
a 3, 3
Conjuntos
a1,4 ⎞
⎟
a2 ,4 ⎟
a3,4 ⎠⎟
• Conjunto de escalares
– Memoria: a , a , a , a , a , a , a
– Cálculo del desplazamiento
1, 2
1, 3
1, 4
2 ,1
• a: conjunto de (rojo, azul, verde)
• 3 bits (rojo bit 0, azul bit 1, verde bit 2)
2 ,2
2 ,3
, a2 , 4 , a3,1 , a3, 2 , a3, 3 , a3, 4
n
n
j =1
l = j +1
desp (i1 , i2 ,..., in ) = sizeof (elementos) ∑ (i j − min j ) ∏ ( maxl − minl + 1)
• Guardada por columnas (primero varían
los índices de la izquierda)
– Memoria: a , a , a , a , a , a , a
– Cálculo del desplazamiento
1,1
2 ,1
3,1
1, 2
2 ,2
• Para la ejecución de un programa
imperativo se necesita una pila porque se
realiza un "recorrido" por su árbol
sintáctico
• En la pila se guarda
– se utiliza un bit por elemento que puede
contener el conjunto. Ejemplo
• Guardada por filas (primero varían los
índices de la derecha)
1,1
Asignación de la Pila
3, 2
1, 3
, a2 , 3 , a3, 3 , a1, 4 , a2 , 4 , a3, 4
n
j −1
j =1
l =1
desp(i1 , i2 ,..., in ) = sizeof ( elementos) ∑ (i j − min j )∏ ( maxl − minl + 1)
– Las operaciones entre conjuntos son
– Resultados intermedios de la evaluación de
expresiones
– Bloques de activación de funciones
• union -> or de bits
• intersección -> and de bits
– El bit que representa la presencia o
ausencia de un elemento se calcula
•
•
•
•
• desp(i)=i / 8 (división entera)
• bit(i)=i % 8 (i modulo 8)
– En el análisis semántico hay que tratar
como caso especial el conjunto vacío
variables locales
enlaces estático, dinámico, display
posición de retorno
valor de retorno
– Bloques de activación de excepciones
– Bloques de salto no local
• Complejidad para n dimensiones
– -n 1sumas
– n multiplicaciones
Compiladores ( 04/11/2003 08:24)
- 6.13 -
Compiladores ( 04/11/2003 08:24)
- 6.14 -
Compiladores ( 04/11/2003 08:24)
- 6.15 -
5
Evaluación de Expresiones (I)
Evaluación de Expresiones (II)
• Una expresión se puede representar como
un árbol donde
– Las operaciones son nodos internos del
árbol, y cada una de ellas tiene por hijos
sus operandos
– Los literales son las hojas del árbol
– Ejemplo: a*b+c*d
- e
Evaluación de Expresiones (III)
• Organización de memoria
• El recorrido del árbol en postorden se
transforma en código de la siguiente forma
– Una pila que crece hacia las direcciones
inferiores de memoria
– SP es el apuntador a la cabeza de la pila
– Los operandos se ponen en la pila
– Las operaciones cogen los operandos de la
pila y dejan el resultado en esta
• Instrucciones
– Poner en la pila un literal
• Ejemplo: a*b+c*d-e
• PushLit número
– Postorden a b * c d * + e– Código
--SP;
*SP= número;
+
PushGVar &a
PushGVar &b
OperBin *
PushGVar &c
PushGVar &d
OperBin *
OperBin +
PushGVar &e
OperBin -
– Poner en la pila una variable global
e
• PushGVar dirección
*
a
*
b
c
--SP;
*SP= *dirección;
d
– Operaciones binarias
• La expresión se evalúa mediante un
recorrido en postorden del árbol
• OperBin operación
*(SP+1)=*(SP+1) operación *SP;
++SP;
a b * c d * + e-
– Operaciones unarias
• OperUna operación
*SP= operación (*SP);
Compiladores ( 04/11/2003 08:24)
- 6.16 -
Compiladores ( 04/11/2003 08:24)
- 6.17 -
Compiladores ( 04/11/2003 08:24)
- 6.18 -
6
Bloque/Registro de Activación de una
Función (I)
Bloque/Registro de Activación de una
Función (II)
• Las funciones cumplen que la última que
ha empezado ha ejecutarse es la primera en
acabar su ejecución. Por lo tanto, la
información necesaria para ejecutar las
funciones se puede guardar en una pila
• Cuando se llama a una función se necesita
crear el espacio para la siguiente
información
– Posición de retorno, o sea donde ha de
continuar la ejecución al salir de la función
– Argumentos de la función
– Valor de retorno
– Variables de la función
– Base del bloque de activación, o sea
dirección a partir de la cual se guardan los
datos necesarios para la ejecución de la
función.
Bloque de Activación de una Función C
• Los argumentos van en orden inverso para
poder implementar las funciones con
número de argumentos variable (printf)
• Para acelerar las llamadas, el valor de
retorno va en un registro del procesador.
Valor de retorno
Argumentos
PC de retorno
Enlace dinámico
B
Argumenton
Argumenton-1
....
Argumento2
Argumento1
Variables locales
SP
PC de retorno
• El registro de activación de un
procedimiento no contiene el valor de
retorno.
Enlace dinámico
B
Variables locales
SP
Compiladores ( 04/11/2003 08:24)
- 6.19 -
Compiladores ( 04/11/2003 08:24)
- 6.20 -
Compiladores ( 04/11/2003 08:24)
- 6.21 -
7
Instrucciones para Llamar a Funciones
Bloque de Activación de una Función
PASCAL
Código para Llamar una Función C
– Llamar a una dirección de memoria
• Call dirección
--SP; *SP=PC+1;
PC=dirección;
– Retornar de función
• Ret
PC=*SP; ++SP;
– Crear enlace dinámico y reservar espacio
para las variables locales
• Link tamaño
--SP; *SP=B; B=SP;
SP=SP - tamaño;
– Eliminar el espacio de las variables locales
y recuperar B
• Unlink
SP=B + 1; B=*B;
– Eliminar los Argumentos
• Add SP tamaño
SP=SP + tamaño;
Código que llama a la función
Código de la Función
Calculo del Argumenton
Calculo del Argumenton-1
...
Calculo del Argumento2
Calculo del Argumento1
Call &Fun
Add SP tamaño argumentos
Push VR
Link tamaño variables
• El enlace estático o el display se utiliza
para poder acceder a las variables locales
de otras funciones
Código del cuerpo de
la función
Valor de retorno
Pop RV
Unlink
Ret
Argumento1
Argumento2
....
Argumenton-1
Argumenton
• El código que realiza la llamada no
necesita saber el espacio ocupado por las
variables locales de la función.
• Al final de la llamada a una función queda
en la pila su valor de retorno.
Enlace estático
o display
PC de retorno
Enlace dinámico
B
– Registro del Valor de Retorno VR
• Push RV
Variables locales
--SP;*SP=RV;
• Pop RV
SP
RV=*SP; ++SP;
Compiladores ( 04/11/2003 08:24)
- 6.22 -
Compiladores ( 04/11/2003 08:24)
- 6.23 -
Compiladores ( 04/11/2003 08:24)
- 6.24 -
8
Funciones/Procedimientos Anidados en
PASCAL
nivel 0
Procedure P1;
Var V1:integer;
nivel 1
Procedure P2;
Var V2:integer;
Nivel 2
Procedure P3
Var V3:integer; Nivel 3
Begin
End;
Begin
End;
Procedure P4;
Var V4:integer;
Nivel 2
Begin
End;
Begin
End;
Procedure P5
Var V5:integer;
Nivel 1
Begin
End;
Código para Llamar una Función
PASCAL
Enlace Estático
Código que llama a la función
Código de la Función
Add SP -tamaño valor de retorno
Calculo del Argumento1
Calculo del Argumento2
...
Calculo del Argumenton-1
Calculo del Argumenton
Cálculo del EE/Display
Call &Fun
Add SP tamaño argumentos+
tamaño EE/Display
Link tamaño variables
Código del cuerpo de
la función
Unlink
Ret
• El código que realiza la llamada no
necesita saber el espacio ocupado por las
variables locales de la función.
• Al final de la llamada a una función queda
en la pila su valor de retorno.
• El enlace estático de un bloque de
activación de una función apunta al bloque
de activación de la función donde se ha
definido.
• El enlace dinámico apunta al bloque de
activación de la función que ha llamado
Procedure P1;
Var V1:integer;
Procedure P2;
Var V2:integer;
Begin
End;
Procedure P4;
Var V4:integer;
Begin
End;
Begin
End;
P1
ED PC EE
P4
ED PC EE
P2
ED PC EE
P1
ED PC EE
Secuencia de llamadas
P1->P4->P2->P1
Compiladores ( 04/11/2003 08:24)
- 6.25 -
Compiladores ( 04/11/2003 08:24)
- 6.26 -
Compiladores ( 04/11/2003 08:24)
- 6.27 -
9
Instrucciones para el Bloque de Activación
con Enlace Estático
– Crear enlace estático/display
Cálculo del Enlace Estático
Display
• El enlace estático se calcula a partir de
diferencias de nivel
• Enlace estático de un nuevo bloque de
activación
• PushEE nivel
ee=B;
for (i= nivel;i>0; --i) ee=ee->ee;
--SP; *SP=ee;
– Acceder a variable local por enlace estático
• PushEEVar nivel,desp
ee=B;
for (i= nivel;i>0; --i) ee=ee->ee;
--SP; *SP=*(ee+ desp);
• PopEEVar nivel,desp
ee=B;
for (i= nivel;i>0; --i) ee=ee->ee;
*(ee+ desp)=*SP; ++SP;
• El display es la agrupación de la lista de
enlaces estáticos en un array
DifNivel= nivel llamada - nivel función+1
EE=B
for i=1 to DifNivel do EE=EE
- >EE;
• Enlace estático de una variable
DifNivel= nivel variable - nivel código
EE=B
for i=1 to DifNivel do EE=EE
- >EE;
ED PC EE
ED PC
ED PC EE
ED PC
ED PC EE
ED PC
ED PC EE
ED PC
ED PC EE
ED PC
Enlaces estáticos
Compiladores ( 04/11/2003 08:24)
- 6.28 -
Compiladores ( 04/11/2003 08:24)
- 6.29 -
Compiladores ( 04/11/2003 08:24)
Display
- 6.30 -
10
Instrucciones para el Bloque de Activación
con Display
Creación del Display
Acceder a una Variable por Display
• El display de un nuevo bloque de
activación se crea por copia del anterior
modificado
– Crear display
• Push B
--SP; *SP=B;
• Puntero del display de una variable
DifNivel= nivel variable - nivel código
– DifNivel==0
DifNivel= nivel llamada - nivel función+1
– Acceder a variable local por display
B+desp
Valor de retorno
• PushDispVar nivel,desp
--SP; *SP=*(B[nivel]+ desp);
• PopDispVar nivel,desp
*(B[nivel]+ desp)=*SP; ++SP;
• PushBVar desp
--SP; *SP=*(B+ desp);
• PopBVar desp
*(B+ desp)=*SP; ++SP;
DifNivel==0
•Copiar display
•Añadir B
– DifNivel>0
Argumentos
B[DifNivel+1]+desp
display anterior
B
PC de retorno
ED
Valor de retorno
Argumentos
B
...
Variables locales
DifNivel>0
Copiar display menos
los últimos DifNivel
apuntadores
display anterior
DifNivel
EE3
EE2
EE1
PC de retorno
ED
Valor de retorno
Argumentos
display nuevo
B+4
B+3
B+2
B+1
B
Variables locales
PC de retorno
ED
B
Variables locales
Compiladores ( 04/11/2003 08:24)
- 6.31 -
Compiladores ( 04/11/2003 08:24)
- 6.32 -
Compiladores ( 04/11/2003 08:24)
- 6.33 -
11
Descargar