Você está na página 1de 17

ARQUITECTURA de COMPUTADORES Terico-Prticas Stack e Recursividade

Alexandre Bragana Lus Nogueira Nuno Bettencourt Paulo Baltarejo Sousa Paulo Ferreira
Dep. de Engenharia Informtica ISEP

Orlando Sousa

{atb,lmn,nmb,oms,pbs,pdf}@isep.ipp.pt 2011/2012

ATB et al. (ISEP)

Decises

2011/2012

1 / 17

Funes e variveis locais

frequente uma funo ter necessidade de guardar valores temporariamente Os registos do CPU podem ser usados para esse efeito mas so em nmero limitado Pela suas caractersticas, a stack o local ideal para armazenar variveis locais Tal como vimos na aula anterior, aps termos o EBP a apontar para o topo da stack no incio da funo, podemos adicionar valores stack sem afectar a forma como os parmetros de entrada so obtidos Podemos ento reservar espao para as variveis locais na stack, continuando a usar o EBP como referncia para aceder aos parmetros de entrada da funo e s suas variveis locais
Assumindo que foram adicionadas variveis locais de 4 bytes, a primeira pode tambm ser obtida a partir do EBP com -4(%ebp), a segunda por -8(%ebp), ...

ATB et al. (ISEP)

Decises

2011/2012

2 / 17

Funes e variveis locais

ATB et al. (ISEP)

Decises

2011/2012

3 / 17

Funes e variveis locais

A gura anterior revela um problema! E se a funo colocar valores na stack durante a execuo?
Note-se que o ESP continua a apontar para o valor antigo do EBP (o que era o topo da stack no incio da funo) Logo, as variveis locais sero sobrepostas com cada push feito pela funo

A soluo reservar espao para as variveis locais subtraindo os bytes necessrios ao valor actual do ESP

ATB et al. (ISEP)

Decises

2011/2012

4 / 17

Variveis locais

function: # prologo pushl %ebp movl %esp, %ebp subl $12, %esp ...

ATB et al. (ISEP)

Decises

2011/2012

5 / 17

Funes e variveis locais

Agora, novos valores adicionados stack com push sero sempre colocados depois das variveis locais
O ESP aponta agora para o m da rea reservada para as variveis locais

O prlogo da funo passa ento a incluir uma terceira instruo para reservar o espao necessrio para todas as variveis locais usadas pela funo No m da funo, com a reposio do valor original do ESP, as variveis locais so descartadas (da o termo locais)

ATB et al. (ISEP)

Decises

2011/2012

6 / 17

Exemplo: Determinar a potncia N de um nmero X


power: #prologo pushl %ebp movl %esp, %ebp subl $4, %esp movl 8(%ebp), %ebx movl 12(%ebp), %ecx movl %ebx, -4(%ebp) main_program: ... pushl expoente pushl base call power addl $8, %esp ... power_loop_start: cmpl $1, %ecx je end_power movl -4(%ebp), %eax imull %ebx, %eax movl %eax, -4(%ebp) decl %ecx jmp power_loop_start end_power: movl -4(%ebp), %eax #epilogo movl %ebp, %esp popl %ebp ret
ATB et al. (ISEP) Decises 2011/2012 7 / 17

#reserva espaco para a variavel local #primeiro argumento (base) no %ebx #segundo argumento (expoente) no %ecx #guarda resultado actual na variavel local

#se o expoente for 1, terminou #move resultado actual para o %eax #multiplica resultado actual pela base #guarda resultado actual na variavel local #decrementa o expoente #salta para o proximo expoente

#move resultado final para o %eax

Funes recursivas

Funes recursivas so funes que se invocam a si prprias So compostas por duas partes fundamentais:
Uma ou mais condies de paragem, resolvidas sem recursividade Uma regra geral recursiva que reduz a resoluo do problema atravs da invocao recursiva de casos mais pequenos (at ser atingida alguma das condies de paragem)

int factorial(int n){ if(n == 1) return 1; else return n * factorial (n-1); }

int power(int x, int n){ if(n == 0) return 1; else return x * power(x,n-1); }

ATB et al. (ISEP)

Decises

2011/2012

8 / 17

Funes recursivas

De um modo geral, a recursividade exige que cada activao da funo tenha os seus prprios dados, o que normalmente signica os seus parmetros de entrada e variveis locais Estes dados so alocados na invocao e incio da funo e libertados no seu retorno A stack , mais uma vez, o local ideal para o fazer, sendo consistente com o mtodo de passagem de parmetros usado pelo C Desde que se cumpram as regras de manuteno do estado dos registos (atravs do seu armazenamento na stack e posterior reposio) cada funo (ou invocao) pode usar todos os registos

ATB et al. (ISEP)

Decises

2011/2012

9 / 17

Invocao de funes recursivas

Em C tipo funcao(lista de parmetros){ ... funcao(novos parmetros) ... }

Em Assembly funcao: ... push ... push call addl ... ret

parmetro n parmetro 1 funcao <n bytes>, %esp

ATB et al. (ISEP)

Decises

2011/2012

10 / 17

Exemplo: Factorial em C e Assembly


Em C int fact(int x) { if (x == 1) return 1; else return x * fact(x-1); } Em Assembly
factorial: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax cmpl $1, %eax je end_factorial decl %eax pushl %eax call factorial addl $4, %esp movl 8(%ebp), %ebx imull %ebx, %eax end_factorial: movl %ebp, %esp popl %ebp ret

ATB et al. (ISEP)

Decises

2011/2012

11 / 17

Exemplo: factorial(3)
___________ | 0003 | <- EBP+8 |___________| 1st |Return Addr| <- EBP+4 Call|___________| | Old EBP | <- EBP _____|___________|_________ N=3 | 0002 | <- EBP+8 |___________| 2nd |Return Addr| <- EBP+4 Call|___________| | Old EBP | <- EBP _____|___________|_________ N=2 | 0001 | <- EBP+8 3rd |___________| Call|Return Addr| <- EBP+4 |___________| | Old EBP | <- EBP _____|___________|__________N=1
ATB et al. (ISEP) Decises

factorial: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax cmpl $1, %eax je end_factorial decl %eax pushl %eax call factorial addl $4, %esp movl 8(%ebp), %ebx imull %ebx, %eax end_factorial: movl %ebp, %esp popl %ebp ret

2011/2012

12 / 17

Exemplo: Determinar a potncia N de um nmero X


Em C int power(int x, int n) { if(n == 0) return 1; else return power(x,n-1) * x; } Em Assembly
power: pushl %ebp movl %esp, %ebp pushl %ecx pushl %ebx movl 12(%ebp), %ecx movl 8(%ebp), %ebx cmpl $0, %ecx jne next_power movl $1, %eax jmp end next_power: decl %ecx pushl %ecx pushl %ebx call power addl $8, %esp mull %ebx end: popl %ebx popl %ecx movl %ebp, %esp popl %ebp ret
Decises 2011/2012 13 / 17

ATB et al. (ISEP)

Exemplo: power(5,2)
___________ | 2 | <- EBP+12 |___________| X | 5 | <- EBP+8 |___________| |Return Addr| <- EBP+4 1st |___________| Call| Old EBP | <- EBP X _____|___________|___________N N | 1 | <- EBP+12 |___________| X | 5 | <- EBP+8 |___________| |Return Addr| <- EBP+4 2nd |___________| Call| Old EBP | <- EBP X _____|___________|___________N N | 0 | <- EBP+12 |___________| X | 5 | <- EBP+8 |___________| |Return Addr| <- EBP+4 3rd |___________| Call| Old EBP | <- EBP X _____|___________|___________N N
ATB et al. (ISEP)

= 5 = 2

= 5 = 1

= 5 = 0
Decises

power: pushl %ebp movl %esp, %ebp pushl %ecx pushl %ebx movl 12(%ebp), %ecx movl 8(%ebp), %ebx cmpl $0, %ecx jne next_power movl $1, %eax jmp end next_power: decl %ecx pushl %ecx pushl %ebx call power addl $8, %esp mull %ebx end: popl %ebx popl %ecx movl %ebp, %esp popl %ebp ret
2011/2012 14 / 17

Funes recursivas com agregao


Algumas funes recursivas podem exigir a agregao de mais do que uma invocao da funo para a produo de um resultado intermdio fib(3) / \ / \ fib(2) fib(1) /\ | / \ | fib(1) fib(0) 1 | | | | 1 0
int fibonacci(int n){ if(n == 0) return 0; else if(n == 1) return 1; else return fibonacci(n-1) + fibonacci(n-2); }

Para bonacci(3), por exemplo, o resultado de bonacci(2) tem de ser determinado e guardado temporariamente, depois necessrio determinar bonacci(1) e s ento podem os dois valores ser agregados pela adio

ATB et al. (ISEP)

Decises

2011/2012

15 / 17

Fibonacci

fibonacci: pushl %ebp movl %ebp, %esp pushl %ebx movl 8(%ebp), %eax cmpl $0, %eax je fim not_zero: cmpl $1, %eax je fim not_one: subl $1, %eax pushl %eax call fibonacci addl $4, %esp # guarda o "1o " resultado em %ebx movl %eax, %ebx

movl 8(%ebp), %eax subl $2, %eax pushl %eax call fibonacci addl $4,%esp #soma o resultado das duas "invocaes" addl %ebx, %eax fim: popl %ebx movl %ebp, %esp popl %ebp ret

ATB et al. (ISEP)

Decises

2011/2012

16 / 17

Exerccios

Implemente em C uma funo recursiva para determinar a soma de todos os nmeros de 1 at N Implemente a mesma funo agora em Assembly

ATB et al. (ISEP)

Decises

2011/2012

17 / 17

Você também pode gostar