You are on page 1of 18

Procedimentos

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

A arquitetura IA32 (a maioria das arquiteturas) d


suporte implementao de procedimentos com base
em instrues para transferncia de controle e no
uso de uma pilha
memria auxiliar durante a execuo de uma aplicao

Pilha de execuo
Registrador dedicado para
apontar o topo da pilha: %esp

Stack
Pointer
%esp

Topo da pilha"

instrues para inserir (push) e


remover (pop) elementos

A pilha cresce em direo a


endereos menores da
memria
A unidade de alocao uma
palavra (4 bytes)
para alocar espao subtraimos 4
de %esp
para liberar espao somamos 4
a %esp

pilha
cresce"

endereos"
de memria
crescem"

Base da pilha"
3

Operao push: empilha


Novo topo da pilha

pushl src

subl $4, %esp


movl src,(%esp)

%eax = 0xa13f45c6

%esp
-4!

c6 45 3f a1

endereos"
de memria
crescem"

pushl %eax

Base da pilha
4

Operao pop: desempilha


popl dst

movl (%esp), dst


addl 4, %esp
%esp

popl %eax
%eax = 0xa13f45c6

Novo topo da pilha


+4!

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)

O endereo de retorno armazenado (pelo hw)


na pilha
6

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

A instruo ret retorna o controle ao chamador


o endereo de retorno removido da pilha e o
controle transferido (desvio)

As duas instrues alteram, portanto, %esp


7

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

Valor de retorno e passagem de


parmetros
instrues call e ret s transferem controle
no cuidam de passagem de valores!
uma alternativa a passagem de parmetros em
registradores
no adequada quando h muitos parmetros
nem para passar estruturas como parmetros

passagem de parmetros pela pilha


retorno de valor por %eax (inteiro ou endereo)

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

Empilhamento dos parmetros


No momento de ativao da funo (aps chamada):
int teste(int tam, int nums[])
Por que no usar %esp para
acessar os parmetros?
durante a execuo da funo o
valor se %esp pode variar!

o registrador %ebp (frame


pointer) usado para acesso
aos parmetros

end.ret
tam
&nums[0]

%esp"
%esp+4"
%esp+8"

...

base do registro de ativao (a poro


da pilha associada a uma chamada de
funo)
12

Acesso aos parmetros


Conveno (compilador C)

Durante a execuo da funo

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"

movl %ebp, %esp


popl %ebp restaura ebp-ant
ret

%ebp"

...

pilha de execuo tambm chamada de pilha de registros de ativao!

13

Exemplo
x = add(4,5)
...
pushl $5
pushl $4
call add
addl $8, %esp
movl %eax, %ecx ;retorno

...

int add(int a, int b) {


return a+b;
}
add:
push
movl
movl
addl
movl
popl
ret

%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"

<%eax, %ecx, %edx>

Cada parmetro ocupa uma palavra (4 bytes),


mesmo que seu tipo ocupe um tamanho menor
15

Uso dos Registradores


Funes usam registradores para armazenar
valores (variveis locais, temporrios)
tanto a funo chamadora (caller) como a funo
chamada (callee)

A pilha usada para preservar o contedo de


registradores
evita perda de valores ao chamar uma funo
mas quem armazena: caller? callee?

Necessidade de uma conveno


para os valores dos registradores serem "salvos"
apenas uma vez
16

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

Callee (chamada): %ebx, %esi e %edi


pode sobrescrever %eax, %ecx e %edx
porque a chamadora salvou os valores em uso

deve armazenar na pilha os valores de %ebx, %esi e %edi


antes de usar esses registradores
e deve restaurar os valores antes de retornar !
17

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

You might also like