Assembly. Prof. Jorge Cavalcanti. Prof. Sérgio Faustino.

Documentos relacionados
No. de bits. O primeiro IBM PC foi construído com o 8088 (versão de 8 bits do 8086).

CPU. CPU Unidade Central de Processamento. Função: leitura, escrita e processamento de dados

Laboratório de Sistemas Processadores e Periféricos Lista de comandos de Assembly

x86 arquitetura e instruções básicas

Organização de Computadores 1

Professor: Dr. Rogério Rodrigues de Vargas.

ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA

Microprocessadores I ELE Aula 7 Conjunto de Instruções do Microprocessador 8085 Desvios

Registradores. Os processadores possuem espaços específicos onde são guardados valores, os chamados registradores.

EEL Microprocessadores

Microprocessadores. Família x86 - Programação do i8086

2º Estudo Dirigido CAP 3

7. A pilha e subrotinas

2.5 - Instruções Lógicas do ULA

José Augusto Fabri. Assembly Básico

Organização Funcional

MÓDULO. Conjunto de Instruções do 8086/88 Aritméticas, lógicas, deslocamento e rotação M 02

ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA

Arquitectura de Computadores 3º Teste. Instruções do x86

ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA

AJProença, Sistemas de Computação, UMinho, 2017/18 1. Componentes (físicos) a analisar: a unidade de processamento / o processador:

SSC510 Arquitetura de Computadores 1ª AULA

Solução Lista de Exercícios Processadores

Arquitetura de Computadores Conceitos Fundamentais. Graduação em Engenharia Elétrica - UFPR Prof. Carlos Marcelo Pedroso 2016

Organização e Arquitetura de Computadores I

Linguagem de Montagem e Assembly. André Luiz da Costa Carvalho

Universidade de São Paulo

Organização de Computadores

Arquitetura e Organização de Computadores

2. A influência do tamanho da palavra

Periféricos e Interfaces Ano lectivo 2003/2004 Docente: Ana Paula Costa. Aula Teórica 3

Aula 14 Funcionamento de Processadores (Visão específica)

Arquitetura e Organização de Computadores

Disciplina: Arquitetura de Computadores

CONJUNTO DE INSTRUÇÕES

2. A influência do tamanho da palavra

Operadores lógicos (bit a bit)

Arquitetura e Organização de Computadores

William Stallings Arquitetura e Organização de Computadores 8 a Edição

Sistemas de Microprocessadores I Lista de exercícios (questões de provas de semestre anteriores)

ORGANIZAÇÃO DE COMPUTADORES CAPÍTULO 6: PROCESSADORES. Prof. Juliana Santiago Teixeira

Microprocessadores I ELE Conjunto de Instruções do Microprocessador 8085 Aula 9 - PILHA E SUBROTINAS -

Aula 4 Conjunto de Instruções do Microprocessador 8085 Grupo Aritmético

ENGENHARIA DE SISTEMAS MICROPROCESSADOS

Sistemas de Computação

Microprocessador Intel 8086

Prof. Gustavo Oliveira Cavalcanti

EXEMPLO DE ARQUITETURAS REAIS INTEL 8086 AULA 07 Arquitetura de Computadores Gil Eduardo de Andrade

Prof. Adilson Gonzaga

Conjunto de Instruções e Modelos de Arquiteturas

Microprocessadores CPU. Unidade de Controle. Prof. Henrique

ULA. Combina uma variedade de operações lógicas e matemáticas dentro de uma única unidade.

Conjunto de Instruções e Modelos de Arquiteturas

14/3/2016. Prof. Evandro L. L. Rodrigues

Algoritmos e Estruturas de Dados I (DCC/003) Estruturas Básicas. Aula Tópico 2

Sistemas de Computação para Controle e Automação CIC132. Assembly. Assembly. Notas. Décima quarta aula: Introdução a programação Assembly

INSTRUÇÕES DE TRANSFERÊNCIA

Programação de Microcontroladores II

Todo processador é constituído de circuitos capazes de realizar algumas operações primitivas:

SEL-433 APLICAÇÕES DE MICROPROCESSADORES I

NEANDERWIN. Algumas características do processador Neander são:

CONJUNTO DE INSTRUÇÕES DE UM PROCESSADOR (UCP)

William Stallings Arquitetura e Organização de Computadores 8 a Edição

Introdução à Organização de Computadores. Aula 8

Organização Básica de Computadores. Organização Básica de Computadores. Organização Básica de Computadores. Organização Básica de Computadores

Linguagem de Montagem Assembly

OTermo Assembly significa montagem, ou seja, linguagem

A linguagem ASSEMBLY

Unidade de Controle. UC - Introdução

CONJUNTO DE INSTRUÇÕES DE UM PROCESSADOR (UCP)

Arquitectura de Computadores

LISTA 02 CONJUNTO DE INSTRUÇÕES - GABARITO

Conjunto de Instruções do 8051

A arquitectura IA32. A arquitectura de um processador é caracterizada pelo conjunto de atributos que são visíveis ao programador.

Neander - características

Evolução dos computadores

Arquitetura de Computadores I

Símbolos e abreviaturas utilizadas na descrição das instruções

ELETRÔNICA DIGITAL II. AUTOR: ENG. ANTONIO CARLOS LEMOS JÚNIOR

Algoritmos e Estruturas de Dados I (DCC/003) 2013/1. Estruturas Básicas. Aula Tópico 4

ção de Computadores I

Histórico de desenvolvimento de computadores Prof. Luís Caldas Aula 02 Processador de uso geral

SEL-614 MICROPROCESSADORES E APLICAÇÕES. Adilson Gonzaga

Estrutura Básica de um Computador

Trabalhos Práticos Arquitetura de Computadores I Prof. Fabian Vargas

Conjunto de Instruções. Alisson Brito

Para facilitar o entendimento das rotinas escritas em assembly, apresentadas em aula, estudar as seguintes instruções da linguagem assembly:

Arquitetura de Computadores. Ciclo de Busca e Execução

PCS-2529 Introdução aos Processadores. Prof. Dr. Paulo Sérgio Cugnasca

Conjunto de Instruções (ISA) I

UNIDADE CENTRAL DE PROCESSAMENTO FELIPE G. TORRES

Arquitetura e Organização de Computadores

Prof. Leonardo Augusto Casillo

Nível do Conjunto de Instruções Prof. Edson Pedro Ferlin

Processador. Processador

sumário 1 bases numéricas 1 2 sistemas de numeração em computação introdução representação de números... 3

Arquitetura do 8086/8088

UNIDADE CENTRAL DE PROCESSAMENTO FELIPE G. TORRES

Introdução à Computação: Arquitetura von Neumann

Prof. Leonardo Augusto Casillo

Transcrição:

F A C A P E FACULDADE DE CIÊNCIAS APLICADAS E SOCIAIS DE PETROLINA CIÊNCIA DA COMPUTAÇÃO Assembly MANUAL DE REFERÊNCIA Prof. Jorge Cavalcanti jorge.cavalcanti@uol.com.br Prof. Sérgio Faustino sergiofaustino@hotmail.com Laboratório de Arquitetura de Computadores

1. INTRODUÇÃO Este manual objetiva abordar superficialmente diversos tópicos relacionados ao conjunto de instruções dos microprocessadores 8086/88. É o suporte necessário aos diversos experimentos que são realizados utilizando o SID como depurador assembly. Inicialmente é apresentada uma rápida revisão sobre sistemas de numeração e suas conversões, depois são feitos comentários sobre os microprocessadores apresentando a arquitetura do 8086/88. A partir de então são descritos os diversos registradores e flags utilizados pelo microprocessador, e finalmente são apresentadas as principais instruções assembly utilizadas nos experimentos com suas funções. No final são mostrados pequenos programas exemplos fazendo uso de interrupções. Qualquer conhecimento mais aprofundado consulte livros específicos indicados na bibliografia. 2. CONVERSÃO ENTRE SISTEMAS DE NUMERAÇÃO Existem vários sistemas numéricos, dentre os quais se destacam: o sistema decimal, o binário, o octal e o hexadecimal. Os sistemas binário e hexadecimal são muito importantes nas áreas de técnicas digitais e informática pois há uma forte ligação entre estes sistemas de numeração e os circuitos lógicos. Utilizando o conceito básico de formação de um número, obtém-se o equivalente decimal do número binário 1001 2 da seguinte forma: 2 3 2 2 2 1 2 0 1 0 0 1 1 x 2 3 + 0 x 2 2 + 0 x 2 1 + 1 x 2 0 = 1 x 8 + 1 x 1 = 9 10 1001 2 = 9 10 Será visto agora a transformação inversa, ou seja, a conversão de um número do sistema decimal para o sistema binário. Para converter 47 10 em binário faz-se: 47 2 = 23 1 resto = 1 23 2 = 11 2 resto = 1 11 2 = 5 3 resto = 1 5 2 = 2 4 resto = 1 2 2 = 1 5 resto = 0 1 2 = 0 6 resto = 1 O último resto será o algarismo mais significativo e ficará à esquerda. Os outros algarismos seguem-se na ordem até o primeiro resto. Logo: 47 10 = 101111 2 O sistema hexadecimal possui 16 algarismos, sendo sua base igual a 16. Os algarismos são assim enumerados: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, e F A tabela 1 mostra a seqüência de numeração do sistema hexadecimal ate a quantidade dezoito. A regra de conversão do sistema hexadecimal para o sistema decimal é análoga à de outros sistemas, somente neste caso, a base é 16. Como exemplo, será convertido o número 3F 16 em decimal. 16 1 16 0 3 F 3 x 16 1 + F x 16 0 = sendo F 16 = 15 10, substituindo: 3 x 16 1 + 15 x 16 0 = 3 x 16 + 15 x 1 = 63 10 3F 16 = 63 10 2

Tabela 1 Seqüência de numeração hexadecimal e binária. DECIMAL HEXADECIMAL BINÁRIO 0 0 0000 1 1 0001 2 2 0010 3 3 0011 4 4 0100 5 5 0101 6 6 0110 7 7 0111 8 8 1000 9 9 1001 10 A 1010 11 B 1011 12 C 1100 13 D 1101 14 E 1110 15 F 1111 16 10 10000 17 11 10001 18 12 10010 A conversão do sistema decimal para hexadecimal se dá da seguinte forma, considerando a conversão do número 1000 10 em hexa: 1000 16 = 62 1 resto = 8 62 16 = 3 2 resto = 14 3 16 = 0 3 resto = 3 sendo 14 10 = E 16, temos: 1000 10 = 3E8 16 Para converter números hexadecimais em binários necessitam-se de 4 bits para representar cada algarismo hexadecimal. Por exemplo, para converter o número C13 16 para o sistema binário, faz-se: C 1 3 1100 0001 0011 C13 16 = 110000010011 2 A conversão do sistema binário para o sistema hexadecimal é feita agrupando-se os dígitos binários de 4 em 4 bits da direita para a esquerda. Por exemplo, para transformar o número 10011000 2 em hexadecimal: 1001 1000 10011000 2 = 98 16 9 8 3. OPERAÇÕES ARITMÉTICAS NO SISTEMA BINÁRIO Para efetuar a adição no sistema binário, deve-se agir como numa adição convencional no sistema decimal, lembrando que, no sistema binário, tem-se apenas 2 algarismos. Para exemplificar, serão somados os números binários 110 2 e 111 2. 3

110 2 + 111 2 = 1101 2 verificação: (6 10 + 7 10 = 13 10 ) O método de subtração no sistema binário é análogo a uma subtração no sistema decimal. Observa-se que para o caso 0 1, o resultado será igual a 1, porém haverá um transporte para a coluna seguinte que deve ser acumulado no subtraendo e, obviamente, subtraído do minuendo. Por exemplo, é mostrada abaixo a resolução da operação 10002 111 2 passo a passo. 4. MICROPROCESSADORES Este componente é o principal responsável pelo desempenho de um microcomputador. Exemplos de microprocessadores usados nos PCs são o Pentium, o 486 e o 386, além de outros, é claro. Todos os microprocessadores usados nos PCs são descendentes do 8086, o primeiro microprocessador de 16 bits lançado pela Intel, no final dos anos 70. Antes deles, reinavam os microprocessadores de 8 bits, entre os quais pode-se citar o 8080, 0 8085, o Z80, o 6502, o 6800 e o 6809. Um microprocessador é um chip que contém o que é chamado de Unidade Central de Processamento (em inglês, Central Processing Unit, ou CPU). É responsável por buscar e executar instruções existentes na memória. Essas instruções são chamadas de linguagem assembly ou propriamente linguagem de máquina. São comandos muito simples, como operações aritméticas e lógicas, leituras, gravações, comparações e movimentações de dados. Essas instruções simples, quando agrupadas, formam os programas. 4.1 8086 Lançado pela Intel em 1978, o 8086 tinha um desempenho dez vezes melhor que seu antecessor o 8080. Seus registradores tinham a largura de 16 bits, o barramento de dados passou de 8 para 16 bits e o barramento de 4

endereços se tornou maior com 20 bits de largura, permitindo assim que fosse controlado mais de 1 milhão de bytes de memória. A memória passou a ser tratada de maneira diferente pois esse processador tratava a mesma como se fosse dividida em até 16 segmentos contendo 64 kilobytes cada, e não permitia que nenhuma estrutura de dados ultrapassasse a barreira entre os segmentos. 4.2 8088 O 8088 surgiu da necessidade em se criar um processador com características parecidas com as do 8086 mas que tivesse um custo menor. Dessa forma, a Intel colocou no mercado um chip que só se diferenciava do 8086 pelo fato de ter um barramento de dados de 8 bits. Em virtude de sua concepção menos avançada e do baixo custo de produção o 8088 foi escolhido pela IBM, para o projeto de seu computador pessoal, pois, além de possuir o projeto interno de 16 bits também pertencia à mesma linhagem do 8080. A figura 1 apresenta o diagrama de blocos do microprocessador 8086/88. Figura 1 Diagrama de Blocos do 8086/88. 5. O QUE É ASSEMBLY? Assembly é uma linguagem de baixo nível, que pode ser usado em conjunto com linguagens de alto nível para acelerar tarefas lentas. Basicamente ela consiste de sentenças que representam instruções em linguagem de máquina, e, como está próxima ao código de máquina, ela é rápida. Há décadas atrás, quando surgiu o 8086, programar não era uma tarefa fácil. Quando os primeiros computadores foram desenvolvidos, a programação tinha que ser feita em código de máquina. Como não era uma tarefa fácil criaram a linguagem Assembly. Para programar em assembly é necessário o tradutor assembler, um programa de computador que produz um código binário correspondente a cada mnemônico (instrução assembly). Os programas de tradução avisam quando encontra algum erro no programa. Nos experimentos em laboratório será utilizado o SID como tradutor assembler. 5.1 Por que aprender assembly? A primeira razão para se trabalhar com assembly é a oportunidade de conhecer melhor o funcionamento do PC, o que permite o desenvolvimento de programas de forma mais consistente. Uma outra razão é que programas assembly são mais rápidos, menores e mais poderosos do que os criados com outras linguagens. Também 5

oferece maior flexibilidade e controle sobre o PC, ao nível de hardware. Além do mais, o assembler (montador) permite uma otimização ideal nos programas, seja no seu tamanho ou execução. Uma outra vantagem é que o programador assembly tem acesso a todos os recursos e instruções disponíveis na máquina. O programador de linguagem de alto nível não tem este acesso. Por exemplo, se for necessário verificar um bit de estouro (overflow) em um registrador, um programa assembly pode testá-lo, mas não um programa Pascal. 6. REGISTRADORES E FLAGS NO 8086/88 Quando se está trabalhando com assembly, tem-se que usar registradores. Pode-se imaginá-los como sendo variáveis já definidas para o programador. O 8086/88 possui 14 registradores distribuídos nas unidades internas EU (Unidade de Execução) e BIU (Unidade de Interface com o Barramento). Segundo a Intel, os registradores podem ser agrupados da seguinte forma: Registradores de Uso Geral: AX, BX, CX, DX, SP, SI e DI; Registradores de Segmento: CS, DS, SS e ES; Apontador de Instrução: IP; Registrador de FLAGS. 6.1 Registradores de Uso Geral (AX, BX, CX, DX, SP, SI e DI) Estes registradores são definidos como registradores de uso geral pois se pode realmente armazenar qualquer coisa neles. São também registradores de 16 bits, o que significa que é possível armazenar um inteiro positivo de 0 a 65535, ou um inteiro com sinal de -32768 to 32768. Então se tiver que armazenar 0A4C (hexadecimal) em AX, AH conterá 0A, e AL conterá 4C. Os registradores de uso geral são subdivididos em dois conjuntos de 4 registradores: Registradores de Dados: AX, BX, CX e DX. Seus bytes superiores (AH, BH, CH e DH) e inferiores (AL, BL, CL e DL) podem ser acessados de modo separado. Isto significa que cada registrador pode ser usado como um registrador de 8 ou 16 bits. Isto é vantajoso porque evita o uso de registradores de 16 bits quando se realizam operações de 8 bits. Eles podem ser utilizados sem restrições na maioria das operações lógicas e aritméticas. Como será visto a seguir, adicionalmente algumas instruções usam certos registradores de forma implícita, permitindo uma poderosa forma de codificação. Registradores Apontadores e de Indexação: SP, BP, SI e DI. Todo acesso é feito em 16 bits. Podem também participar da maioria das operações lógicas e aritméticas. Registrador AX (AH + AL) Também denominado acumulador primário. Todas as operações de I/O são realizadas através deste registrador. As operações que utilizam dados imediatos necessitam de menos memória quando são feitas através de AX. Geralmente é utilizado como hospedeiro para valores retornados de sub-rotinas. Registrador BX (BH + BL) Também denominado Registrador Base. Usado preferencialmente como apontador da base de uma tabela de dados. Todas as referências à memória que usam esse registrador no cálculo do endereço usam o registrador DS como segmento padrão. Registrador CX (CH + CL) Também denominado contador, sendo usado prioritariamente para contar o número de interações no interior de um loop e também na manipulação de strings. Ele é decrementado durante as operações envolvendo loops e strings. Também utilizado na rotação e deslocamento de vários bits. 6

Registrador DX (DH + DL) Também chamado de registrador de dados ou endereçador de I/O. É usado para guardar dados de 16 bits nas operações com a ULA e controle indireto de I/O. Pode ser usado por compiladores para retornar valores de subrotinas. Registrador SP É denominado Stack Pointer (Ponteiro de Pilha). Utilizado juntamente com BP para acessar dados no segmento da pilha. Armazena o offset do endereço do topo da pilha. Todas as referências ao SP, por definição, utilizam juntamente o registrador de segmento SS. Também pode ser usado como operando em operações lógicas e aritméticas de 16 bits. Registrador BP É denominado Base Pointer (Ponteiro da Base). Permite acessar dados no segmento da pilha. Tipicamente é usado para acessar parâmetros que foram passados pela pilha. Também pode ser usado como operando em operações lógicas e aritméticas de 16 bits. Registradores de Indexação (SI e DI) São denominados Source Index (Índice de Origem) e Destination Index (Índice de Destino). São usados para acessar dados na memória de dados. São extensivamente usados nas operações com strings. Também podem ser usados como operando em operações lógicas e aritméticas de 16 bits. 6.2 Registradores de Segmentos A memória do 8086/88 é dividida em segmentos lógicos de até 64 Kb. A CPU tem acesso simultâneo a até 4 segmentos, utilizando os seguintes registradores como seletores de endereço: CS, DS, SS e ES. Estes registradores estão localizados na BIU, sendo acessíveis para programas, podendo ser manipulados por várias instruções. São descritas a seguir as principais funções de cada um destes registradores. Registrador CS É denominado Code Segment (Segmento de Código). É utilizado para montar o endereço de uma instrução (code) a ser buscada (fetch) na memória. CS define o endereço base (segmento) e deve ser somado ao registrador IP (também localizado na BIU) para formar o endereço de 20 bits da instrução. Em outras palavras, aponta para o segmento de código de instrução em uso. Registrador DS É denominado Data Segment (Segmento de Dados). Aponta para os segmentos de dados onde geralmente são armazenadas as variáveis de programa. Em conjunto com IP define o endereço efetivo do dado a ser lido ou escrito na memória. Registrador SS É denominado Stack Segment (Segmento de Pilha). Aponta para o segmento da pilha em uso. Todos os acessos à pilha utilizam os registradores SP e BP e utilizam como referência o registrador de segmento de pilha (SS). Registrador ES É denominado Extra Segment (Segmento Extra). É uma opção extra para apontar a base de um segmento de dados (strings). Por exemplo, ele é utilizado juntamente com o DI para formar o endereço da base de strings de dados. 7

6.3 Registrador IP É denominado Instruction Pointer (Ponteiro de Instruções). Este registrador é atualizado pela BIU e contém a distância em bytes (offset) da próxima instrução em relação ao início do código que está sendo executado, isto é, ele aponta para a próxima instrução. Os programadores não têm acesso direto ao registrador. 6.4 Registrador de FLAGs O microprocessador 8086/88 contém em seu interior um total de 9 sinalizadores, também conhecidos como flags. Eles existem para indicar resultados obtidos sempre na última operação lógica ou aritmética executada, ou para definir o comportamento do microprocessador na execução de certas instruções. Estes 9 flags estão agrupados, para facilidade de acesso, em um registrador de 16 bits, chamado de Registrador de Flags, Registrador de Estado ou Palavra de Estado do Programa, sendo localizado na EU. Como mostra a figura 2, ele utiliza bits para armazenar informações de estado (status) e de controle. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 O D I T S Z A P C Flags de estado: O, S, Z, P, C e A. Flags de controle: T, D, I. 6.4.1 Flags de Estado Figura 2 Registrador de Flags do 8086/88. Os bits de estado refletem certas propriedades de resultados de operações lógicas e aritméticas realizadas na EU, a qual é responsável por setar estes bits no registrador. A seguir é descrito o significado dos flags de estado. Flag A (Auxiliary): reflete o vai um do terceiro bit de uma operação de 8 bits. É utilizado por instruções que trabalham com operações decimais. Flag C (Carry): reflete o vai um do bit mais significativo nas operações aritméticas (de 8 e 16 bits). É também modificado por algumas instruções de rotação e deslocamento. Flag O (Overflow): é setado quando o resultado de uma operação aritmética excede os limites da área destinada ao armazenamento (que pode ser 8 ou 16 bits). Ou quando ocorre um vai um do penúltimo bit mais significativo para o último bit mais significativo. Se o registrador ou variável for de 8 bits, e O = 1, significa que houve um vai um do 6º para o 7º bit do registrador ou variável. Se o registrador ou variável for de 16 bits, e O = 1, significa que houve um vai um do 14º para 15º bit do registrador ou variável. Flag S (Sign): é igual ao bit de mais alta ordem do resultado de uma operação aritmética, ou seja, indica se o resultado da operação é positivo (S = 0) ou negativo (S = 1). Flag P (Parity): indica a paridade (par) dos 8 bits menos significativos do resultado da operação realizada (aritmética ou lógica): P = 1 número par de 1 nos 8 bits menos significativos. P = 0 número ímpar de 1 nos 8 bits menos significativos. Flag Z (Zero): é setado (Z = 1) se o resultado da operação for igual a zero. 6.4.2 Flags de Controle Existem 3 flags que podem ser setados pelos programas, alterando as operações do processador: Flag D (Direction): determina se as operações de string devem ser auto-decrementadas (D = l) ou incrementadas (D = 0). Em outras palavras, determina se as operações com strings vão incrementar ou decrementar os registradores de indexação (SI e DI). 8

Flag I (Interrupt Enable): caso a CPU esteja habilitada para receber instruções mascaráveis, então I = l. Caso contrário, I = 0 desabilita interrupções mascaráveis. Flag T (Trap): utilizado para depuração de programa. Se T = 1, o processador executará as instruções passo a passo. 7. INSTRUÇÕES DO MICROPROCESSADOR Para que um programa possa ser executado por um computador, ele precisa ser constituído de uma série de instruções de máquina e estar armazenado em células sucessivas na memória principal. A CPU é responsável pela execução das instruções que estão na memória. Quem executa um programa é o hardware e o que ele espera encontrar é um programa em linguagem de máquina (uma seqüência de instruções de máquina em código binário). A linguagem de máquina é composta de códigos binários, representando instruções, endereços e dados e está totalmente vinculada ao conjunto de instruções do microprocessador. Um ser humano usa seu conhecimento e inteligência para traduzir uma tarefa complexa (tal como, por exemplo, a tarefa de buscar uma pasta em um arquivo) em uma série de passos elementares (identificar o móvel e gaveta onde está a pasta, andar até o móvel, abrir a gaveta. encontrar a pasta, retirar a pasta e fechar a gaveta). Para o computador, uma instrução precisa ser detalhada, dividida em pequenas etapas de operações, que são dependentes do conjunto de instruções do microprocessador e individualmente executáveis. 7.1 Conjunto de Instruções A tabela 2 apresenta um conjunto das principais instruções utilizadas nos experimentos de laboratório. Para maiores detalhes consulte livros específicos indicados na bibliografia. Tabela 2 Conjunto de Instruções do 8086/88. INSTRUÇÃO OPERAÇÃO FLAGS AAA Ascii Adjust for Addition (Ajuste Ascii para Adição): Altera o conteúdo de Aft: A, CXXX AL para um decimal válido. Ind: P, S, Z, O AAS Ascii Adjust for Subtraction (Ajuste Ascii para Subtração): Corrige o Aft: A, C resultado de uma subtração de decimais em AL. Ind: P, S, Z, O ADC destino, Add with Carry (Adição com Carry): Soma dois operandos binários e põe o Aft: A, C, O, P, resultado no destino. Se C estiver setado, soma 1 ao resultado. S, Z ADD destino, Arithmetic Addition (Soma Aritmética): Soma e destino, repondo o Aft: A, C, O, P, valor original do destino. Ambos os operandos são binários. S, Z AND destino, Logical And (E Lógico): Faz um E Lógico entre os dois operandos, Aft: C,O,P,S,Z substituindo o destino com o resultado. Ind: A Procedure Call (Procedimento de Chamada): Põe o Ponteiro de Instrução (e o AAAXXXXX CALL destino Segmento de Código para chamadas do tipo far) na pilha e carrega o Ponteiro de Instrução com o endereço do nome do procedimento. O código continua com a execução em CS:IP. CLC Clear Carry (Limpa Carry): Limpa (zera) o Flag Carry. Aft: C Clear Direction Flag (Limpa o Flag de Direção): Limpa (zera) o Flag de CLD Direção levando instruções de string a incrementar os índices dos Aft: D registradores SI e DI. CMP destino, DAA Compare (Compara): Subtrai a do destino, atualiza os flags mas não guarda o resultado (não altera os valores de destino e ). Decimal Adjust for Addition (Ajuste Decimal para Adição): Corrige o resultado (em AL) de uma operação BCD de adição prévia. O conteúdo de AL é modificado para um par de dígitos decimais. Aft: A, C, O, P S, Z Aft: A,C,P,S,Z Ind: O 9

DAS Decimal Adjust for Subtraction (Ajuste Decimal para Subtração): Corrige o resultado (em AL) de uma operação BCD de subtração prévia. O conteúdo de AL é modificado para um par de dígitos decimais. Aft: A,C,P,S,Z DEC destino Decrement (Decrementa): Subtração binária sem sinal de um (1) do destino. Aft: A,O,P,S,Z Divide: Divisão sem sinal do acumulador pela. Se o divisor for DIV um valor byte, então BL é dividido pela e o quociente é colocado em Ind: A, C, O, BL e o resto em BH. Se o operando for um valor word, então DX:AX é P, S, Z dividido pela e o quociente é colocado em BX e o resto em DX. INC destino INT valor Increment (Incremento): adiciona um (1) ao operando binário sem sinal destino. Interrupt (Interrupção): inicia uma interrupção por software colocando (push) os flags na pilha, limpando a Trap e os flags de Interrupção, pondo (push) CS seguido do IP na pilha e carregando CS:IP com os valores encontrados na tabela de vetores de interrupção. A execução começa no ponto endereçado pelo novo CS:IP. Aft: A, O, P, S, Z Aft: I, T Jxx TODOS OS SALTOS (JUMPS) CONDICIONAIS (ver tabela 3) JCXZ label Jump if Register CX is Zero (Salte se o Registrador CX for Zero): desvia a execução para label se CX for zero. Usa uma comparação sem sinal. Obs: label é o endereço da instrução a ser executada. JMP label LOOP label LOOPE label LOOPZ label LOOPNZ label LOOPNE label MOV destino, MOVS destino, MOVSB MOVSW MOVSD MUL NEG destino Uncoditional Jump (Salto Incondicional): transfere o controle para label incondicionalmente. Os saltos estão entre -32768 e 32767 bytes distantes da instrução seguinte ao salto. Saltos NEAR e SHORT provocam a atualização do IP, enquanto que saltos FAR provocam a atualização de CS e IP. Decrement CX and Loop if CX Not Zero (Decrementa CX e faz Loop se CX for Não Zero): decrementa CX em 1 e transfere o controle para label se CX não for zero. O operando label precisa estar a -128 ou 127 bytes da instrução que segue a instrução de loop. Loop While Equal / Loop While Zero (Loop enquanto Igual / Loop enquanto Zero): decrementa CX em 1 (sem modificar flags) e transfere o controle para label se CX não for zero e o flag Zero estiver setado. O operando label precisa estar a -128 ou 127 bytes da instrução que segue a instrução de loop. Loop While Not Zero / Loop While Not Equal (Loop enquanto Não Zero / Loop enquanto Não Igual): decrementa CX em 1 (sem modificar flags) e transfere o controle para label se CX não for zero e o flag Zero estiver resetado (zerado). O operando label precisa estar a -128 ou 127 bytes da instrução que segue a instrução de loop. Move Byte or Word (Move Byte ou Word): copia um byte ou word do operando para o operando destino. Se o destino é SS, as interrupções são desabilitadas, exceto nas CPUs 808x mais antigas e com bug. Algumas CPUs desabilitam as interrupções se o destino for um dos registradores de segmento. Não copia byte ou word de memória para memória. Move String - Byte or Word (Move String - Byte ou Word): copia dados endereçados por DS:SI (mesmo que um operando seja fornecido) para a localização ES:DI e atualiza SI e DI baseado no tamanho do operando ou da instrução usada. Se o flag de direção estiver resetado (zerado), SI e DI são incrementados, se estiver setado, SI e DI são decrementados. Use com REP. Unsigned Multiply (Multiplicação sem Sinal): multiplicação sem sinal do acumulador pela. Se a for um valor byte, então AL é usado como o outro multiplicando e o resultado é colocado em AX. Se a for um valor word, então AX é multiplicado pela e EX:AX recebe o resultado. Two's Complement Negation (Negação com Complemento de 2): subtrai o destino de 0 (zero) e salva o complemento de 2 no próprio destino. Aft: C, O Ind: A, P, S, Z Aft: A, C, O, P, S, Z 10

NOP NOT destino OR destino, POP destino POPF PUSH PUSHF RCL destino, vezes RCR destino, vezes ROL destino, vezes ROR destino, vezes SAR destino, vezes SBB destino, SHL destino, vezes SHR destino, vezes SUB destino, TEST destino XCHG destino, XOR destino, No Operation (Nenhuma Operação): esta é uma instrução de fazer nada. Resulta na ocupação tanto de espaço quanto de tempo e é muito útil para fazer patches em segmentos de código. One's Complement Negation - Logical NOT (Negação com Complemento de 1 - NÃO Lógico): Inverte os bits do operando destino formando seu complemento de 1. Inclusive Logical OR (OU Inclusive Lógico): OU Inclusive Lógico dos dois operandos, retornando o resultado no destino. Todos os bits ativos em qualquer dos operandos estará ativo no resultado. Pop Word off Stack (Tire Word da Pilha): transfere o word do topo da pilha (SS:SP) para destino e incrementa SP em 2 para indicar o novo topo de pilha. Pop Flags off Stack (Tire os Flags da Pilha): tira word da pilha e os transfere para os registradores de flags. Depois incrementa SP em 2. Push Word onto Stack (Ponha Word na Pilha): decrementa SP pelo tamanho do operando (dois, ou quatro, valores byte são estendidos por sinal) e transfere um word da para o topo da pilha (SS:SP) Push Flags onto Stack (Ponha os Flags na Pilha): transfere os registradores de flags para a pilha. PUSHF guarda um valor de 16 bits. Rotate Through Carry Left (Rolar através do Carry para a Esquerda): Rola os bits do destino para a esquerda as vezes indicadas com todos os dados que vazarem pela esquerda re-entrando pela direita. O flag de carry conterá o valor do último bit rolado. Rotate Through Carry Right (Rolar através do Carry para a Direita): Rola os bits do destino para a direita as vezes indicadas com todos os dados que vazarem pela direita re-entrando pela esquerda. O flag de carry conterá o valor do último bit rolado. Rotate Left (Rotação para a Esquerda): Rola os bits do destino para a esquerda as vezes indicadas com todos os dados que vazarem pela esquerda re-entrando pela direita. O flag C conterá o último bit rolado. Rotate Right (Rotação para a Direita): Rola os bits do destino para a direita as vezes indicadas com todos os dados que vazarem pela direita re-entrando pela esquerda. O flag de carry conterá o valor do último bit rolado. Shift Arithmetic Right (Deslocamento Aritmético para a Direita): Desloca os bits do destino para a direita as vezes indicadas com o bit de sinal replicado no último bit. O flag de carry conterá o valor do último bit deslocado. Subtract with Borrow (Subtração com Empréstimo): Subtrai a do destino, além de subtrair 1 se o flag de carry estiver setado. O resultado é armazenado no destino. Shift Logical Left (Deslocamento Lógico para a Esquerda): Desloca os bits do destino para a esquerda as vezes indicadas com zeros colocados à direita. O flag de carry conterá o valor do último bit deslocado. Shift Logical Right (Deslocamento Lógico para a Diretita): Desloca os bits do destino para a direita as vezes indicadas com zeros colocados à esquerda. O flag de carry conterá o valor do último bit deslocado. Subtraction (Subtração): Subtrai a do destino e o resultado é armazenado em destino. Test (Testar): Faz um AND lógico entre os operandos, atualizando os flags e sem armazenar o resultado. Exchange (Troca): Troca o destino pela e vice-versa. Fonte e destino podem ser dois registradores ou um registrador e uma posição de memória. Exclusive Or (OU Exclusivo): faz um OU Exclusivo entre os operandos e retorna o resultado no destino. Aft: C,O,P,S,Z Ind: A todos são afetados Aft: C, O Aft: C, O Aft: C, O Aft: C, O Aft: C, O, P, S, Z Ind: A Aft: A, C, O, P, S, Z Aft: C,O,P,S,Z Ind: A Aft: C,O,P,S,Z Ind: A Aft: A, C, O, P, S, Z Aft: C,O,P,S,Z Ind: A XCHGpdestino, Aft: C,O,P,S,Z Ind: A 11

Obs: Aft significa Afetado. Indica quais flags são afetados depois de executada determinada instrução. Ind significa Indefinido. Indica quais flags são setados indefinidamente (aleatoriamente). A tabela 3 mostra instruções de quebra ou mudança de seqüência do tipo Jxx. Tabela 3 Conjunto de Instruções de Transferência Condicional. Mnemônico Significado Condição de Salto JA Salte se Acima (Jump if Above) C = 0 e Z = 0 JAE Salte se Acima ou Igual (Jump if Above or Equal) C = 0 JB Salte se Abaixo (Jump if Below) C = 1 JBE Salte se Abaixo ou Igual (Jump if Below or Equal) C = 1 ou Z = 1 JC Salte se Carry (Jump if Carry) C = 1 JCXZ Salte se CX for Zero (Jump if CX Zero) CX = 0 JE Salte se Igual (Jump if Equal) Z = 1 JG Salte se Maior (Jump if Greater) (COM SINAL) Z = 0 e S = O JGE Salte se Maior ou Igual (Jump if Greater or Equal) (COM SINAL) S = O JL Salte se Menor (Jump if Less) (COM SINAL) S <> O JLE Salte se Menor ou Igual (Jump if Less or Equal) (COM SINAL) Z = 1 ou S <> O JMP Salto Incondicional (Unconditional Jump) JNA Salte se Não Acima (Jump if Not Above) C = 1 ou Z = 1 JNAE Salte se Não Acima ou Igual (Jump if Not Above or Equal) C = 1 JNB Salte se Não Abaixo (Jump if Not Below) C = 0 JNBE Salte se Não Abaixo ou Igual (Jump if Not Below or Equal) C = 0 e Z = 0 JNC Salte se Não Carry (Jump if Not Carry) C = 0 JNE Salte se Não Igual (Jump if Not Equal) Z = 0 JNG Salte se Não Maior (Jump if Not Greater) (COM SINAL) Z = 1 ou S <> O JNGE Salte se Não Maior ou Igual (Jump if Not Greater or Equal) (COM SINAL) S <> O JNL Salte se Não Menor (Jump if Not Less) (COM SINAL) S = O JNLE Salte se Não Menor ou Igual (Jump Not Less or Equal) (COM SINAL) Z = 0 e S = O JNO Salte se Não Overflow (Jump if Not Overflow) (COM SINAL) O = 0 JNP Salte se Não Paridade (Jump if Not Parity) P = 0 JNS Salte se Não Sinal (Jump if Not Signed) (COM SINAL) S = 0 JNZ Salte se Não Zero (Jump if Not Zero) Z = 0 JO Salte se Overflow (Jump if Overflow) (COM SINAL) O = 1 JP Salte se Paridade (Jump if Parity) P = 1 Uma vez apresentadas as diversas instruções reconhecidas pelo microprocessador 8086/88 da Intel, será exemplificado abaixo um pequeno programa feito no SID utilizando estas instruções, e entendendo passo a passo o que o programa faz. ENDEREÇO MNEMÔNICOS COMENTÁRIOS 0000 SUB AX, AX Faz AX = 0 0002 ADD AX, [BX] Adiciona uma Word apontada por BX em AX 0004 ADD BX, 2 Adiciona 2 à BX 0007 CMP DX, BX Compara DX com BX 0009 JNS 0002 Se DX BX salta para o endereço 0002 000B INT 3 Finaliza o programa A programação em assembly é feita através de mnemônicos, que são, posteriormente, convertidos em opcodes pelo montador, que é a linguagem de máquina entendida pelo processador. 12

8. INTERRUPÇÕES Uma das coisas essenciais que tornam um computador diferente de qualquer outro tipo de máquina feita pelo homem é sua capacidade de responder a uma imprevisível variedade de trabalhos. O recurso de interrupção permite ao computador suspender o que estiver fazendo e passar a fazer outra coisa em resposta a uma interrupção (por exemplo, pressionar uma tecla no teclado). Os processos de interrupções permitem este tipo de resposta imediata sem ter que desperdiçar tempo de CPU e códigos de programa, verificando todas as possíveis tarefas paralelas que precisem ser realizadas em um determinado momento. 8.1 Interrupções por Hardware Interno Interrupções internas são geradas por certos eventos que ocorrem durante a execução de um programa. Estes tipos de interrupções são gerenciados, na sua totalidade, pelo hardware e não é possível modificá-las. Um exemplo claro deste tipo de interrupção é a que atualiza o contador do clock interno do computador, o hardware chama esta interrupção muitas vezes durante um segundo. Não é permitido ao programador gerenciar diretamente esta interrupção, uma vez que não se pode controlar a hora atualizada por software. Mas o programador pode usar seus efeitos no computador para o seu benefício, por exemplo para criar um virtual clock atualizado continuamente pelo contador interno de clock. Para tanto, é necessário apenas ler o valor atual do contador e o transformar num formato compreensível pelo usuário. 8.2 Interrupções por Hardware Externo Interrupções externas são geradas através de dispositivos periféricos, tais como teclados, impressoras, placas de comunicação, entre outros. São também geradas por co-processadores. Não é possível desativar interrupções externas. Estas interrupções não são enviadas diretamente para a CPU, mas, de uma forma melhor, são enviadas para um circuito integrado cuja função exclusiva é manusear este tipo de interrupção. O circuito, chamado PIC8259A, é controlado pela CPU através de uma série de comunicação chamada paths. 8.3 Interrupções por Software Interrupções por software podem ser ativadas diretamente por programas assembly, invocando o número da interrupção desejada com a instrução INT. O uso das interrupções facilita bastante a criação dos programas, tornando-os menores. Além disso, é fácil compreendê-las e geram boa performance. Estes tipos de interrupções podem ser separados em duas categorias: Interrupções do Sistema Operacional DOS e interrupções do BIOS. A diferença entre ambas é que as interrupções do sistema operacional são mais fáceis de usar, mas também são mais lentas, uma vez que acessam os serviços do BIOS. Por outro lado, interrupções do BIOS são muito mais rápidas, mas possuem a desvantagem de serem parte do hardware, o que significa serem específicas à arquitetura do computador em questão. A escolha sobre qual o tipo de interrupção usar irá depender somente das características que deseja dar ao seu programa: velocidade (use BIOS), portabilidade (use DOS). 8.4 Principais Interrupções BIOS: Interrupção 16h serviço 0 MOV AH, 0 INT 16H 13

função: leitura do teclado sem ecoar na tela. Na saída, AL contém o código do caractere que foi digitado. Se AL = 0 então foi pressionada uma tecla especial cujo código estará em AH = SCAN CODE. Interrupção 10h serviço 2 MOV AH, 2 MOV DH, linha MOV DL, coluna MOV BH, 0 ; pagina de video. INT 10H função: posiciona o cursor. Interrupção 10h serviço 6 MOV AH, 6 MOV AL, numero de linhas a rolar MOV CH, linha superior esquerdo MOV CL, coluna superior esquerdo MOV DH, linha inferior direito MOV DL, coluna inferior direito MOV BH, atributo INT 10H função: limpa a tela. DOS: Interrupção 21h serviço 1 MOV AH, 1 INT 21H função: leitura do teclado com eco na tela. O caractere lido está em AL, se AL = 0, deve repetir a leitura (tecla especial). Interrupção 21h serviço 9 MOV AH, 9 MOV DX, offset string INT 21H função: imprime na tela uma string que inicia no endereço apontado por DX e vai até encontrar um "$". Interrupção 21h serviço 2 MOV AH, 2 INT 21H função: escreve o caractere que está em DL na tela. 9. BIBLIOGRAFIA 1. Lance A. Leventhal - 8080/8085 Assembly Language Programming, Osborne/McGraw-Hill, Berkeley, California, 1979. 2. Lance A. Leventhal and Winthrop Saville - 8080/8085 Assembly Language Subroutines, Osborne/McGraw-Hill, Berkeley, California, 1983. 3. Antonio C. J. F. Visconti - Microprocessadores 8080 e 8085 : Software, Livros Érica Editora Ltda., Vol. 2, São Paulo, 1983. 4. Intel Corporation - MCS-85 User's Manual, 1981. 5. Intel Corporation - 8080/8085 Assembly Language Programming Manual, 1981. 14