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).
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.