Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Bibliografía:
[BRY11] Cap.3 Computer Systems: A Programmer’s Perspective. Bryant, O’Hallaron. Pearson, 2011
Signatura ESIIT/C.1 BRY com
Bibliografía:
[BRY11] Cap.3 Computer Systems: A Programmer’s Perspective. Bryant, O’Hallaron. Pearson, 2011
Signatura ESIIT/C.1 BRY com
1
14/10/2011
long switch_eg
(long x, long y, long z) Ejemplo de sentencia
{
long w = 1; switch
switch(x) {
case 1:
w = y*z; Etiquetas de caso múltiples
break; Aquí: 5 & 6
case 2:
w = y/z; Caídas en cascada*
/* Fall Through */ Aquí: 2
case 3:
w += z; Casos ausentes*
break; Aquí: 4
case 5:
case 6:
w -= z;
break;
default:
w = 2;
}
return w;
}
* “fall through cases”, “missing cases”, en inglés 4
2
14/10/2011
•
Traducción Aproximada •
target = JTab[x]; * •
g
goto *target;
g
Targn-1: Code Block
n–1
* “jump table”, “jump targets”, en inglés 5
3
14/10/2011
4
14/10/2011
Tabla de Saltos
Tabla de saltos
switch(x) {
.section .rodata case 1: // .L3
.align 4 w = y*z;
.L7:
break;
.long .L2 # x = 0
.long .L3 # x = 1 case 2: // .L4
.long .L4 # x = 2 w = y/z;
.long .L5 # x = 3 /* Fall Through */
.long .L2 # x = 4 case 3: // .L5
.long .L6 # x = 5 w += z;
.long .L6 # x = 6 break;
case 5:
case 6: // .L6
w -= z;
break;
default: // .L2
w = 2;
}
10
5
14/10/2011
11
12
6
14/10/2011
Características notables
La tabla de saltos ahorra secuenciar a través de los casos
Tiempo constante, en vez de lineal
Usar la tabla de saltos para gestionar huecos y etiquetas múltiples*
Usar secuenciación del programa para gestionar caída en cascada
No inicializar w = 1 a menos de que realmente se necesite
* ver pág.4 13
14
7
14/10/2011
15
16
8
14/10/2011
Dirección Valor x
0x8048660 0x8048422 0
0x8048664 0x8048432 1
0x8048668 0x804843b 2
0x804866c 0x8048429 3
0x8048670 0x8048422 4
0x8048674 0x804844b 5
0x8048678 0x804844b 6
17
Destinos desensamblados
8048422: b8 02 00 00 00 mov $0x2,%eax
8048427: eb 2a jmp 8048453 <switch_eg+0x43>
8048429: b8 01 00 00 00 mov $0x1,%eax
804842e: 66 90 xchg %ax,%ax # noop
8048430: eb 14 jmp 8048446 <switch_eg+0x36>
8048432: 8b 45 10 mov 0x10(%ebp),%eax
8048435: 0f af 45 0c imul 0xc(%ebp),%eax
8048439: eb 18 jmp 8048453 <switch_eg+0x43>
804843b: 8b 55 0c mov 0xc(%ebp),%edx
804843e: 89 d0 mov %edx,%eax
8048440: c1 fa 1f sar $0x1f,%edx
8048443: f7 7d 10 idivl 0x10(%ebp)
8048446: 03 45 10 add 0x10(%ebp),%eax
8048449: eb 08 jmp 8048453 <switch_eg+0x43>
804844b: b8 01 00 00 00 mov $0x1,%eax
8048450: 2b 45 10 sub 0x10(%ebp),%eax
8048453: 5d pop %ebp
8048454: c3 ret
18
9
14/10/2011
19
long switch_eg
(long x, long y, long z)
{
long w = 1;
switch(x) {
case 1:
w = y*z;
break;
case 2:
w = y/z;
/* Fall Through */
case 3:
w += z;
break;
case 5:
case 6:
w -= z;
break;
default:
w = 2;
}
return w;
}
20
10
14/10/2011
Resumen (Control)
Control C
if‐then‐else
do‐while
while, for
switch
Control Ensamblador
Salto condicional
Movimiento condicional
Salto indirecto
Compilador genera secuencia código p/implementar control más complejo
Técnicas estándar
Bucles convertidos a forma do‐while
Sentencias switch grandes usan tablas de saltos
Sentencias switch poco densas podrían usar árboles decisión
21
22
11
14/10/2011
Pila IA32
“Fondo” de Pila **
Región de memoria gestionada
con disciplina de pila
Crece hacia posiciones inferiores Direcciones
Crecientes
“Tope” de Pila
La Pila
crece hacia
“Abajo”
Puntero Pila: %esp
‐4
“Tope” Pila
* ocupando por tanto ese byte (el más bajo) y los 3 inmediatamente encima ** “push” = empujar 24
12
14/10/2011
La Pila
crece hacia
+4 “Abajo”
Puntero Pila: %esp
“Tope” Pila
13
14/10/2011
call 8048b90
0x110 0x110
0x10c 0x10c
0x108 123 0x108 123
0x104 0x8048553
ret
0x110 0x110
0x10c 0x10c
0x108 123 0x108 123
0x104 0x8048553 0x8048553
%eip: contador de programa * notar que dir.ret. sigue escrita en memoria, pero más allá del tope,
así que ya no se considera que esté en la pila (que sea elemento válido pila) 28
14
14/10/2011
Disciplina de pila
Estado para un procedimiento dado, necesario por tiempo limitado
Desde que se le llama hasta que retorna
El invocado† retorna antes de que lo haga el invocante†
La pila se reserva en Marcos†† † “callee/caller” en inglés
estado para una sola instanciación procedimiento †† “allocated in frames” en inglés
* “block structured” en terminología Intel
** “instantiate” = crear nuevos ejemplares 29
15
14/10/2011
Marcos de Pila
Marco
Contenido Anterior
Variables locales
Información para retorno
Puntero de Marco: %ebp
Espacio temporal
Marco para
proc
Gestión
Espacio se reserva al entrar el procedimiento “Tope” Pila
Código de “Inicialización”*
Se libera al retornar
Código de “Finalización” *
Pila
Ejemplo
yoo(…) yoo
%ebp
{
yoo
yoo
• who %esp
•
who();
• amI amI
•
} amI
amI
32
16
14/10/2011
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
who
• • • •
amI(); %ebp
who();
• • • • amI amI who
• amI(); %esp
} • • •
} amI
amI
33
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
amI(…) who
• • • •
{
amI();
who();
• • •• • amI amI who
•
amI();
•
• •amI();
• %ebp
}
} • amI amI
• %esp
}
amI
34
17
14/10/2011
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
amI(…) who
• • • •
{
amI();
who();amI(…)
• who
• • • {• amI amI
•
• amI();•
• amI();
• •
}
} • • amI amI
• amI();
} • %ebp
• amI
} amI
%esp
35
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
amI(…) who
• • • •
{
amI();
who(); amI(…)
• • •• {• amI amI who
•
• amI();• amI(…)
} • •amI();
• {
} • • • amI amI
• amI();
} • •
• amI(); amI
} • amI
•
} %ebp
amI
%esp
36
18
14/10/2011
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
amI(…) who
• • • •
{
amI();
who();amI(…)
• who
• • • {• amI amI
•
• amI();•
• amI();
• •
}
} • • amI amI
• amI();
} • %ebp
• amI
} amI
%esp
37
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
amI(…) who
• • • •
{
amI();
who();
• • •• • amI amI who
•
amI();
•
• •amI();
• %ebp
}
} • amI amI
• %esp
}
amI
38
19
14/10/2011
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
who
• • • •
amI(); %ebp
who();
• • • • amI amI who
• amI(); %esp
} • • •
} amI
amI
39
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
amI(…) who
• • • •
{
amI();
who();
• • •• • amI amI who
•
amI();
•
• •amI();
• %ebp
}
} • amI amI
• %esp
}
amI
40
20
14/10/2011
Pila
Ejemplo
yoo(…) yoo
{ who(…)
•{ yoo
yoo
who
• • • •
amI(); %ebp
who();
• • • • amI amI who
• amI(); %esp
} • • •
} amI
amI
41
Pila
Ejemplo
yoo
yoo(…) %ebp
{ yoo
yoo
• who %esp
•
who(); amI amI
•
•
} amI
amI
42
21
14/10/2011
Registros
Marco de Pila del Invocante Salvados
+
Dirección de retorno Variables
Salvada por la instrucción call Locales
Argumentos para esta llamada (invocación)
Preparación
… Puntero de Pila
Argumentos
%esp
* Si el compilador no puede resolver la compilacion del procedimiento usando sólo registros 43
Pila
void swap(int *xp, int *yp) • Resultante
{ •
int t0 = *xp; •
int t1 = *yp; %esp
*xp = t1;
&course2 subl
*yp = t0;
} &course1 %esp
call
Dir. ret. %esp
44
22
14/10/2011
popl %ebx
popl %ebp Fin
ret
45
swap Ajuste #1
Pila a la Entrada Pila Resultante
%ebp %ebp
• •
• •
• •
&course2 yp
&course1 xp
Dir. ret. %esp Dir. ret.
Ant. %ebp %esp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
46
23
14/10/2011
swap Ajuste #2
Pila a la Entrada Pila Resultante
%ebp
• •
• •
• •
&course2 yp
&course1 xp
Dir. ret. %esp Dir. ret.
%ebp
Ant. %ebp %esp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
47
swap Ajuste #3
Pila a la Entrada Pila Resultante
%ebp
• •
• •
• •
&course2 yp
&course1 xp
Dir. ret. %esp Dir. ret.
Ant. %ebp %ebp
Ant. %ebx %esp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
48
24
14/10/2011
swap Cuerpo
Pila a la Entrada Pila Resultante
%ebp
• •
• •
• •
Offset relativo a %ebp
&course2 12 yp
&course1 8 xp
Dir. ret. %esp 4 Dir. ret.
Ant. %ebp %ebp
Ant. %ebx %esp
49
swap Fin
Pila antes de Fin Pila Resultante
%ebp
• •
• •
• •
yp yp
xp xp
Dir. ret. Dir. ret. %esp
Ant. %ebp %ebp
Ant. %ebx %esp Observación
Se salva y recupera registro %ebx
... No sucede así con %eax, %ecx, %edx
popl %ebx
popl %ebp
ret 50
25
14/10/2011
Desensamblado de swap
08048384 <swap>:
8048384: 55 push %ebp
8048385: 89 e5 mov %esp,%ebp
8048387: 53 push %ebx
8048388: 8b 55 08 mov 0x8(%ebp),%edx
804838b: 8b 4d 0c mov 0xc(%ebp),%ecx
804838e: 8b 1a mov (%edx),%ebx
8048390: 8b 01 mov (%ecx),%eax
8048392: 89 02 mov %eax,(%edx)
8048394: 89 19 mov %ebx,(%ecx)
8048396: 5b pop %ebx
8048397: 5d pop %ebp
8048398: c3 ret
Código Llamada
80483b4: movl $0x8049658,0x4(%esp) # Copiar &course2
80483bc: movl $0x8049654,(%esp) # Copiar &course1
80483c3: call 8048384 <swap> # Llamar swap
80483c8: leave # Preparar retorno
80483c9: ret # Retornar
* LEAVE deshace ENTER previo: ESP←EBP, POP EBP. 51
Sentencias switch
Procedimientos IA 32
Estructura de la Pila
Convenciones de Llamada
Ejemplos ilustrativos de Recursividad & Punteros
52
26
14/10/2011
27
14/10/2011
56
28
14/10/2011
pcount_r:
Función Recursiva #1 pushl %ebp
movl %esp, %ebp
/* Recursive popcount */ pushl %ebx
int pcount_r(unsigned x) { subl $4, %esp
if (x == 0) movl 8(%ebp), %ebx
return 0; • • •
else return
(x & 1) + pcount_r(x >> 1);
}
•
•
•
Acciones
Salvar en pila antiguo valor %ebx x
Reservar espacio para argumento Dir. ret.
de llamada recursiva
Ant. %ebp %ebp
Almacenar x en %ebx
Ant. %ebx
%ebx x %esp
58
29
14/10/2011
Función Recursiva #2 • • •
movl $0, %eax
/* Recursive popcount */ testl %ebx, %ebx
int pcount_r(unsigned x) { je .L3
if (x == 0) • • •
return 0; .L3:
else return • • •
(x & 1) + pcount_r(x >> 1); ret
}
Acciones
Si x == 0, retornar
con %eax puesto a 0
%ebx x
59
Función Recursiva #3 • • •
movl %ebx, %eax
/* Recursive popcount */ shrl %eax
int pcount_r(unsigned x) { movl %eax, (%esp)
if (x == 0) call pcount_r
return 0; • • •
else return
(x & 1) + pcount_r(x >> 1);
}
Acciones •
•
Almacenar (pasar) x >> 1 en pila •
Hacer llamada recursiva
Efecto Dir. ret.
%eax puesto a resultado función Ant. %ebp %ebp
%ebx aún tiene valor de x Ant. %ebx
x >> 1 %esp
%ebx x
60
30
14/10/2011
Función Recursiva #4
/* Recursive popcount */ • • •
int pcount_r(unsigned x) { movl %ebx, %edx
if (x == 0) andl $1, %edx
return 0; leal (%edx,%eax), %eax
else return • • •
(x & 1) + pcount_r(x >> 1);
}
Asumir
%eax contiene valor de llam. recursiva
%ebx contiene x %ebx x
Acciones
Calcular (x & 1) + valor retornado
Efecto
%eax puesto a resultado función
61
Función Recursiva #5
/* Recursive popcount */ • • •
int pcount_r(unsigned x) { L3:
if (x == 0) addl $4, %esp
return 0; popl %ebx
else return popl %ebp
(x & 1) + pcount_r(x >> 1); ret
}
%ebp
Acciones
• •
Restaurar valores de • •
%ebx y %ebp • •
Restaurar %esp %esp
Dir. ret.
Ant. %ebp %ebp
%ebx
Ant. %ebx
%esp Ant. %ebx
62
31
14/10/2011
Referenciando un Puntero
/* Increment value by k */
void incrk(int *ip, int k) {
*ip += k;
}
32
14/10/2011
8 x
4 Dir. ret.
0 Ant. %ebp %ebp
Parte intermedia de add3
-4 localx
movl $3, 4(%esp) # 2nd arg = 3
leal -4(%ebp), %eax # &localx -8
movl %eax, (%esp) # 1st arg = &localx -12 Sin usar
call incrk
-16
-20 3 %esp+4
-24 %esp
66
33
14/10/2011
8 x
4 Dir. ret.
0 Ant. %ebp %ebp
Parte final de add3
-4 localx
movl -4(%ebp), %eax # Return val= localx
leave -8
ret -12 Sin usar
-16
-20
-24 %esp
67
34
14/10/2011
Bibliografía:
[BRY11] Cap.3 Computer Systems: A Programmer’s Perspective. Bryant, O’Hallaron. Pearson, 2011
Signatura ESIIT/C.1 BRY com
69
35