MC404
Programação estruturada em linguagem de montagem

Prof. Célio Guimarães
Atualizado em 05 Out 2009

Programação estruturada é importante qualquer que seja a linguagem e talvez com maior razão em linguagens de montagem. A maioria das técnicas relacionadas usadas ao programar em alto nível se aplica também para linguagens de montagem:

  1. Todo programa não trivial deve ser estruturado em subrotinas (rotinas) ou funções.
    Subrotinas devem ter uma cabeçalho explicando seu objetivo, quais são os parâmetros de entrada, quais os parâmetros de saída e, opcionalmente, quais registradores ela modifica (a fim de alertar sobre possiveis efeitos colaterais).

  2. Subrotinas podem ser colocadas antes ou após o programa principal, preferivelmente na ordem em que são invocadas, mas isto é uma questão de gosto pessoal. Alguns programadores em C preferem colocá-las no início, com o programa principal (main()) no final.
    Subrotinas usualmente possuem instruções para inicializar variáveis e podem conter laços e rótulos.

  3. Definições de macros devem ser colocadas antes de qualquer outro código e comentadas de forma análoga a subrrotinas.

  4. Em assembler comentários de linha são altamente recomendados, preferivelmente alinhados à direita de instruções/diretivas: um comentário de linha não deve explicar o que uma instrução/diretiva faz (está escrito no manual!), mas qual o seu papel no algoritmo sendo desenvolvido.

  5. Parâmetros do programa que podem mudar conforme o teste devem ser definidos via constantes no inicio do programa (via diretiva .equ), de forma análoga à utilização da diretiva #define em C. Isto permite editar uma única linha quando se deseja mudar o parâmetro para testes (por exemplo, o tamanho de um vetor).

  6. Parâmetros de versão/configuração do programa devem preferencialmente ser definidos através das macro_diretivas #ifdef, #if, #else e #endif(**).

  7. Contrôle de fluxo: este é o item menos trivial: em linguagens de alto nivel temos os comandos while,   if-then-else,   case,  break, etc; Em alto nível if-then-else aninhados expressam condições complexas que devem ser testadas em sequencia. Em assembler só temos saltos diretos e saltos condicionais para este fim. Por isso cuidados extras são necessários:

    • Em linguagem de montagem if-then-elses devem ser codificados sempre com saltos para frente; desta forma o fluxo de execução do programa segue a técnica ocidental de leitura de documentos: sempre para frente (veja exceção a seguir);

    • saltos para trás só devem existir para voltar ao início de um laço;

    • quando preciso, use a saída do meio de um laço via salto: isto equivale ao comando break da linguagem C: é conveniente e pode economizar testes desnecessários;
      se Você desenhar um grafo do seu programa com arcos indicando os desvios, este é um dos poucos pontos onde é razoável um arco (o de saída do laço) cruzar outro arco (o de volta ao início do laço). Outra exceção é o salto para fora do bloco then de um comando if-then-else implementado em assembler.
      Pelo menos uma vez desenhe este grafo para um programa seu!(*)

      (*)Exercício: escreva um trecho de programa contendo apenas uma instrução lógica e saltos condicinais apropriados, para verificar se um inteiro com sinal em um registrador é positivo, negativo, par ou ímpar. Desenhe os arcos onde há saltos e verifique se o número de cruzamentos de arcos é mínimo.

(**)Exemplo:
#define    SRAM
	rjmp reset
reset:
#ifdef SRAM
	; SRAM code
#else
	; E2PROM code
#endif