Rotinas reentrantes Prof.Fernando Branquinho Rotinas Reentrantes A linguagem "C" demonstra um bom exemplo de criação de rotinas reentrantes. Isto se deve ao fato de utilizar a pilha para a passagem de parâmetros, e principalmente para a alocação de variáveis locais. Abaixo encontra-se o resultado da compilação de uma pequena rotina em "C", que demonstra essa característica: void main() { calcula(5,6); } void calcula (int a,int b) { int soma,div,mult,sub; soma=a+b; div=a/b; mult=a*b; sub=a-b; printf ("Soma %d\nSubtracao %d\nMultiplicacao %d\nDivisao %d\n",soma,sub,mult,div) } Equivalente em Assembly: ; ; ; void main() { push mov ; ; ; ; calcula(5,6); mov push mov push call pop pop ; ; ; ; bp bp,sp ax,6 ax ax,5 ax near ptr _calcula cx cx } pop ret bp ; void calcula(int a, int b) { ; push bp mov bp,sp sub sp,8 push si push di mov di,word ptr [bp+4] mov si,word ptr [bp+6] ; ; int soma,div,mult,sub; ; ; soma=a+b; ; mov ax,di add ax,si mov word ptr [bp-2],ax ; ; div=a/b; ; mov ax,di cwd idiv si mov word ptr [bp-4],ax ; ; mult=a*b; ; mov ax,di imul si mov word ptr [bp-6],ax ; ; sub=a-b; ; mov ax,di sub ax,si mov word ptr [bp-8],ax ; ; ; printf ("Soma %d\nSub ... push push push push mov push call add ; ; ; word ptr [bp-4] word ptr [bp-6] word ptr [bp-8] word ptr [bp-2] ax,offset DGROUP:s@ ax near ptr _printf sp,10 } pop pop mov pop ret di si sp,bp bp Repare na rotina main(), que os dois valores passados como parâmetro, são armazenados na pilha. mov push mov push call ax,6 ax ax,5 ax near ptr _calcula Já no início da rotina "calcula", é reservada uma área na pilha, para armazenamento das variáveis locais: push mov sub bp bp,sp sp,8 Após a execução destas instruções, podemos considerar o estado da pilha como mostrado abaixo: SP BP » » Endereço Conteúdo Instrução n-14 n-12 n-10 n-8 sub mult div soma n-6 antigo BP n-4 n-2 n IP 05 06 sub sp,8 sub sp,8 sub sp,8 sub sp,8 push bp mov bp,sp call push ax push ax Repare que após este ponto, todas as variáveis da rotina encontram-se na pilha, e são referenciadas através do registrador BP (posicionado estrategicamente entre os parâmetros passados e as variáveis locais). Exemplificando, os valores passados como parâmetro para a rotina, encontram-se na posição BP+4 e BP+6, enquanto que as variáveis locais, se encontram nas posições BP-2, BP-4, BP-6, BP-8. A instrução abaixo mostra o momento do armazenamento de um valor na variável "soma": mov word ptr [bp-2],ax Concluindo, podemos ver que este tipo de rotina não sofre problemas de reentrância, já que suas variáveis locais são armazenadas na pilha, onde uma nova área é reservada a cada re-execução da rotina. Exercícios 1. 2. 3. 4. 5. É possível criar rotinas reentrantes em "C" ? Porque? É possível criar rotinas não-reentrantes em "C" ? Dê um exemplo? Como são transportados os parâmetros, durante uma chamada de função em "C" ? Porque o registrador BP é armazenado na pilha no início da rotina "calcula" ? Considerando que este tipo de rotina possa ser chamada por vários programas rodando em multitarefa, várias áreas passam a ser reservadas na pilha. Como é possível garantir que não exista sobreposição de tais áreas ? 6. Modifique a rotina "PRINT" do programa NAVE.C, transformando-a em não-reentrante. Qual o resultado obtido ? Final do documento Fernando J.C.Branquinho http://br.geocities.com/branqs