Sub-Rotinas

Por vezes um programa tem necessidade de repetir diversas acções (algoritmos). A sequência de instruções que desenvolve uma acção específica e que pode ser chamada de qualquer ponto de um programa designa-se por sub-rotina.

Na figura 28 está exemplificado o processo de execução de uma sub-rotina.

Fig. 28

       Quando o microprocessador encontra uma instrução de chamada de uma sub-rotina (CALL) o endereço do byte que se segue a esta instrução é colocado no stack antes de o salto se efectuar. A sub-rotina termina com uma instrução de retorno (RETURN) e, automaticamente, o endereço da instrução do programa principal que foi colocado no stack pela instrução CALL é armazenado no registo PC.

 Durante a execução da sub-rotina é provável que o conteúdo dos registos de uso geral, dos registos de índice e do registo de flags sofra alteração, perdendo-se, assim, o estado do sistema ao ser executada uma instrução CALL.

É, no entanto, possível preservar o conteúdo dos diversos registos através da sua passagem para o stack. As instruções PUSH e POP colocam e extraem do stack o conteúdo dos diferentes registos da CPU.

Dentro de uma sub-rotina é possível chamar outra sub-rotina, obtendo-se diversos níveis de sub-rotinas. Cada sub-rotina termina por uma instrução de retorno que conduz o processamento para a sub-rotina mais exterior até se atingir o programa principal.

 

Instruções Push e Pop

 1 - PUSH par de registos

A instrução PUSH par qq coloca na memória da pilha (stack) o conteúdo do par de registos qq. 0 conteúdo do registo referente aos oito bits de menor ordem do par de registos é armazenado na posição de memória indicada por (SP-2). 0 conteúdo do registo referente aos oito bits de maior ordem do par de registos é armazenado na posição de memória endereçada por (SP-1).

A instrução PUSH qq tem o formato:

 

 2 - PUSH registos IX e IY As instruções PUSH IX e PUSH IY são semelhantes à instrução PUSH qq. 0 byte de menor ordem do registo de índice é colocado na célula de memória endereçada por (SP-2), enquanto o byte de maior ordem é armazenado em (SP-1).

 A instrução PUSH 1 tem o seguinte código:

 Nenhuma das instruções PUSH afecta o registo de flags.

 3 - POP par de registos

Se no código da instrução PUSH qq atribuirmos ao bit número dois o valor 0, obtemos o código da instrução POP qq. Esta instrução atribui ao byte de maior ordem, do par de registos, o valor da célula de memória apontada por (SP+1) e ao byte de menor ordem, também do par de registos, o valor da posição de memória endereçada por (SP).

 4 - POP registos IX e IY

 A instrução POP IX, ou POP IY, carrega o byte de maior ordem do registo IX, ou IY, com o valor da célula de memória endereçada por (SP + 1), e o byte de menor ordem com o conteúdo da posição de memória apontada por (SP).

  0 código desta instrução, tanto para IX como para IY, obtém-se substituindo por 0 o valor do bit número dois do segundo byte, dos códigos de PUSH IX e PUSH IY.

Depois de uma instrução PUSH ou POP ser executada, o conteúdo do registo stack pointer é automaticamente ajustado de modo a indicar a última posição livre.

A figura 29 ilustra o processo de transferência de valores de registos para o stack e do stack para os registos, utilizando instruções PUSH e POP.

 INSTRUÇÃO PUSH BC (C5)

 

 INSTRUÇÃO POP HL (El)

 

 Na tabela 27 representam-se os códigos hexadecimais das instruções PUSH e POP.

 

 CALL nn: Chamada Incondicional de Uma Sub-Rotina

 A instrução CALL nn salvaguarda na pilha o conteúdo do contador de programa e carrega-o com o novo valor nn, expresso no segundo e terceiro bytes desta instrução. 0 ponteiro de pilha é actualizado de modo a indicar uma nova posição disponível.

Assim, o processamento prossegue com a execução da instrução armazenada na célula cujo endereço é nn. A sub-rotina termina com uma instrução de RETURN que coloca no PC o endereço da instrução imediatamente a seguir à instrução de CALL e que se encontra salvaguardado na pilha.

 A sub-rotina pode principiar por salvaguardar na pilha o, conteúdo de alguns registos (PUSH). Por outro lado, no fim da sub-rotina, e antes da instrução de retorno, o conteúdo dos registos pode ser reposto a partir da pilha com instruções de POP.

A instrução CALL nn tem o seguinte código binário:

 

 CALL CC, nn: Chamada Condicional de Uma Sub-Rotina

 Tal como nas instruções de JUMP, uma sub-rotina pode ser chamada, apenas, se uma determinada condição se verificar. As condições de chamada são testadas pela análise do valor dos bits do registo de flags e são idênticas às condições existentes na instrução JUMP.

Esta instrução é também composta por três bytes:

 Instruções de Restart (RST)

 As instruções RESTART são instruções de chamada de sub-rotinas formadas por um único byte. Estas instruções são, importantes, quando uma sub-rotina é chamada com frequência, devido ao espaço em memória que se poupa (código de um único byte).

As instruções de RESTART são oito, endereçando concomitantemente oito posições de memória. As oito posições de memória são fixas e são definidas pelos bits RRR considerando o resto do endereço constituído apenas por zeros.   

 Tal como as instruções CALL, podem-se utilizar conjuntamente com as instruções RST as operações de PUSH e POP do conteúdo de registos em relação à pilha. As sub-rotinas RST devem terminar, também, por uma instrução de RETURN.

 

 Instruções de Retorno (Return)

 Já foi referida a necessidade de se introduzir uma instrução de retorno no fim de uma sub-rotina. A instrução de retorno vai restabelecer o conteúdo do contador de programa (PC), devolvendo-lhe o endereço da posição de memória que se segue à da instrução originária da chamada da sub-rotina.

0 retorno pode ser incondicional, RET, ou dependente de uma condição que pode testar no registo de flags, RET cc.

Estas duas instruções têm os códigos binários seguintes: 

 

Nota: Algumas flags têm mais de um significado. Quando fizer o teste deve ter em conta a última operação que alterou a flag

 No caso da instrução RET cc, o retorno para o programa que chamou a sub-rotina só se efectua se a condição explicitada for verdadeira.

Na tabela 28 estão representados os códigos hexadecimais das instruções CALL e RETURN.

As instruções RETI e RETN são usadas no caso do retorno de uma sub-rotina de interrupção e de uma sub-rotina de uma interrupção não mascarável (NMI)

<-- Voltar

Hosted by www.Geocities.ws

1