Suporte a funções e procedimentos no IA-32 (3) Análise do código de gestão de uma função – invocação e regresso • instrução de salto, mas com salvaguarda do end. regresso – em registo (RISC; aninhamento / recursividade ? ) – em memória/stack (IA-32; aninhamento / recursividade ? ) – invocação e regresso • instrução de salto para o endereço de regresso – salvaguarda & recuperação de registos (na stack) • função chamadora ? (nenhum/ alguns/ todos ? RISC/IA-32 ? ) • função chamada? (nenhum/ alguns/ todos ? RISC/IA-32 ? ) – gestão do contexto (em stack) • atualização/recuperação do frame pointer (IA-32... ) • reserva/libertação de espaço para variáveis locais AJProença, Sistemas de Computação, UMinho, 2014/15 1 Análise das fases em swap, no IA-32 (fig. já apresentada) void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } swap: pushl %ebp movl %esp,%ebp pushl %ebx movl movl movl movl movl movl 12(%ebp),%ecx 8(%ebp),%edx (%ecx),%eax (%edx),%ebx %eax,(%edx) %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret AJProença, Sistemas de Computação, UMinho, 2014/15 Arranque Corpo Término 2 Análise dos contextos em swap, no IA-32 void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } AJProença, Sistemas de Computação, UMinho, 2014/15 • em call_swap • na invocação de swap • na execução de swap • no regresso a call_swap Que contextos (IA-32)? • passagem de parâmetros •via stack •espaço para variáveis locais •na stack •info de suporte à gestão (stack) •endereço de regresso •apontador para a stack frame •salvaguarda de registos 3 Construção do contexto na stack, no IA-32 call_swap swap %esp variáveis locais de swap 1. Antes de invocar swap 2. Preparação p/ invocar swap •salvaguardar registos? •passagem de parâmetros 3. Invocar swap •e guardar endereço de regresso frame pointer salv. registos ? %esp %ebp antigo %ebp %esp ender. regresso 1. Início de swap •atualizar frame pointer •salvaguardar registos ? •reservar espaço p/ locais 2. Corpo de swap 3. Término de swap ... %esp •libertar espaço de var locais %esp •recuperar registos ? •recuperar antigo frame pointer •regressar a call_swap frame pointer 4. Terminar invocação de swap... %ebp •libertar espaço com parâmetros na stack •recuperar registos? AJProença, Sistemas de Computação, UMinho, 2014/15 endereço crescente parâmetros p/ swap salv. registos ? variáveis locais de call_swap stack antigo %ebp 4 Evolução da stack, no IA-32 (1) call_swap 1. Antes de invocar swap endereço crescente void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } AJProença, Sistemas de Computação, UMinho, 2014/15 %esp %ebp-4 %ebp frame pointer zip2 stack zip1 antigo %ebp 5 Evolução da stack, no IA-32 (2) call_swap 2. Preparação p/ invocar swap • salvaguardar registos?...não... • passagem de parâmetros void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } AJProença, Sistemas de Computação, UMinho, 2014/15 %esp %ebp-12 endereço crescente &zip1 &zip2 zip2 frame pointer %ebp stack zip1 antigo %ebp 6 Evolução da stack, no IA-32 (3) call_swap endereço crescente 2. Preparação p/ invocar swap • salvaguardar registos?...não... • passagem de parâmetros leal pushl leal pushl -8(%ebp),%eax %eax -4(%ebp),%eax %eax Calcula &zip2 Empilha &zip2 Calcula &zip1 Empilha &zip1 %esp %ebp-12 &zip1 &zip2 zip2 frame pointer %ebp AJProença, Sistemas de Computação, UMinho, 2014/15 stack zip1 antigo %ebp 7 Evolução da stack, no IA-32 (4) call_swap 3. Invocar swap • e guardar endereço de regresso endereço crescente void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } call swap %esp antigo %eip &zip1 %ebp-12 Invoca função swap frame pointer %ebp AJProença, Sistemas de Computação, UMinho, 2014/15 &zip2 zip2 stack zip1 antigo %ebp 8 Evolução da stack, no IA-32 (5) 1. Início de swap • atualizar frame pointer • salvaguardar registos • reservar espaço p/ locais...não... swap %esp void swap(int *xp, int *yp) %ebp %esp { frame pointer int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } swap: pushl %ebp Salvaguarda antigo %ebp movl %esp,%ebp Faz %ebp frame pointer pushl %ebx Salvaguarda %ebx antigo %ebx endereço crescente antigo %ebp antigo %eip *xp *yp zip2 stack zip1 antigo %ebp AJProença, Sistemas de Computação, UMinho, 2014/15 antigo %ebp 9 Evolução da stack, no IA-32 (6) 2. Corpo de swap swap %esp %ebp void swap(int *xp, int *yp) frame pointer { } int int *xp *yp movl movl movl movl movl movl antigo %ebp endereço crescente antigo %eip t0 = *xp; t1 = *yp; = t1; = t0; 12(%ebp),%ecx 8(%ebp),%edx (%ecx),%eax (%edx),%ebx %eax,(%edx) %ebx,(%ecx) antigo %ebx %ebp+8 %ebp+12 Carrega arg yp em ecx Carrega arg xp em edx Coloca y em t1(eax) Coloca x em t0 (ebx) Armazena y em *xp Armazena x em *yp AJProença, Sistemas de Computação, UMinho, 2014/15 *xp *yp zip2 zip1 stack antigo %ebp 10 Evolução da stack, no IA-32 (7) swap %esp 3. Término de swap ... • libertar espaço de var locais...não... • recuperar registos • recuperar antigo frame pointer • regressar a call_swap void swap(int *xp, int *yp) { (…) } popl %ebx movl %ebp,%esp popl %ebp ou leave ret Recupera %esp, %ebp Regressa à f. chamadora AJProença, Sistemas de Computação, UMinho, 2014/15 antigo %ebp endereço crescente antigo %eip *xp *yp zip2 Recupera %ebx Recupera %esp Recupera %ebp antigo %ebx zip1 %ebp frame pointer stack antigo %ebp 11 Evolução da stack, no IA-32 (8) call_swap 4. Terminar invocação de swap... • libertar espaço de parâmetros na stack... • recuperar registos?...não... void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } &zip1 *xp &zip2 *yp %esp addl $8,%esp Atualiza stack pointer frame pointer %ebp AJProença, Sistemas de Computação, UMinho, 2014/15 endereço crescente zip2 stack zip1 antigo %ebp 12