Professional Documents
Culture Documents
Chamada de funes e
passagem de parmetros
Procedimentos
Ao chamarmos um procedimento/funo passamos
dados & controle de uma parte do cdigo para outra
chamador chamado
parmetros e valor de retorno
Pilha de execuo
Registrador dedicado para
apontar o topo da pilha: %esp
Stack
Pointer
%esp
Topo da pilha"
pilha
cresce"
endereos"
de memria
crescem"
Base da pilha"
3
pushl src
%eax = 0xa13f45c6
%esp
-4!
c6 45 3f a1
endereos"
de memria
crescem"
pushl %eax
Base da pilha
4
popl %eax
%eax = 0xa13f45c6
c6 45 3f a1
crescem
endereos
de memria
Base da pilha
5
Transferncia de Controle
Duas instrues realizam a transferncia de
controle: call label e ret
necessrio guardar o endereo de retorno para
que o controle possa voltar para esse endereo ao
final da execuo da funo
esse endereo o da instruo seguinte ao call !
call
movl
funcao1
%eax, (%ebx)
Chamada e Retorno
A instruo call label transfere o controle para
uma funo
o endereo de retorno inserido na pilha antes do
controle ser transferido para a funo
transferncia o desvio para o endereo de label
Exemplo de chamada
804854e:
8048553:
call
add
sum <8048b90>
$4, %esp
Antes do call
0x108
123
Depois do call
0x104
0x8048553
0x108
123
Pilha
(na memria)
0x10c
0x10c
0x110
0x110
%esp
0x108
%eip
0x804854e
%esp
0x104
%eip 0x8048b90
Registradores
na CPU
Exemplo de Retorno
8048591:
ret
Antes do ret
Depois do ret
0x8048553
0x104 0x8048553
0x108
0x10c
0x108
0x10c
0x110
0x110
%esp
123
0x104
%eip 0x8048591
%esp
123
0x108
%eip 0x8048553
Pilha
(na memria)
Registradores
na CPU
10
Passagem de parmetros
Conveno em C: chamador empilha os
parmetros na ordem inversa em que aparecem
na declarao do procedimento (i.e., da direita
para a esquerda)
int teste(int tam, int nums[])
11
end.ret
tam
&nums[0]
%esp"
%esp+4"
%esp+8"
...
Incio de procedimento:
pushl %ebp salva ebp-ant
movl %esp, %ebp novo RA
Durante o procedimento:
parmetros so acessados via
%ebp+<deslocamento>!
Fim de procedimento:
%esp"
...
ebp-ant
end.ret
tam
&nums
%ebp+8!
%ebp+12!
...
ebp-ant"
%ebp"
...
13
Exemplo
x = add(4,5)
...
pushl $5
pushl $4
call add
addl $8, %esp
movl %eax, %ecx ;retorno
...
%ebp
%esp, %ebp
8(%ebp), %eax /* a */
12(%ebp), %eax /* b */
%ebp, %esp
%ebp
14
Observaes importantes
tarefa do chamador desempilhar os
parmetros aps o retorno da funo chamada
instruo pop ou soma de um valor a %esp
pilha imediatamente
antes do call
e depois do ret
<parmetros>
%esp"
Conveno de Salvamento
Deve ser respeitada por todas as funes,
inclusive bibliotecas
No Linux:
Caller (chamadora): %eax,%ecx e %edx
deve armazenar o contedo na pilha antes de preparar a
chamada da funo
Exemplo
/*
g: push %ebp
%ecx usado pela chamadora
movl %esp, %ebp
%edx tem o valor do parmetro
push %ebx
*/
movl 8(%ebp), %eax
...
movl $1, %ebx
pushl %ecx ;salva reg
...
pushl %edx ;parametro
movl %ebx,%eax
call g
popl %ebx
addl $4, %esp
movl %ebp, %esp
popl %ecx
popl %ebp
;o retorno da f est em eax:
ret
movl %eax,(%ecx)
...
18