|
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:
- 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).
- 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.
- Definições de macros devem ser colocadas antes de qualquer outro código
e comentadas de forma análoga a subrrotinas.
- 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.
- 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).
- Parâmetros de versão/configuração do programa devem preferencialmente ser definidos através
das macro_diretivas #ifdef, #if, #else e #endif(**).
- 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