Programação estruturada Vantagens • Concepção modular • Reutilização de código • Facilidade na detecção e correcção de erros • Fácil manutenção (alteração) Implementação em assembly 8086 Programa Principal (Code Segment) call • Invoca a subrotina <sub_prog> = endereço da subrotina =deslocamento call <sub_prog> <sub_prog> : ;subrotina ret • Regressa da subrotina ret ou Segmento + deslocamento 85 Programação estruturada Tipos de chamadas: intrasegment near call – Neste tipo de chamada a sub rotina está localizada no mesmo segmento de código do programa principal. Neste caso <sub_prog>=deslocamento. Chamada da subrotina call <sub_prog> • coloca na pilha o endereço cs:[FFFF] (deslocamento) da instrução pilha seguinte à instrução call, no fundo, posição de retorno. cs:[XXXX] SS:[SP] ret Endereço de retorno RRRR SS:[SP+2] cs:[RRRR] call <sub_prog> SS:[0000] cs:[0000] IP XXXX • coloca no registo IP o endereço da primeira instrução da subrotina. Retorno da subrotina ret • retira da pilha o endereço da posição de retorno e coloca-o no endereço IP 86 1 Programação estruturada Tipos de chamadas: intersegment far call – Neste tipo de chamada a subrotina está localizada num segmento distinto do segmento de código do programa principal. Neste caso <sub_prog>=segmento:deslocamento. cs’:[FFFF] cs:[XXXX] ret cs’:[0000] cs:[FFFF] cs:[RRRR] call <sub_prog> Chamada da subrotina call <sub_prog> • coloca na pilha o endereço (CS actual + deslocamento) da instrução seguinte à instrução call, no fundo, posição de retorno. • coloca no registo CS o segmento da subrotina e no registo IP o deslocamento da primeira instrução da subrotina. cs:[0000] 87 Programação estruturada Tipos de chamadas: intersegment far call – Neste tipo de chamada a subrotina está localizada num segmento distinto do segmento de código do programa principal. Neste caso <sub_prog>=segmento:deslocamento. pilha SS:[SP] CS RRRR SS:[SP+4] • Retira da pilha o segmento da posição de retorno e coloca-o no resgisto CS. SS:[0000] CS IP Retorno da subrotina ret • retira da pilha o endereço (deslocamento) da posição de retorno e coloca-o no endereço IP. CS’ XXXX 88 2 Programação estruturada Passagem de parâmetros • por valor • por referência/por variável Mecanismos de passagem de parâmetros • por registos • por variáveis globais • por pilha Passagem de parâmetros por valor/por registo Program teste; var c,d:char; <procedimento> begin write (‘c=?’); readln (c); asm end; end. mov al,c call upper mov d,al writeln (d); procedure upper;near;assembler {parâmetros – al // resultado – al } asm cmp al,’a’ jb @endif cmp al,’z’ ja @endif sub al, ‘a’-’A’ @endif: end; 89 Programação estruturada Passagem de parâmetros por referência/registos Program teste; var c:char; <procedimento> begin write (‘c=?’); readln (c); asm mov di, seg c mov es, di mov di, offset c call upper end; writeln (c); end. procedure upper;near;assembler {parâmetro – es:[di] } asm mov al, es:[di] cmp al,’a’ jb @endif cmp al,’z’ ja @endif sub al, ‘a’-’A’ mov es:[di], al @endif: end; 90 3 Programação estruturada Passagem de parâmetros por variáveis globais Program teste; var pt:pointer; n,x:word; <procedimento> Begin {chamada por procedimento em pascal} n:=5; pt:=@x factorial; end. {chamada do procedimento em assembly} asm mov n,5 mov word ptr pt, offset x mov word ptr pt+2, seg x call factorial end; writeln (x); 91 Programação estruturada Passagem de parâmetros por variáveis globais procedure factorial;near;assembler; {parâmetro n passado por valor parâmetro pt passado por referência = endereço da variável } asm mov ax,1 mov cx,n cmp cx,1 jbe @endif @ciclo: mul cx loop @ciclo @endif: les bx,pt mov word ptr es:[bx], ax end; les bx,pt pt pt+2 offset bx seg es pt = endereço da variável onde se armazena N! 92 4 Programação estruturada Passagem de parâmetros por pilha Organização da pilha do sistema (“Stack frame/Activation record”) Organização da pilha do sistema quando se invoca o procedimento (depois da instrução call) parâmetros Endereço de retorno 16 bits =offset p/ near call 32 bits = offset+segment p/ far call SS:SP BP Variáveis locais SS:[0000] 93 Programação estruturada Passagem de parâmetros por pilha Organização da pilha do sistema (“Stack frame/Activation record”) Utilização do registo BP para referência dos parâmetros (na subrotina) Antes parâmetros Endereço de retorno Instruções Depois {salvaguarda BP} push BP mov BP,SP parâmetros Endereço de retorno BP (anterior) SS:SP=SS:[BP] Referência dos parâmetros: SS:[BP+<cte>] em que cte= deslocamento em relação a BP 94 5 Programação estruturada Passagem de parâmetros por pilha Organização da pilha do sistema (“Stack frame/Activation record”) Reserva de espaço para variáveis locais (no início da subrotina) Instruções Depois parâmetros sub sp,<vlocais> parâmetros Endereço de retorno vlocais= n.º bytes Necessários para variáveis locais (multiplo de dois) Endereço de retorno Antes BP,SP BP (anterior) BP (anterior) Var. locais n.º bytes BP SP Referência às variáveis locais: SS:[BP – cte] em que cte é o deslocamento em relação a BP 95 Programação estruturada Passagem de parâmetros por pilha Organização da pilha do sistema (“Stack frame/Activation record”) Salvaguarda do conteúdo dos registos (opcional) Instruções Antes parâmetros {exemplos} push ax push cx . . . Endereço de retorno BP (anterior) Var. locais n.º bytes BP SP Depois parâmetros Endereço de retorno BP (anterior) Var. locais n.º bytes ax cx BP SP 96 6 Programação estruturada Passagem de parâmetros por pilha Organização da pilha do sistema (“Stack frame/Activation record”) No fim da subrotina • • Restabelece anteriores valores dos registos pop cx pop ax …. Liberta o espaço ocupado por variáveis locais mov sp,bp • Recupera o valor anterior de BP pop bp • Liberta o espaço ocupado pelos parâmetros ret <n.ºbytes dos parâmetros> 97 Programação estruturada Passagem de parâmetros por pilha Exemplos em Pascal/Inline assembler procedure subp (I:integer; b:byte;var x:integer);near;assembler; asm …. end; Código executado automaticamente no início da subrotina {caso existam parâmetros ou var locais} push BP mov BP,SP {caso existam parâmetros ou var locais} sub SP,<var_locais> {caso existam var locais} Código executado automaticamente no fim da subrotina mov SP,BP {caso existam var locais} pop BP {caso existam parâmetros ou var locais} ret {n.º de bytes dos parâmetros 98 7 Programação estruturada Passagem de parâmetros por pilha Organização da pilha (“stack frame/activation record” I – Passado por valor Param I B – Passado por valor Param B Endereço da variável passado por referência Segmento X Offset X End. retorno +10 +8 Acesso aos parâmetros Parâmetro I ⇔ [BP+10] Parâmetro B ⇔ [BP+8] +4 End. da variável X ⇔ [BP+4] +2 BP BP,SP 99 Programação estruturada Passagem de parâmetros por pilha Chamada do procedimento Pascal: {admitindo variável global Z} Assembly subp (10, 5, Z); Param I Param B Segmento X Offset X End. retorno BP +12 +10 +6 +4 +2 Se far call o endereço de retorno = 4 bytes BP,SP …. end; asm . . mov ax,10 push ax mov al,5 push ax mov ax, seg Z push ax mov ax, offset z push ax call subp 100 8 Programação estruturada Passagem de parâmetros por pilha Exemplo Procedure subp (var I:integer;j,k:integer);near;assembler; Push bp Mov bp,sp pop bp Ret <param> asm {i:=j+k} push es push ax push bx les bx,[bp+8] mov ax,[bp+6] add ax,[bp+4] mov es:[bx],ax pop bx pop ax pop es end; var I var I j {les bx,I} {mov ax,j} {add ax,k} {i:=j+k} k ret BP +8 +6 +4 +2 BP,SP 101 9