120 likes | 216 Views
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 ? )
E N D
Suporte a funçõese 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çãoe 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
Arranque Corpo Término 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 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax movl (%edx),%ebx movl %eax,(%edx) movl %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret
Análise dos contextos em swap, no IA-32 • em call_swap 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); (…) } • 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
%esp %esp %esp %esp %esp frame pointer frame pointer %ebp %ebp Construção do contexto na stack, no IA-32 call_swap swap variáveis locais deswap endereçocrescente 1. Antes de invocar swap • 2. Preparação p/ invocar swap • salvaguardar registos? • passagem de parâmetros salv. registos ? antigo %ebp • 3. Invocar swap • e guardar endereço de regresso ender. regresso • 1. Início de swap • atualizar frame pointer • salvaguardar registos ? • reservar espaço p/ locais parâmetrosp/ swap 2. Corpo de swap salv. registos ? • 3. Término de swap ... • libertar espaço de var locais • recuperar registos ? • recuperar antigo frame pointer • regressar a call_swap variáveis locais decall_swap stack • 4. Terminar invocação de swap... • libertar espaço com parâmetros na stack • recuperar registos? antigo %ebp
%esp %ebp %ebp-4 Evolução da stack, no IA-32 (1) call_swap 1. Antes de invocar swap endereçocrescente void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } zip2 stack zip1 antigo %ebp frame pointer
%esp frame pointer %ebp Evolução da stack, no IA-32 (2) call_swap • 2. Preparação p/ invocar swap • salvaguardar registos?...não... • passagem de parâmetros endereçocrescente void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } &zip1 &zip2 %ebp-12 zip2 stack zip1 antigo %ebp
%esp frame pointer %ebp Evolução da stack, no IA-32 (3) call_swap endereçocrescente • 2. Preparação p/ invocar swap • salvaguardar registos?...não... • passagem de parâmetros leal -8(%ebp),%eaxCalcula &zip2 pushl %eax Empilha &zip2 leal -4(%ebp),%eaxCalcula &zip1 pushl %eaxEmpilha &zip1 &zip1 &zip2 %ebp-12 zip2 stack zip1 antigo %ebp
%ebp-12 %esp frame pointer %ebp Evolução da stack, no IA-32 (4) call_swap • 3. Invocar swap • e guardar endereço de regresso endereçocrescente void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } antigo %eip &zip1 &zip2 zip2 stack call swapInvoca função swap zip1 antigo %ebp
%esp 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 endereçocrescente antigo %ebx void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } %esp %ebp antigo %ebp frame pointer antigo %eip *xp *yp • swap: • pushl %ebpSalvaguardaantigo %ebp • movl %esp,%ebpFaz %ebp frame pointer • pushl %ebxSalvaguarda %ebx zip2 stack zip1 %ebp antigo %ebp antigo %ebp
%esp Evolução da stack, no IA-32 (6) swap 2. Corpo de swap antigo %ebx endereçocrescente %ebp antigo %ebp frame pointer void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } antigo %eip %ebp+8 *xp %ebp+12 *yp zip2 movl 12(%ebp),%ecx Carrega arg ypemecx movl 8(%ebp),%edx Carrega arg xpemedx movl (%ecx),%eax Coloca yemt1(eax) movl (%edx),%ebx Coloca xem t0 (ebx) movl %eax,(%edx) Armazena y em *xp movl %ebx,(%ecx) Armazena x em *yp zip1 stack antigo %ebp
%esp Evolução da stack, no IA-32 (7) swap • 3. Término de swap ... • libertar espaço de var locais...não... • recuperar registos • recuperar antigo frame pointer • regressar a call_swap antigo %ebx antigo %ebx endereçocrescente antigo %ebp antigo %ebp antigo %eip antigo %eip void swap(int *xp, int *yp) { (…) } *xp *yp zip2 popl %ebxRecupera %ebx movl %ebp,%espRecupera %esp popl %ebpRecupera %ebp ou leave Recupera %esp,%ebp retRegressa à f. chamadora zip1 stack %ebp antigo %ebp frame pointer
*xp *yp %esp frame pointer %ebp 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... endereçocrescente void call_swap() { int zip1 = 15213; int zip2 = 91125; (…) swap(&zip1, &zip2); (…) } &zip1 &zip2 zip2 stack addl $8,(%esp) Atualiza stack pointer zip1 antigo %ebp