Linguagem assembly

Linguagem assembly

(Parte 1 de 11)

última revisão Ago/20071

Linguagem Assembly Família Intel

Linguagem ASSEMBLY da Família INTEL

1 Introdução

Este texto apresenta uma descrição da linguagem de montagem do microprocessador 8086/8. Este processador se tornou um enorme sucesso comercial, não apenas mas sobretudo devido ao lançamento em 1981 do primeiro microcomputador pessoal (PC) da IBM, que se baseava no 8088.

Figura 1: Diagrama de blocos da arquitetura interna de um processador 8086/8

Com o sucesso dos PCs e interessada em preservar ao investimento em software dos seus usuários a Intel, fabricante do processador, preocupou-se em preservar a compatibilidade das novas gerações de processadores com a arquitetura básica do 8086/8. Como resultado, mesmo os atuais membros da família Pentium ainda executam código escrito para os fundadores desta dinastia de

última revisão Ago/20072

Linguagem Assembly Família Intel processadores Intel. Levando ainda em conta a simplicidade da arquitetura do 8086/8 é didaticamente conveniente construir o estudo sobre linguagem de montagem a partir deste processador.

Este texto apresenta inicialmente a arquitetura interna destes microprocessadores visível ao programador Assembly. Em seguida é apresentada a sua linguagem Assembly. O aluno que desejar uma documentação completa, incluindo as novas instruções da família Pentium e as instruções para dados em ponto flutuante, poderão fazer o download do Manual correspondente (http://developer.intel.com/design/pentium4/manuals/245471.htm).

2 Arquitetura interna

A Figura 1 mostra a arquitetura interna dos microprocessadores 8086 e 8088. Há basicamente duas diferenças entre eles: a largura do barramento externo de dados (8 bits no 8088, e 16 bits no 8086), e o tamanho do bloco "fila de instruções" (4 bytes no 8088 e 6 bytes no 8086). Os principais blocos são:

a) ULA capaz de executar operações sobre 8 ou 16 bits. b) Banco de Registradores, constituído de:

• Quatro registradores gerais, de 16 bits, AX, BX, CX e DX, que podem ser subdivididos em (e referenciados separadamente como) registradores de 8 bits, AH, AL, BH, BL, CH, CL, DH e DL. Neste caso, X representa o registrador de 16 bits, enquanto H ("high") e L ("low") representam respectivamente seus 8 bits mais e menos significativos. Os registradores A têm a função de acumulador para algumas operações lógicas/aritméticas. Os registradores B são utilizados em algumas instruções como registradores de base. Há instruções que utilizam implicitamente os registradores C como contadores. Os registradores D não têm nenhuma função específica, além de funcionarem como registradores de rascunho.

• Dois Registradores de Índice, de 16 bits, SI e DI.

• Apontador de Pilha, de 16 bits, SP.

• Um segundo Registrador de Base, de 16 bits, BP.

• Contador de Programa, de 16 bits, IP.

• Quatro Registradores de Segmento, de 16 bits, CS, DS, ES, S. Estes registradores participam na formação do endereço físico que é gerado nos pinos de endereço do processador. Sua função será descrita, mais adiante.

• Registrador de Estado, de 16 bits. Na verdade somente 9 destes 16 bits têm significado, conforme mostra a Figura 2. Cada sinalizador ("flag") tem o seguinte significado:

15 1413 12 1 109 8 7 6 5 4 3 2 1 0

Figura 2: Registrador de Estado do 8086/8088

última revisão Ago/20073

Linguagem Assembly Família Intel

♦ OF - sinalizador de "overflow". Este bit é ativado quando a ALU ao executar uma operação o transporte para dentro do bit mais significativo é diferente do transporte para fora do bit mais significativo.

♦ DF - sinalizador de direção. Há instruções que envolvem os registradores de índice na formação do endereço efetivo dos operandos. Algumas destas instruções implicam na alteração do conteúdo do registrador de índice. Dependendo do conteúdo deste sinalizador, os registradores de índice serão incrementados ou decrementados automaticamente, quando tais instruções são executadas.

♦ IF - sinalizador de interrupção. Este sinalizador determina, se o processador está habilitado ou desabilitado a atender interrupções. Interrupção será o tema do próximo capítulo.

♦ TF - "trap flag". Quando este sinalizador está ativado, é gerada internamente uma interrupção a cada instrução executada. A compreensão de seu funcionamento será postergada para o próximo capítulo.

♦ SF - sinalizador de sinal. Corresponde ao bit mais significativo do resultado produzido pela ULA, ao executar operações artiméticas.

♦ ZF - sinalizador de zero. Indica, quando ligado, que o resultado produzido pela ULA é nulo.

♦ AF - indica o transporte para fora do nibble menos significativo - do bit 3 para o bit 4 - do resultado produzido pela ULA. É utilizado quando se manipula operandos representados em código BCD ou ASCII.

♦ PF - sinalizador de paridade. Este sinalizador é ativado, quando o número de 1s nos 8 bits menos significativos do resultado produzido pela ULA é par, e desativado caso contrário.

♦ CF - sinalizador de transporte

c) Controle. No esquema apresentado na Figura 1 o controle está dividido em dois blocos: "Sistema de Controle da EU" e "Lógica de Controle das Barras". Esta divisão se justifica tendo em vista que o processador está dividido em duas unidades funcionais que cooperam entre si:

• A Unidade de Execução - "Execution Unit" - (EU): Esta unidade é responsável exclusivamente pela execução das instruções. Ela não se ocupa da transferência de informações entre o microprocessador e os demais componentes do sistema. Quando a execução de uma instrução exige o acesso a algum operando externo ao microprocessador, a EU gera uma solicitação à

• A Unidade de Interface com o Barramento - "Bus Interface Unit" - (BIU): Esta unidade se ocupa exclusivamente com a transferência de informações entre o microprocessador e o restante do sistema. A forma como estas duas unidades cooperam será vista adiante.

A Figura 1 contém, além disso, alguns outros elementos. São eles: um

última revisão Ago/20074

Linguagem Assembly Família Intel somador (Σ), a fila de instruções, além dos quatro registradores de segmento já mencionados. A função destes elementos será discutida mais adiante.

3 Linguagem Assembly do 8086/8088

Nas linhas que se seguem são apresentadas de modo resumido as principais características da linguagem Assembly do 8086/8088 (ASM86). Para ter uma descrição detalhada desta linguagem. O aluno deverá recorrer aos manuais e livros indicados.

3.1 Convenção para o armazenamento de variáveis.

Todos os sistemas reais são capazes de armazenar variáveis que ocupam mais do que um byte, em posições consecutivas da memória. Assim, se uma variável ocupa uma palavra de 16 bits, esta variável estará armazenada em dois endereços consecutivos.

Há aqui duas convenções possíveis: a) armazenar o byte menos significativo no endereço A+1 e o mais significativo no endereço A, e b) armazenar o byte menos significativo no endereço A e o mais significativo no endereço A+1.

A Figura 3 ilustra as duas convenções para armazenar o valor 3456H

A primeira convenção é chamada de “big endien” e é utilizada pelos processadores da Motorola, por exemplo. A segunda alternativa é chamada “little endien” e é utilizada por todos os processadores da linha Intel. Deve-se ainda acrescentar que nos processadores Intel o endereço de uma palavra de dois ou quatro bytes é o endereço do byte menos significativo. Em outras palavras, se uma variável tem comprimento igual a n bytes, e está armazenadas nos endereços A,..., A+n-1 , o endereço desta variável será A.

AA
A+1A+1

endereço conteúdo endereço conteúdo “little endien” “big endien”

Figura 3: Convenções “little endien” e “big endien”.

3.2 Comandos

Existem dois tipos de comandos na linguagem Assembly-86 (ASM86): instruções e diretivas.

última revisão Ago/20075

Linguagem Assembly Família Intel

As instruções correspondem a códigos binários que são as instruções de máquina executadas pelo microprocessador. Enquanto as instruções assembler são simbólicas, as chamadas instruções de máquinas são binárias. A razão para usar instruções Assembly ao invés de instruções binárias é evidente. É muito mais fácil para o programador desenvolver de dar manutenção num programa escrito na forma de símbolos que sugerem a função de cada instrução do que num programa constituído por uma cadeia de 0’s e 1’s. O papel do programa montador (Assembler) é traduzir as instruções Assemby para as instruções de máquina.

Ao contrário do que ocorre com as instruções, o montador não gera para as diretivas nenhuma instrução de máquina. As diretivas são informações fornecidas pelo programador que auxiliam o montador no processo de montagem. As instruções podem ter até cinco campos:

((rótulo :) (prefixo) mnemônico (operando(s)) (;comentários)) onde os parênteses denotam que se trata de campos opcionais (os parênteses não são escritos pelo programador). O campo rótulo fornece um nome à posição de memória que contém a instrução, de tal maneira que se pode fazer referência a ela simbolicamente numa instrução de desvio (p. ex.: JMP) em algum outro ponto do programa. Um prefixo leva o montador a gerar um byte de prefixo que modifica de alguma forma a execução normal da instrução. O uso de tais prefixos será melhor esclarecido mais adiante neste texto. O mnemônico identifica o tipo de instrução (p. e. MOV para movimentação, ADD para adição, etc.) que deve ser gerada..

Uma instrução pode ter zero, um ou dois operandos separados por uma vírgula. Os comentários não afetam a execução de um programa, mas constituem meramente um recurso que facilita a compreensão da lógica implementada no programa. É muitíssimo útil durante o desenvolvimento ou posteriormente na manutenção do programa. Recomenda-se enfaticamente que o aluno utilize extensivamente comentários em seus programas. As diretivas podem ter até quatro campos:

(nome) mnemônico (operando(s)) (;comentários)

Algumas diretivas exigem um nome, enquanto outras proíbem um nome. O montador reconhece a diretiva a partir do mnemônico escrito no segundo campo.Todos os eventuais operandos são escritos em seguida.

(Parte 1 de 11)

Comentários