Aula 8 Procedimentos e Funções - Inf

Propaganda
Aula 8
Procedimentos e funções
Procedimentos e Funções
• Chamada CALL label
• Retorno RET
• Ex:
...
...
Call TESTE
...
...
TESTE:
#codigo da funcao
ret
1
Procedimentos e Funções
• Chamada CALL label
• Empilha a próxima instrução a ser executada e
desvia para a função
– PUSH ENDERECO_DA_PROXIMA_INSTRUCAO
– JUMP FUNCAO
Procedimentos e Funções
• Chamada RET
• EIP <= (%ESP)
• %ESP <= %ESP – 4
• * Importante, quando manipular a pilha dentro de
uma função, a mesma deverá estar no seu estado
inicial antes da operação RET
2
Procedimentos - C
• Utilizada no C*
– Todos os parâmetros são
passados usando a pilha
– Todos os parâmetros são
alinhados em 32 bits
– Note que a ordem dos
parâmetros é do último para o
primeiro (pense como
implementar o printf, se os
parâmetros fossem passados em
ordem diferente)
– A instrução CALL armazena o
endereço de retorno
ESP
return addr
param 1
param 2
...
param N
*SystemV ABI- http://www.caldera.com/developers/devspecs/abi386-4.pdf
Convenção utilizada no C
• Logo após a entrada na
função o valor do
ESP
registrador EBP (base
pointer) e colocado no topo
da pilha
• O novo EBP, recebe o valor
do registrador ESP
• Essa série de instruções é
denominada prologue
procA:
push %EBP
mov %ESP, %EBP
OLD_EBP
return addr
param 1
param 2
...
param N
3
FRAME
• O registrador EBP é utilizado para delimitar o
ESP
“frame” da função
• A pilha é utilizada também para armazenar todas
as variáveis locais, assim o registrador EBP é
utilizado para endereçar tais variáveis
EBP
void PROC(){
int A, B;
A= 1
}
Em assembler:
PROC:
push %ESP
mov %ESP, %EBP
sub $8, %ESP #alocando espaço para as variaveis
A e B
B
A
OLD_EBP
return addr
param 1
param 2
...
mov $1, -4(%EBP)
param N
Retorno
EBX
ESP
• Recuperar o antigo valor de EBP e ajustar o
ponteiro da pilha
• Essa série de instruções é denominada epilogue
• Atenção: todos os registradores devem ter os
valores preservados, portanto os mesmos devem
ser salvos e recuperados antes de retornarem da
função
• Ex:
PROC:
push %ESP
mov %ESP, %EBP
sub $8, %ESP #alocando espaço para as variaveis
A e B
push %eax #salvando os antigos valores
push %ebx #salvando os antigos valores
...
...
... Codigo da função
pop %ebx
pop %eax
leave # (ESP <- EBP, POP EBP): restaura o frame
ret
EAX
B
A
EBP
OLD_EBP
return addr
param 1
param 2
...
param N
4
Retorno
• Recuperar o antigo valor de EBP e ajustar o
ponteiro da pilha
• Atenção: todos os registradores devem ter os
valores preservados, portanto os mesmos devem ESP
ser salvos e recuperados antes de retornarem da
função
• Ex:
PROC:
push %ESP
mov %ESP, %EBP
sub $8, %ESP #alocando espaço para as variaveis
A e B
push %eax #salvando os antigos valores
push %ebx #salvando os antigos valores
...
...
... Codigo da função
pop %ebx
pop %eax
leave # (ESP <- EBP, POP EBP): restaura o frame
ret
EBP
B
A
OLD_EBP
return addr
param 1
param 2
...
param N
Retorno
• Recuperar o antigo valor de EBP e ajustar o
ponteiro da pilha
• Atenção: todos os registradores devem ter os
valores preservados, portanto os mesmos devem
ser salvos e recuperados antes de retornarem da
função
• Ex:
PROC:
ESP EBP
push %ESP
mov %ESP, %EBP
sub $8, %ESP #alocando espaço para as variaveis
A e B
push %eax #salvando os antigos valores
push %ebx #salvando os antigos valores
...
...
... Codigo da função
pop %ebx
pop %eax
leave # (ESP <- EBP, POP EBP): restaura o frame
ret
OLD_EBP
return addr
param 1
param 2
...
param N
5
Retorno
• Recuperar o antigo valor de EBP e ajustar o
ponteiro da pilha
• Atenção: todos os registradores devem ter os
valores preservados, portanto os mesmos devem
ser salvos e recuperados antes de retornarem da
função
• Ex:
PROC:
push %ESP
mov %ESP, %EBP
sub $8, %ESP #alocando espaço para as variaveis
A e B
push %eax #salvando os antigos valores
push %ebx #salvando os antigos valores
...
...
... Codigo da função
pop %ebx
pop %eax
add $8, %ESP # elimando o espaco usado pelas
var. locais
pop %ebp
ret
ESP
return addr
param 1
param 2
...
param N
Funções
• Funções que retornam valores escalares ou ponteiros,
utilizam o registrador %eax para armazenar o resultado
int soma(int a, int b){
return (a+b)
}
Soma_2elementos:
push %EBP
mov %ESP, %EBP
movl 8(%ESP), %EAX
addl 12(%ESP),%EAX
leave
ret
ESP
#valor de a
#valor de b
OLD_EBP
return addr
A
B
...
...
6
Funções
• Funções que retornam
struct/union, retornam o
endereço através o registrador
%EAX
• Porém, neste caso, o endereço
da struct deve ser passado
através da pilha
return addr
ESP
end. struct
A
B
...
...
Funções
• A função deve retirar o
endereço, antes de executar a
operação ret
Após o retorno
return addr
ESP
A
A
ESP
B
B
...
...
...
...
7
Prologue (struct/union)
prologue:
popl %eax / pop return address
xchgl %eax,0(%esp) / swap return address
/and return value address
pushl %ebp / save frame pointer
movl %esp, %ebp / set new frame pointer
subl $80 , %esp / allocate local space
pushl %edi / save local register
pushl %esi / save local register
pushl %ebx / save local register
movl %eax , -4(%ebp) / save return value address
Epilogue (struct/union)
epilogue:
movl -4(%ebp), %eax / setup return value
popl %ebx / restore local register
popl %esi / restore local register
popl %edi / restore local register
leave / restore frame pointer
ret / pop return address
8
Usando gcc
• Usando o gcc para compilar programas em assembler
.section .data
.section .text
.global main
.type main, @function
main:
push %ebp
#salvando o frame anterior
mov %esp, %ebp #novo frame
# seu codigo
leave
ret
# recupera o frame anterior
# retorna
Compilando
gcc teste.s –o teste.x
- a função _start é agora implementada por uma função padrão que
inicializa a pilha de forma adequada, e a biblioteca libc
Exercícios
• Implemente uma função que some dois números
• Implemente uma função que calcule o fatorial de
um número
9
Download