next up previous contents
Next: Criação da tabela de Up: Montagem Previous: Funcionalidades básicas   Sumário

Processamento de macro-instruções

De maneira geral, um processador de macro deve realizar quatro tarefas básicas:

  1. Reconhecer as definições de macros;
  2. Salvar as definições de macros de forma possibilitar a posterior expansão;
  3. Reconhecer as invocações a macros; e
  4. Expandir as invocações, possivelmente substituindo argumentos e verificando condições.

O processador de macros pode ser visto como um programa independente do montador, que é invocado antes do processo de montagem propriamente dito. Sua implementação mais simples pode ser realizada em dois passos.

No primeiro passo, cada linha do arquivo com o programa fonte (já sem comentários) é lida. Caso contenha na coluna do campo de operação a pseudo-instrução MACRO, então o que se segue é uma definição de macro, que deve ser armazenada. Uma estrutura de dados, a Tabela de Definição de Macro, é usada para guardar essas definições. A chave nessa tabela é o nome da macro, definido no campo de rótulo dessa mesma linha.

Associado a cada nome de macro-instrução, a tabela de definição de macro contém dois valores. Um valor é o corpo da definição da macro e o outro a sua lista de parâmetros formais.

Para obter a lista de parâmetros formais, o processador de macro verifica se essa lista está presente no campo de operandos da linha. Se estiver, cada membro da lista será associado a uma entrada em outra estrutura de dados auxiliar, a Tabela da Lista de Argumentos, que será referenciada na tabela de definição de macro (Figura 4.1).

Figura 4.1: Estruturas de dados no processamento de macros.
\includegraphics[scale=.85]{tdmacro.eps}

Para armazenar o corpo da macro, a linha a seguir é lida e copiada literalmente para a tabela. Verifica-se então se o campo de operação da linha copiada era ENDM; se sim, então a definição dessa macro é concluída. Caso contrário, o procedimento repete para a linha seguinte.

O primeiro passo do processador de macro é encerrado quando a pseudo-instrução END é encontrada, sinalizando o fim do código fonte.

No segundo passo, cada linha de entrada é novamente lida e o campo de operação é obtido. Se a operação especificada for MACRO, esta linha e todas as que a seguem, até aquela que contenha a operação ENDM, são ignoradas. Caso contrário, verifica-se se a operação está presente na tabela de definição de macro. Se não estiver, a linha é copiada para o arquivo de saída na sua forma original. Caso contrário, a linha contém uma invocação de macro-instrução que deve ser expandida.

Na expansão da macro, verifica-se se a tabela da lista de argumentos contém algum elemento. Caso haja argumentos, as strings com os nomes dos argumentos são associadas, como valores na tabela, aos parâmetros, que são as chaves nessa tabela.

A expansão da macro continua pela leitura de linhas de código da definição, a partir da tabela de definição de macros. Caso a linha contenha no campo de operação a pseudo-instrução ENDM, o processo de expansão está concluído e continua a leitura do arquivo de entrada. Caso contrário, caso o campo de operando contenha algum nome iniciado pelo símbolo &, então esse nome é buscado na tabela da lista de argumentos para ser substituído pela string correspondente nesta expansão. Após essa substituição (se houver), a linha resultante é passada para o arquivo de saída.

O processamento de macros conclui quando a pseudo-instrução END é copiada para o arquivo de saída, o qual então conterá apenas linhas com instruções do processador ou pseudo-instruções, já sem comentários ou macro-instruções.

O processamento de macros pode ocorrer em um único passo caso se restrinja que todas as invocações a uma macro só podem ocorrer no código-fonte após sua definição, quando então os dois passos podem ser combinados.


next up previous contents
Next: Criação da tabela de Up: Montagem Previous: Funcionalidades básicas   Sumário
Ivan L. M. Ricarte 2003-02-14