Buscar

LINGUAGEM ASSEMBLY

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 3, do total de 52 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 6, do total de 52 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 9, do total de 52 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Prévia do material em texto

Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 1 
 
 
Linguagem ASSEMBLY da Família INTEL 
 
1 Introdução 
Este texto apresenta uma descrição da linguagem de montagem do 
microprocessador 8086/88. 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/88 
 
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/88. Como resultado, mesmo os atuais membros da 
família Pentium ainda executam código escrito para os fundadores desta dinastia de 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 2 
processadores Intel. Levando ainda em conta a simplicidade da arquitetura do 
8086/88 é 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, SS. 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 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
 
Figura 2: Registrador de Estado do 8086/8088 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 3 
♦ 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 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 4 
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 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. 
 A Figura 3 ilustra as duas convenções para armazenar o valor 3456H. 
Deve-se ainda acrescentar que nos processadores Intel o endereço de umapalavra 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. 
 
 endereço conteúdo endereço conteúdo 
 A A 
 A+1 A+1 
 
 “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. 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 5 
 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. 
 
3.2.1 Algumas Diretivas 
 
 A relação de diretivas apresentada nesta seção é apenas adequada aos 
objetivos deste curso sem ser completa. Outras diretivas serão apresentadas nas 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 6 
aulas de laboratório. 
 
3.2.1.1 Constantes 
 
 Constantes numéricas podem ser apresentadas em binário, decimal, octal e 
hexadecimal. A base utilizada deve ser indicada pelo programador colocando à 
esquerda do numeral, respectivamente as letras B, D, Q e H. Quando nenhuma 
letra for indicada o montador assume que se trata da base decimal. 
 Muitos montadores exigem que o primeiro dígito de um número em base 
hexadecimal seja um numeral. Na prática isso significa que os números 
hexadecimais que iniciam com A, B, C, D, E ou F, devem ser digitados tendo um 0 
(zero) na frente. 
 Todas as constantes devem ser inteiras representáveis em 16 bits, incluindo 
sinal. Números negativos são representados em complemento de dois. 
 Caracteres são apresentados entre apóstrofes e podem aparecer em cadeias 
de até 255 caracteres, quando utilizadas para iniciar posições de memória. Quando 
utilizadas como operandos imediatos, caracteres podem ter no máximo dois bytes. 
A diretiva EQU é utilizada para associar um símbolo a uma constante. 
 O uso de constantes é ilustrado a seguir. 
 
MOV STRING[SI],’A ; caracter 
MOV STRING[SI], 41h ; equivalente em hexadecimal 
ADD AX, 0C4H ; constantes hexa iniciam com numeral 
OCTAL_8 EQU 10Q ; 8 em octal 
OCTAL_9 EQU 11Q ; binário 
UMS EQU 11111111B ; 9 em octal 
MENOS_5 EQU -5 ; decimal (default) 
MENOS_8 EQU -6D 
 ; ‘D’ indica que é decimal 
 
 
3.2.1.2 Definição de Dados 
 A maioria dos programas iniciam difinindo as variáveis com que eles vão 
trabalhar. Três diretivas, DB, DW e DD são usadas para alocar e dar nome a 
posições de memória. São usadas para definir variáveis em três unidades: DB 
significa “define byte”, DW significa “define word” e DD significa “define doubleword”. 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 7 
 Os operandos destas diretivas indicam ao montador quantas unidades de 
armazenamento alocar - respectivamente 1, 2 e 4 bytes - e qual o valor inicial, se 
houver. Os exemplos abaixo esclarecem como utilizar estas diretivas: 
ALFA DB ? ; não inicializada 
BETA DW ? ; não inicializada 
GAMA DD ? ; não inicializada 
UPSILON DW 5 ; constante 05H 
IOTA DB ‘HELLO’ ; contém 48 45 4C 4C 4F H 
MU DD 100 DUP 0 ; aloca e inicializa 100 bytes com 0 (zero) 
 Para cada variável num programa ASM86, o montador registra a informação 
do tipo, ou seja, do número de bytes alocados a ela. Quando uma variável é 
referenciada no programa, o montador utiliza esta informação para determinar a 
forma da instrução de máquina que deve ser gerada. 
 Se o uso da variável conflita com o seu atributo, o montador gera uma 
mensagem de erro. Há casos em que o programador deve indicar explicitamente ao 
montador qual é o tipo do operando. Por exemplo, a instrução: 
MOV [BX],5 
escreve o valor 5 na posição de memória, cujo endereço está definido pelo 
conteúdo do registrador BX. Esta instrução não identifica o tipo da variável, se é um 
byte, uma palavra ou uma palavra dupla. Note, que dependendo do tipo da variável, 
a execução desta instrução envolverá a modificação de 1, 2 ou 4 bytes da memória. 
A informação do tipo de variável pode ser fornecido através das diretivas: byte ptr, 
word ptr, dword ptr, como nos exemplos a seguir 
MOV word ptr [BX],5 ; indica que é palavra 
SUB byte ptr [BX][SI],1 ; indica que é byte 
ANA BETA,32H ; implícito que é palavra 
CMP byte ptr ALFA[SI], 10 ; indica que é byte (redundante) 
DEC byte ptr GAMA ; indica que é byte apesar da definição 
 
 A primeira e segunda linhas do exemplo esclarecem que o primeiro operando 
da instrução é um byte. Na terceira linha não é necessário utilizar estas diretivas, 
pois o montador assume o tipo indicado quando da definição da variável, neste 
caso, uma palavra (vide exemplo anterior). Na quarta linha o uso da diretiva é 
redundante e, portanto desnecessário, por que a variável já havia sido definida (vide 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 8 
exemplo anterior), como byte. A última linha tem um aspecto interessante. Embora a 
variável GAMA tenha sido definida como palavra dupla, a instrução decrementa 
apenas o byte apontado pelo endereço GAMA, sem alterar os demais 3 bytes da 
palavra dupla. 
 A diretiva TYPE identifica a unidade de alocaçãode memória (1 = byte; 2 = 
palavra, 4 = palavra dupla). 
 A linguagem provê duas diretivas: LENGHT e SIZE, que podem ser escrito 
nas instruções com informações de atributo. LENGHT faz o montador retornar com 
o número de unidades de armazenamento (bytes, palavras ou palavras duplas) 
ocupadas por um vetor. SIZE leva o montador a retornar o número de bytes 
ocupados pela variável ou vetor. 
Estas diretivas permitem que se escrevam seqüências de instruções que não 
precisam ser mudadas (somente montadas novamente), se os atributos das 
variáveis mudarem, por exemplo, um vetor de bytes muda para um vetor de 
palavras. 
O exemplo a seguir ilustra uma aplicação típica destas diretivas. 
 
; soma do conteúdo de uma tabela em AX 
; observe que a mesma instrução funciona para 
; TABELA DB 50 DUP(?) 
; TABELA DD 50 DUP(?) 
 SUB AX,AX ; zera contador 
 MOV CX, LENGHT TABELA ; número de iterações 
 MOV SI, SIZE TABELA ; aponta p/ o fim do vetor 
SOMA_OUTRO: 
 SUB SI, TYPE TABELA ; pega elemento anterior 
 ADD AX, TABELA [SI] ; soma um elemento 
; AX contém a soma 
 
 Existe também a diretiva OFFSET. Basta por enquanto considerar que esta 
diretiva retorna o próprio endereço da variável referenciada no programa logo em 
seguida a esta diretiva. 
 Do mesmo modo, algumas outras diretivas relacionadas com o mecanismo de 
segmentação do processador, não serão apresentadas aqui. Embora todo programa 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 9 
deva contê-las para que o montador funcione corretamente, este texto limita-se a 
mencioná-las sem discutir em detalhes o seu papel. 
 
3.2.1.3 Início e Final de Subrotinas 
 Em ASM86 uma subrotina (rotina) é ativada através da instrução CALL, como 
se verá adiante. O código da subrotina termina necessariamente com a instrução 
RET, que desvia o fluxo controle para a instrução seguinte ao CALL. As instruções 
de uma rotina são emolduradas pelas diretivas PROC e ENDP, como no exemplo a 
seguir: 
HISTOGRAMA PROC FAR 
 ; Esta rotina assume que o parâmetro de entrada está em AL, 
 ; e incrementa um contador numa tabela de frequência, 
 ; baseada no valor do parâmetro de entrada. 
 XOR AH,AH ; zera o byte mais significativo de AX 
 MOV SI,AX ; índice para a tabela 
 INC FREQ[SI] ; incrementa o contador 
 RET 
HISTOGRAMA ENDP 
 O uso da diretiva NEAR/FAR será esclarecido posteriormente. 
 
3.3 Modos de Endereçamento 
 O processador 8086 dispõe de várias formas de referenciar os operandos das 
instruções. Os operandos podem estar em registradores, dentro da própria 
instrução, na memória ou em portas de E/S. Além disso, o endereço de memória e 
de portas de E/S, podem ser calculados de várias maneiras. Estes modos de 
endereçamento conferem flexibilidade ao conjunto de instruções do processador. 
Esta seção apresenta uma breve descrição dos modos de endereçamento 
disponíveis neste processador. 
 
3.3.1 Registrador 
 Neste modo de endereçamento, o operando está contido num dos 
registradores internos da máquina. Estas instruções são muito compactas pois o 
“endereço” do registrador está codificado em “uns poucos bits”. O acesso a este 
operando é realizado inteiramente dentro do próprio processador, e não envolve 
acesso externo à memória. Exemplos: 
 
 MOV AL,BL 
 SUB CX,DX 
 DEC CL 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 10 
3.3.2 Imediato 
 O operando está contido na própria instrução. Este operando pode ter 8 ou 16 
bits. Exemplos: 
 SUB CL,2 
 ADD DX,MENOS_5 
 Note nos exemplos que as instruções utilizam também o modo de 
endereçamento registrador. De um modo geral, uma mesma instrução pode usar 
modos de endereçamento diferentes para cada um dos seus operandos. No caso 
deste processador cada instrução pode ter no máximo dois operandos. Cada 
operando pode ser referenciado usando um modo de endereçamento distinto. 
 Quando o operando está na memória, o processador calcula o endereço da 
posição correspondente das formas que serão explicitadas a seguir. Este endereço 
é chamado de endereço efetivo (effective address - EA). 
 Na realidade o endereço efetivo não é propriamente o endereço do operando, 
mas a distância entre o endereço da posição de memória e um certo endereço de 
referência chamado endereço de início de segmento. Por enquanto convém admitir 
que o endereço efetivo é o próprio endereço do operando. Maiores esclarecimentos 
serão dados em seções posteriores.1 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Figura 4: Ilustração do modo de endereçamento direto 
 
Nos modos de endereçamento que serão apresentados a seguir, o endereço 
efetivo será dado pela soma de até três componentes: base (fornecida por um dos 
registradores de base - BX ou BP), índice (fornecido pelo conteúdo de um dos 
registradores de índice - SI ou DI) e um deslocamento (contido na própria instrução). 
O que caracteriza cada um dos modos de endereçamento a seguir é qual ou quais 
destes três componentes estarão presentes na soma. 
 
1 Na realidade o endereço efetivo não é propriamente o endereço do operando, mas a distância 
deste a um certo endereço de referência, chamado endereço de início de segmento. 
opcode mod reg r/m camento desloc
Endereço 
Efetivo 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 11 
3.3.3 Direto 
 Trata-se do modo de endereçamento de memória mais simples. Não envolve 
nenhum registrador. O endereço efetivo é tomado diretamente do deslocamento 
contido na própria instrução. Este modo de endereçamento é tipicamente utilizado 
para referenciar escalares. A Figura 4 ilustra o formato destas instruções. 
 Alguns exemplos: 
 MOV AX,[8000H] 
 SUB CX,BETA 
 DEC byte ptr GAMA 
3.3.4 Registrador Indireto 
 O endereço do operando pode ser tirado de um dos registradores de base 
(BX ou BP) ou índice (SI ou DI), como mostra a Figura 5. Qual destes registradores 
é usado está definido num dos campos da instrução. 
 
 
 
 
 
 
 
 
 
 
 
 
 
Figura 5: Ilustração do modo de endereçamento registrador indireto. 
 
 Somente um registrador de base ou de índice pode estar presente neste 
modo de endereçamento. Os registradores de 8 bits, assim como AX, DX, CX, SP, 
além dos registradores de segmento (CS, DS, ES, SS) são proibidos aqui, a menos 
de raras exceções. Exemplos: 
 MOV AL,[BX] 
 SUB [SI],DX 
 Convém, contudo, notar que qualquer registrador de uso geral pode ser 
utilizado neste modo de endereçamento nas instruções do tipo JMP e CALL. 
Exemplos destes casos são: 
 
 JMP [AX] 
 CALL [DX] 
opcode mod reg r/m
Endereço 
Efetivo 
BX ou BP
ou 
SI ou DI 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 12 
3.3.5 Relativo a uma Base 
 Neste modo de endereçamento, o endereço efetivo é dado pela soma de um 
deslocamento (definido na própria instrução) e pelo conteúdo de um registrador de 
base, mais especificamente, do registrador BX ou do registrador BP. 
 
 
 
 
 
 
 
 
 
 
 
Figura 6: Ilustração do modo de endereçamento com base. 
 
 Este modo de endereçamento é freqüentemente utilizado para 
referenciar estruturas que podem estar armazenadas em endereços diferentes na 
memória. Antes da instrução que referencia o dado propriamente dita normalmente 
se introduzem instruções que carregam no registrador de base o endereço inicial da 
estrutura. O elemento da estrutura é indicado pelo deslocamento. Cópias diferentes 
deuma mesma estrutura podem ser referenciadas simplesmente mudando o 
conteúdo do registrador de base. 
Abaixo são dados alguns exemplos deste modo de endereçamento. 
 MOV AL,[BX+0B000H] 
 SUB CL,MU[BX] 
 ADD dword ptr [BP][1000H], 43H 
3.3.6 Indexado 
 No modo de endereçamento indexado o endereço efetivo é calculado a partir 
da soma de um deslocamento mais o conteúdo de um registrador de índice (SI ou 
DI, conforme definido no campo mod_reg_r/m), como mostra a Figura 7. Este modo 
de endereçamento é freqüentemente utilizado para referenciar elementos de um 
vetor: o deslocamento apontando para o início do vetor e o valor do registrador de 
índice selecionando um dos seus elementos. Como todos os elementos de um vetor 
têm o mesmo comprimento, uma aritmética simples com o registrador de índice 
selecionará qualquer elemento. 
opcode mod reg r/m camento desloc
Endereço 
Efetivo 
 
BX ou BP 
 +
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 13 
 
 
 
 
 
 
 
 
 
 
Figura 7: Ilustração do modo de endereçamento Indexado. 
 
 Abaixo são dados alguns exemplos deste modo de endereçamento. 
 MOV AL,[SI+0B000H] 
 SUB CL,MU[SI] 
 ADD word ptr [DI][1000H], 43H 
3.3.7 Indexado com Base 
 O modo de endereçamento indexado com base gera o endereço efetivo 
somando o conteúdo de um registrador de base (BP ou BX), o conteúdo de um 
registrador de índice (SI ou DI) e um deslocamento, como mostra a figura 8. É 
importante salientar aqui que neste modo de endereçamento está presente um 
registrador de base e um registrador de índice. Qualquer outra combinação de 
registradores é inválida. Este modo é freqüentemente utilizado para referenciar 
vetores localizados na pilha, como será discutido adiante. Novamente neste caso o 
campo mod_reg_r/m da instrução define quais os registradores participam do 
cálculo do endereço efetivo. 
 Abaixo são dados alguns exemplos deste modo de endereçamento. 
 MOV AL,[BX+SI+ 5H] 
 ADD [BP][DI][1000H], AX 
 
 
 
 
 
 
 
 
 
opcode mod reg r/m camento desloc
Endereço 
Efetivo 
 
SI ou DI 
 +
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 14 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Figura 8: Ilustração do modo de endereçamento indexado com base. 
 
3.4 Conjunto de Instruções do 8086/8088 
 A apresentação que se segue não contém todos os detalhes de cada instrução. 
Ela se propõe a ser um esquema a ser seguido em aula e ao mesmo tempo um 
resumo do assunto. 
 É importante ter em mente que todas estas instruções estão presentes no 
conjunto de instruções dos demais processadores da família 80X86, de tal sorte que o 
conhecimento aqui adquirido pode ser utilizado na programação de sistemas mais 
modernos. 
3.4.1 Convenções 
 Na apresentação a seguir adota-se a seguinte convenção: 
d - uma quantidade de 8 ou 16 bits. 
d8 - uma quantidade de 8 bits. 
d16 - uma quantidade de 16 bits. 
r, r1, r2 - um registrador de 8 ou 16 bits de uso geral. 
r8 - um registrador de 8 bits. 
r16 - um registrador de 16 bits. 
( ) - o conteúdo de um registrador, ou posição de memória, 
 dependendo do que estiver entre os parênteses. 
m - endereço de um byte ou uma palavra na memória 
opcode mod reg r/m camento desloc
Endereço 
Efet-ivo 
 
BX ou BP
 +
 
SI ou DI 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 15 
m8 - endereço de um byte na memória 
m16 - endereço de uma palavra de 16 bits. 
m32 - endereço de uma palavra dupla de 32 bits. 
AX/AL - o registrador AX ou AL, dependendo do operando envolvido ser 
 de 16 ou 8 bits. 
alvo - a definição de um endereço na área de código da memória. 
flags - os 16 bits do registrador de estado. 
r1:r2 - indica um valor formado pela composição do conteúdo de r1 e r2. 
 Esta composição pode se dar pela concatenação dos dois valores 
 (p. ex. DX:AX) ou pelo modo próprio do microprocessador formar 
 o endereço (p. ex. CS:DX). 
 
 As convenções utilizadas na descrição que se segue, acabará se tornando 
clara na medida em que as instruções forem sendo apresentadas. Para cada tipo de 
instrução aparece do lado esquerdo uma descrição sintática e uma breve descrição 
semântica da instrução. Ao centro, são dados alguns exemplos, e do lado esquerdo o 
número de ciclos de relógio consumidos na execução da instrução. 
 
3.4.2 Instruções de Transferência de Dados 
 MOV r1,r2 MOV AL,CH 2 
 MOV CX,BP 
MOV r,m MOV AX,TEMP_RESULT 10/8+EA 
 MOV CL,ARRAY[SI], 
MOV m,r MOV COUNT[DI],CX 10/9+EA 
 MOV [SI+1000],DX 
MOV r,d MOV AX,99 4 4 
 MOV SI,61CH 
MOV m,d MOV byte ptr [SI], 0FH 10+EA 
 MOV word ptr [BX+1234],57 
XCHG r1,r2 XCHG AX,BX 3/4 
 XCHG CL,CH 
XCHG m,r XCHG SEMAFORO,AX 17+EA 
 XCHG AL,[BX+2] 
XLAT XLAT 11 
(AL) ← ((BX+AL)) 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 16 
LAHF LAHF 4 
 (AH7,6,4,2,0)← (SF,ZF,AF,PF,CF) 
SAHF SAHF 4 
(SF,ZF,AF,PF,CF) ←(AH7,6,4,2,0) 
3.4.3 Instruções de Manipulação de Cadeias de Caracteres (string) 
Cada uma das instruções deste grupo tem três formatos diferentes. Para o primeiro 
formato (terminado com um "S"), o montador entende que o string é de bytes ou de 
palavras. O segundo (terminado com um "SB") e terceiro (terminado com um "SW") 
indicam explicitamente que se trata respectivamente de um string de bytes e palavras. 
 
MOVS/MOVSB/MOVSW MOVSB 18 
 MOVSW 
 
CMPS/CMPSB/CMPSW CMPSB 22 
 CMPSW 
 
SCAS/SCASB/SCASW SCASB 15 
 SCASW 
 
LODS/LODSB/LODSW LODSB 12 
 LODSW 
 
STOS/STOSB/STOSW STOSB 11 
 STOSW 
 
REP REP MOVSB 9+17*rep 
REP REP LODSW 9+13*rep 
REP REP STOSW 9+10*rep 
REPZ/REPE REPZ CMPS 9+22*rep 
REPNZ/REPNE REPNZ SCAS 9+15*rep 
 Nas cinco últimas linhas da tabela contém prefixos usados para repetir a 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 17 
execução da instrução de manipulação de string escrita em seguida pelo número de 
vezes especificado em CX. Diante das instruções MOVS/MOVSB/MOVSW, 
LODS/LODSB/LODSW e STOS/STOSB/STOSW, pode-se usar o prefixo REP, que 
decrementa o registrador CX, sem afetar os flags, e repete a instrução de string, 
enquanto CX ≠ 0. Diante das instruções CMPS e SCAS, pode-se usar os prefixos 
REPZ(ou REPE) ou REPNZ(ou REPNE). REPZ decrementa CX, sem afetar os flags, 
e repete a instrução de string, enquanto CX ≠ 0 e ZF = 1. O prefixo REPNZ 
decrementa CX, sem afetar os flags, e provoca a repetição da instrução de string, 
enquanto CX ≠ 0 e ZF = 0. 
3.4.4 Instruções de Manipulação de Endereços 
LEA r16,m16 LEA BX,[BP][DI] 2+EA 
(r16) ← m16 
LDS r16,m32 LDS SI,DATA_SEG[DI] 16+EA 
(r16) ← (m32) 
(DS) ← (m32)+2 
LES r16,m32 LES SI,DATA_SEG[DI] 16+EA 
(r16) ← (m32) 
(ES) ← (m32)+2 
3.4.5 Instruções Aritméticas 
3.4.5.1 Adição 
ADD r1,r2 ADD AX,SI 3 
 ADD CL,DH 
ADD r,m ADD DL,[300] 9+EA 
 ADD CX,[BX+1234H] 
ADD m,r ADD byte ptr [300],DL 16+EA 
 ADD word ptr [SI+BX+2],AX 
ADD r,d ADD AL,4 4 
(r) ← (r) + d ADD AX,50 
ADD m,d ADD byte ptr [DI],54 17+EA 
(m) ← (m) + d ADD word ptr [BX+4],4FFH 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 18 
ADC r1,r2 ADCBX,DX 3 
 ADC DH,AL 
ADC r,m ADC BL,[456] 9+EA 
(r) ←(r) + (m) + (CF) ADC CX,word ptr [300H] 
ADC m,r ADC byte ptr [300],DL 16+EA 
(m) ←(m) + (r) + (CF) ADC word ptr [SI],BX 
ADC r,d ADC CL,24 4 
(r) ← (r) + d + (CF) ADC BX,50 
ADC m,d ADC byte ptr [DI],54 17+EA 
(m) ← (m) + d + (CF) ADC word ptr [BX+4],4FFH 
INC r INC AX 2 
(r) ←(r) + 1 INC CL 3 
INC m 15+EA 
(m) ←(m) + 1 INC word ptr [BX+100H] 
 
3.4.5.2 Subtração 
SUB r1,r2 SUB AX,SI 3 
 SUB CL,DH 
SUB r,m SUB DL,[300] 9+EA 
(r) ← (r) - (m) SUB CX,[BX+1234H] 
SUB m,r SUB byte ptr [300],DL 16+EA 
(m) ← (m) - (r) SUB word ptr [SI+BX+2],AX 
SUB r,d SUB AL,4 4 4 
(r) ← (r) - d SUB AX,50 
SUB m,d SUB byte ptr [DI],54 17+EA 
(m) ← (m) - d SUB word ptr [BX+4],4FFH 
SBB r1,r2 SBB BX,DX 3 
(r1) ←(r1) - (r2) - (CF) SBB DH,AL 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 19 
SBB r,m SBB BL,[456] 9+EA 
 SBB CX,word ptr [300H] 
SBB m,r SBB byte ptr [300],DL 16+EA 
(m) ←(m) - (r) - (CF) SBB word ptr [SI],BX 
SBB r,d SBB CL,24 4 
(r) ←(r) - d - (CF) SBB BX,50 
SBB m,d SBB byte ptr [DI],54 17+EA 
(m) ← (m) - d - (CF) SBB word ptr [BX+4],4FFH 
DEC r DEC AX 2 
(r) ←(r) - 1 DEC Cl 3 
DEC m DEC byte ptr [SI] 15+EA 
 DEC word ptr [BX+100H] 
NEG r NEG BX 3 
 NEG AL 
NEG m NEG byte ptr [BX+DI] 16+EA 
(m) ←0 - (m) NEG MULTIPLICADOR 
CMP r1,r2 CMP BX,CX 3 
 CMP AL.BL 
CMP r,m CMP DH, byte ptr ALPHA 9+EA 
(r) - (m) CMP CH,[SI+BX+10] 
CMP m,r CMP [BP+2],SI 9+EA 
(m) - (r) CMP [SI],AX 
CMP r,d CMP BL,02H 4 
(r) - d CMP DL,85H 
CMP m,d CMP RADAR[DI],3420H 10+EA 
(m) - d 
 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 20 
3.4.5.3 Multiplicação 
MUL r MUL BL 70-77 
 MUL CX 118-133 
 
 
MUL m MUL byte ptr MES[SI] (76-83)+EA
(AX) ← (AL) * (m8) MUL word ptr DIA[SI] (124-139)+EA 
(DX:AX) ← (AX) * (m16) MUL BAUD_RATE 
(sem sinal) 
IMUL r IMUL BL 80-98 
(AX) ← (AL) * (r8) IMUL CX 128-154 
(DX:AX) ← (AX) * r16) 
(com sinal) 
IMUL m IMUL byte ptr MES[SI] (86-104)+EA
(AX) ← (AL) * (m8) IMUL word ptr DIA[SI] (134-160)+EA 
(DX:AX) ← (AX) * (m16) 
(com sinal) 
3.4.5.4 Divisão 
DIV r8 DIV CL 80-90 
 
 
 
DIV r16 DIV DX 144-162 
 
 
(sem sinal) 
 
 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 21 
DIV m8 DIV byte ptr [SI] (88-96)+EA
 
 
(sem sinal) 
DIV m16 DIV word ptr [BX] (150-168)+EA 
(AX)←(DX:AX)/(m16) 
(DX)←(DX:AX)mod(m16) 
(sem sinal) 
IDIV r8 IDIV CL 101-112 
(AL)←(AX)/(r8) 
(AH)←(AX) mod (r8) 
(com sinal) 
IDIV r16 IDIV DX 165-184 
(AX)←(DX:AX)/(r16) 
(DX)←(DX:AX) mod (r16) 
(com sinal) 
IDIV m8 IDIV byte ptr [SI] (107-118)+EA 
(AL)←(AX)/(m8) 
(AH)←(AX) mod (m8) 
(com sinal) 
IDIV m16 IDIV word ptr [BX] (171-190)+EA 
(AX)←(DX:AX)/(m16) 
(DX)←(DX:AX)mod(m16) 
(com sinal) 
CBW CBW 2 
Se (AL)<0, 
então (AH) ←0FF 
 
caso contrário, (AH) ←00 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 22 
CWD CWD 5 
Se (AX)<0, então (DX) ← FFFFH 
caso contrário, (DX) ← 0 
3.4.5.5 nstruções de Ajuste 
 Estas instruções são utilizadas quando os dados manipulados pelo programa 
estão em formato ASCII ou BCD. Tendo em vista que estas são instruções de uso 
infreqüente, este trabalho limita-se a mencioná-las. São elas: 
 
AAA AAA 4 
DAA DAA 4 
AAS AAS 4 
DAS DAS 4 
AAM AAM 83 
AAD AAD 60 
 
3.4.6 Instruções Lógicas 
3.4.6.1 E 
AND r1,r2 AND AL,BL 3 
 AND CL,AH 
AND r,m AND DL,[SI+5] 9+EA 
 AND CX,FLAG_WORD 
AND m,r AND ASCII[DI],DL 16+EA 
(m) ← (m) • (r) AND word ptr [SI+BX+2],AX 
AND r,d AND AX,7F7FH 4 
(r) ← (r) • d AND CX,0F0H 
AND m,d AND BETA,01H 17+EA 
(m) ← (m) • d AND byte ptr [BX],6 
TEST r1,r2 TEST SI,DI 3 
 TEST CX,DX 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 23 
TEST r,m TEST SI,END_COUNT 9+EA 
 (r) • (m) TEST CX,[SI] 
TEST r,d TEST BX,0CC4H 4/5 
 (r) • d TEST AL,8 
TEST m,d TEST RETURN_CODE,01H 11+EA 
 (m) • d TEST byte ptr [DI],3 
 
3.4.6.2 OU 
OR r1,r2 OR AL,BL 3 
 OR CL,AH 
OR r,m OR DL,[SI+5] 9+EA 
 OR CX,FLAG_WORD 
OR m,r OR ASCII[DI],DL 16+EA 
(m) ← (m) + (r) OR word ptr [SI+BX+2],AX 
OR r,d OR AX,7F7FH 4 
(r) ← (r) + d OR CX,0F0H 
OR m,d OR BETA,01H 17+EA 
(m) ← (m) + d OR byte ptr [BX],6 
3.4.6.3 OU exclusivo 
XOR r1,r2 XOR AL,BL 3 
 XOR CL,AH 
XOR r,m XOR DL,[SI+5] 9+EA 
 XOR CX,FLAG_WORD 
XOR m,r XOR ASCII[DI],DL 16+EA 
(m) ← (m) ⊕ (r) XOR word ptr [SI+BX+2],AX 
XOR r,d XOR AX,7F7FH 4 
(r) ← (r) ⊕ d XOR CX,0F0H 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 24 
XOR m,d XOR BETA,01H 17+EA 
(m) ← (m) ⊕ d XOR byte ptr [BX],6 
3.4.6.4 Complemento 
NOT r NOT AX 3 
 NOT CL 
NOT m NOT byte ptr [BX] 16+EA 
(m)← not (m) NOT word ptr [BX+SI] 
3.4.6.5 Deslocamento 
SAL/SHL r,1 SAL AL,1 2 
SAL/SHL r,CL SHL DX,CL 8+4*(CL) 
SAL/SHL m,1 SAL word ptr [BX+2],1 15+EA 
SAL/SHL m,CL SHL STORE_COUNT,CL 20+EA+4*(CL)
 CF 
 
 
tantas vezes quantas forem definidas pelo 
segundo operando 
 
SHR r,1 SHR AL,1 2 
SHR r,CL SHR DX,CL 8+4*(CL) 
SHR m,1 SHR word ptr [BX+2],1 15+EA 
SHR m,CL SHR STORE_COUNT,CL 0+EA+4*(CL
) 
 CF 
 
 
tantas vezes quantas forem definidas pelo 
segundo operando 
 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 25 
 
SAR r,1 SAR AL,1 2 
SAR r,CL SAR DX,CL 8+4*(CL) 
SAR m,1 SAR word ptr [BX+2],1 15+EA 
SAR m,CL SAR STORE_COUNT,CL 20+EA+4*(CL)
 CF 
 
 
 
3.4.6.6 Rotação 
ROL r,1 ROL AL,1 2 
ROL r,CL ROL DX,CL 8+4*(CL) 
ROL m,1 ROL word ptr [BX+2],1 15+EA 
ROL m,CL ROL STORE_COUNT,CL 0+EA+4*(CL
) 
 CF 
 
 
tantas vezes quantas forem definidas pelo 
segundo operando 
 
ROR r,1 ROR AL,1 2 
ROR r,CL ROR DX,CL 8+4*(CL) 
ROR m,1 ROR word ptr [BX+2],1 15+EA 
ROR m,CL ROR STORE_COUNT,CL 20+EA+4*(CL)
 CF 
 
 
tantas vezes quantas forem definidas pelo 
segundo operando 
 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 26 
 
RCL r,1 RCL AL,1 2 
RCL r,CL RCL DX,CL 8+4*(CL) 
RCL m,1 RCL word ptr [BX+2],1 15+EA 
RCL m,CL RCL STORE_COUNT,CL 20+EA+4*(CL)
 CF 
 
 
tantas vezes quantas forem definidas pelo 
segundo operando 
 
RCR r,1 RCR AL,1 2 
RCR r,CL RCR DX,CL 8+4*(CL) 
RCR m,1 RCR word ptr [BX+2],1 15+EA 
RCR m,CL RCR STORE_COUNT,CL 20+EA+4*(CL)
 CF 
 
 
tantas vezes quantas forem definidas pelo 
segundo operando 
 
3.4.7 Instruções de Desvio 
3.4.7.1 Desvio incondicional 
 JMP CX 
(CS:IP) ← ‘alvo’ JMP dword ptr [SI] 
 CALL CX 
(CS:IP) ← ‘alvo’. 
O endereço de retorno é 
armazenado na pilha. 
CALL dword ptr [SI] 
 RET 
(CS:IP)←valor armazenado 
no topo da pilha 
 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/200727 
 
 RET 8 
(CS:IP)←valor armazenado 
no topo da pilha. 
 (SP)←(SP)+d16 
 
INT num_vetor INT 21H 51 
(esclarecido noutro capítulo) 
INTO INTO 53 ou 4 
(esclarecido noutro capítulo) 
IRET IRET 
(esclarecido noutro capítulo) 
 
3.4.7.2 Desvio condicional 
 
 instrução descrição da condição de desvio 
 JA / JNBE Jump if above/not below nor equal 
 JAE / JNB Jump if above or equal/not below 
 JB / JNAE Jump if below/not above 
 JBE / JNA Jump if below or equal / not above 
 JC Jump if carry 
 JE / JZ Jump if equal / zero 
 JG / JNLE Jump if greater / not less nor equal 
 JGE / JNL Jump if greater or equal / not less 
 JLE / JNG Jump if less or equal/ not greather 
 JNC Jump if not carry 
 JNE / JNZ Jump if not equal / not zero 
 JNO Jump if not overflow 
 JNP / JPO Jump if not parit / parity odd 
 JNS Jump if not sign 
 JO Jump if overflow 
 JP / JPE Jump if parity / parity even 
 JS Jump if sign 
Tabela 1: Instruções de desvio condicional 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 28 
 
 JA DESTINO 16 ou 4 
Como JMP ‘alvo’, desde 
que ‘cond’ seja satisfeita. 
JC CX 
 
3.4.8 Controle de Iteração 
 LOOP LABEL 16 ou 5 
 
Se (CX) ≠ 0, (IP)←alvo 
LOOPE/LOOPZ alvo LOOPE LABEL 18 ou 6 
(CX) ← (CX) -1 LOOPZ LABEL 
Se (CX) ≠ 0 e, (ZF) =0 
então (IP) ← alvo 
 
LOOPNE/LOOPNZ alvo LOOPE LABEL 19 ou 5 
(CX) ← (CX) -1 LOOPZ LABEL 
Se (CX) ≠ 0 e, (ZF) ) =0 
então (IP) ← alvo 
JCXZ alvo JCXZ ROTINA 18 ou 6 
Se (CX)=0, 
então (IP) ← alvo 
 
 
3.4.9 Manipulação da Pilha 
PUSH r16 PUSH SI 11(reg) ou
 10 (seg-reg)
 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 29 
 
PUSH m16 PUSH RETURN_CODE[SI] 16+EA 
 
 
PUSHF PUSHF 10 
(SP) ←(SP) -2 
((SP)) ←flags 
POP r16 POP SI 8 
 
 
POP m16 POP PARAMETRO 17+EA 
(m16) ← ((SP)) 
(SP) ← (SP) + 2 
POPF POPF 8 
(flags) ← ((SP)) 
(SP) ← (SP) + 2 
 
3.4.10 Operações sobre ‘flags’ 
 CLC 2 
(CF) ← 00 
 CMC 2 
(CF) ← (CF) 
 STC 2 
(CF) ←00 
CLD CLD 2 
(DF) ← 0 
STD STD 2 
(DF) ← 1 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 30 
CLI CLI 2 
(IF) ← 0 
STI STI 2 
(IF) ← 1 
 
3.4.11 Instruções de Entrada e Saída 
IN AL,d8 IN AL,3FH 10 
 IN AL,00H 
IN AL,DX IN AL,DX 8 
 
IN AX,DX IN AX,DX 
 
OUT d8,AL OUT 24H,AL 10 
 
OUT DX,AX OUT DX,AX 8 
 
 
OUT DX,AL OUT DX,AL 
 
 
3.4.12 "NO OPERATION" 
NOP NOP 3 
não realiza nenhuma 
operação 
 
 
3.4.13 Outras Instruções 
 
 Para tornar esta relação completa, serão mencionadas instruções, cuja 
compreensão demanda conhecimento ainda não disponíveis ao estudante nesta 
altura do curso. Por este motivo não será apresentada uma descrição destas 
instruções. São elas: ESC, HLT, LOCK, WAIT. 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 31 
 
 
4 Subrotinas 
 
 A Figura 9 ilustra algumas técnicas que são utilizadas para escrever 
subrotinas em Assembly 86. Neste exemplo um programa chama uma subrotina 
(chamada EXEMPLO) passando a ela um vetor de bytes. Dois parâmetros são 
passados na pilha: o primeiro contém o número de elementos do vetor, e o segundo 
contém o endereço do primeiro elemento do vetor. Desta forma, embora a subrotina 
receba sempre dois parâmetros, eles podem ser usados para referenciar 
indiretamente qualquer número de variáveis na memória. 
 Os resultados que a rotina retorna devem estar em registradores ou em 
memória, mas não podem estar na pilha. AX ou AL são freqüentemente utilizados 
para conter o resultado de uma rotina quando se trata de um byte ou palavra. Este é 
comumente o caso das chamadas functions. Alternativamente o programa principal 
pode passar à subrotina como parâmetro o endereço (ou endereços) de uma área 
da memória onde deve ser escrito o resultado. 
 Cada linguagem de programação de alto nível tem uma convenção diferente 
para passagem de parâmetros na pilha. A convenção aqui apresentada é, portanto, 
apenas um exemplo. 
A Figura 10a mostra como está a pilha antes do programa principal 
armazenar os parâmetros na pilha. A Figura 10b mostra a pilha como a subrotina a 
vê, logo após a execução da instrução CALL. 
 A rotina EXEMPLO pode ser dividida em quatro seções. o prólogo, em que o 
reigstrador SP é preparado para ser utilizado como registrador de base nos acessos 
aos dados contidos na pilha. O próximo passo no prólogo é salvar o estado da 
máquina. Isto é feito armazenando na pilha todos os registradores alterados pela 
subrotina (no caso, apenas CX e BX). Se a subrotina modifica os flags, e o 
programa principal conta com que os flags estejam inalterados após a execução da 
subrotina, o registrador de estado também deve ser armazenado na pilha. 
A última instrução do prólogo aloca três palavras na pilha para serem usadas 
como variáveis locais. A Figura 10c mostra a pilha após o prólogo. O conjunto de 
palavras alocadas na pilha para esta rotina é chamado de “quadro” (“frame”) da 
rotina. 
 O corpo da rotina faz o processamento propriamente dito, que, em 
EXEMPLO, corresponde a nenhum processamento. 
 Os parâmetros na pilha são endereçados relativamente ao registrador BP, 
como mostra a Figura 10. 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 32 
Figura 9: Exemplo do uso de passagem de parâmetros e criação de variáveis locais 
pela pilha. 
 
 
EX_SEG SEGMENT 
VETOR DB 10 DUP(?) 
 
ASSUME CS:EX_SEG,DS:EX_SEG;SS:EX_SEG;ES:NOTHING 
EXEMPLO PROC NEAR 
;Prólogo 
 PUSH BP ; salva BP 
 MOV BP,SP ; estabelece base 
 PUSH CX ; salva estado 
 PUSH BX ; “ “ 
 PUSHF ; e flags 
 SUB SP,6 ; aloca espaço para variáveis locais 
; fim do prólogo 
; Corpo 
 MOV CX,[BP+6] ; pega nº de elementos 
 MOV BX,[BP+4] ; pega endereço inicial do vetor 
 ƒ 
 ƒ 
 ƒ 
 ; variáveis locais estão em [BP-8], [BP-10] e [BP-12] 
 ; fim do corpo 
;Epílogo 
 ADD SP,6 ; desaloca variáveis locais 
 POPF ; restaura flags 
 POP BX ; restaura estado 
 POP CX ; “ “ 
 POP BP ; “ “ 
 ; fim do epílogo 
;Retorno da subrotina RET 4 
EXEMPLO ENDP 
 
; Programa principal 
START: MOV AX, SIZE VETOR 
 PUSH AX 
 MOV AX,OFFSET VETOR 
 PUSH AX 
 CALL EXEMPLO 
 ƒ 
 ƒ 
 ƒ 
EX_SEG ENDS 
 END START 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 33 
 
 O epílogo desaloca o espaço das variáveis locais e restaura o valor antigo do 
estado da máquina. A Figura 10d mostra a configuração na pilha logo após o 
epílogo, pouco antes da instrução de retorno. A última seção da rotina é o retorno: 
instrução RET 4, além de restaurar o antigo valor de IP, descarta os parâmetros de 
entrada, acrescentado 4 ao conteúdo de SP. 
 
endereço 
baixo → 
 
 
 
 
 
 
 
 
 
Endereço 
alto → Í SP 
 
 (a) (b) ( c) (d) 
Figura 10: Condição da pilha: (a) antes do programa principal armazenar os 
parâmetros; (b) após a instrução CALL; ( c) após o prólogo;(d) após o epílogo 
(antes de RET) 
 
5 Codificação das Instruções de Máquina do 8086/8088 
 
 Esta seção fornece uma idéia de como as instruções codificadas em linguagem 
Assembly são traduzidas para as instruções de máquina. O texto apresentado a 
seguir é praticamente uma tradução de parte do “The 8086 Family User’s Manual”. 
 A instrução em ASM-86 "MOV" pode assumir 28 formas diferentes. Um 
programador raramente precisa conhecer os detalhes da codificação das instruções 
para escrever programas. Quando se deseja, por exemplo, depurar um programa a 
partir de informações obtidas pela monitoração das barras do sistema através de 
algum aparelho qualquer. Nesta seção são apresentadas as informações necessárias 
para traduzir ou decodificar uma instrução do 8086/8088. O esquema aqui 
apresentado é o mesmo dos processadores posteriores da família (80286, 80386, 
80486, Pentium etc.), a menos de algumas extensões que foram incorporadas às 
novas versões. 
 Uma instrução de máquina pode ocupar entre 1 e 6 bytes. Instruções de 1 byte 
normalmente operam sobre um único registrador ou sinalizador e são facilmente 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 34 
identificáveis. Nas instruções mais longas são os primeiros dois bytes que contém a 
chave para a decodificação. O formato destes bytes varia mas a maioria das intruções 
segue o formato apontado na Figura 11 
 
byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 
 
 
 
 
 
 
 
 
 
 
Figura 11: Formato típico de uma instrução de máquina do 8086/8088 
 
 Os primeiros seis bits de uma instrução de mais de 1 byte geralmente contém o 
código da operação ("opcode") que identifica o tipo básico da instrução: ADD, XOR, 
etc. O bit seguinte, o campo D, geralmente especifica a direção da operação: 1 → o 
campo REG no segundo byte identifica o operando de destino, 0 → o campo REG 
identifica o operando fonte. O campo W distingui entre operações sobre 8 bits ou 16 
bits: 0 = byte, 1 = palavra de 16 bits. 
 Um entre três campos de um bit, S, V, ou, Z aparece no formato de algumas 
instruções. S é usado em conjunto com W para indicar a extensão do campo imediato 
nas instruções aritméticas. V distingui entre deslocamentos e rotações de uma ou 
várias posições. Z é usado como bit de comparação com o indicador ZF (zero) nas 
instruções de repetição e iterações condicionais. A Tabela 2 mostra um resumo do 
significado associado a cada um destes campos de um bit. 
O segundo byte da instrução usualmente identifica os operandos da instrução. 
O campo MOD indica, se um dos operandos está na memória ou, se ambos os 
operandos são registradores (veja Tabela 3). 
 O campo REG identifica o registrador que conte um dos operandos. Sua 
codificação é igual à no campo R/M para MOD=11 (3 primeiras colunas da Tabela 3 
Em várias instruções, principalmente as do tipo "operando imediato para a 
memória", REG é usado como uma extensão do "opcode" para identificar o tipo de 
operação. A codificação do campo R/M (registrador/memória) depende do conteúdo 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 35 
do campo MOD. Se MOD = 11 (modo registrador-registrador), R/M identifica o 
segundo registrador operando. Se MOD seleciona o modo memória, então o campo 
R/M indica como deve ser calculado o endereço efetivo do operando. 
 
campo valor função 
S 0 
1 
nenhuma estensão do sinal 
sinal do valor de 8 bits é extendido se W=1 
W 0 
1 
a instrução opera sobre byte 
a instrução opera sobre palavra de 16 bits 
D 0 
1 
o campo REG identifica o operando fonte 
o campo REG identifica o operando destino 
V 0 
1 
deslocamento/rotação de uma posição 
deslocamento/rotação especificado em CL 
Z 0 
1 
repetição/iteração, enquanto ZF = 0 
repetição/iteração, enquanto ZF = 1 
Tabela 2: Codificação dos campos de um bit 
 
Os bytes 3 a 6 de uma instrução, quando estão presentes, contém usualmente 
o valor do deslocamento do operando na memória e/ou o valor de um operando 
imediato. 
Pode haver um ou dois bytes contendo o deslocamento do endereço efetivo do 
operando. O campo MOD indica quantos campos deslocamento estão presentes. 
Seguindo a convenção da Intel, "little endian", se o deslocamento contém dois bytes, o 
byte mais significativo é armazenado em segundo lugar na instrução. Se o 
deslocamento é apenas um único byte, o 8086/8088 estende este valor internamente 
mantendo o sinal, para um valor de 16 bits, para então utilizá-lo nos cálculos de 
endereço. Valores imediatos sempre vêm depois dos valores de deslocamento, 
quando presentes. O segundo byte de um valor imediato de dois bytes é o mais 
significativo. O data sheet deste processador possui tabelas com a decodificação de 
cada instrução, baseada na descrição apresentada. 
 
 
MOD=11 Cálculo do Endereço Efetivo 
R/M W=0 W=1 MOD=00 MOD=01 MOD=10 
000 AL AX (BX)+(SI) (BX)+(SI)+d8 (BX)+(SI)+d16 
001 CL CX (BX)+(DI) (BX)+(DI) +d8 (BX)+(DI) +d16 
010 DL DX (BP)+(SI) (BP)+(SI) +d8 (BP)+(SI) +d16 
011 BL BX (BP)+(DI) (BP)+(DI) +d8 (BP)+(DI) +d16 
100 AH SP (SI) (SI) +d8 (SI) +d16 
101 CH BP (DI) (DI) +d8 (DI) +d16 
110 DH SI end. direto (BP)+d8 (BP)+d16 
111 BH DI (BX) (BX) +d8 (BX) +d16 
Tabela 3: Codificação dos modos de endereçamento do 8086/8088 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 36 
6 Formação do Endereço no 8086/8088 
 
No 8086/88 o conteúdo do registrador apontador de programa - IP - não é 
propriamente o endereço da próxima instrução a ser executada, mas a diferença 
("offset") entre o endereço da próxima instrução a ser executada e um determinado 
endereço inicial, conforme ilustra a Figura 12. 
 
 
Figura 12: Relação entre o endereço lógico e físico no 8086/88 
 
 De modo semelhante, o endereço efetivo de um operando calculado pela EU 
do 8086/88 não é o endereço físico da posição de memória que contém o operando, 
mas a diferença ("offset") entre o endereço da posição de memória que contém o 
operando e um determinado endereço inicial. A este endereço inicial dá-se o nome de 
endereço de início de segmento ou endereço de base. 
 Tanto num caso como no outro, o endereço de início de segmento está em um 
dos registradores de segmento (CS, DS, SS ou ES). 
O endereço efetivo calculado pela EU, bem como o conteúdo do apontador de 
programa - IP, são valores de 16 bits. Isto implica em que, usando um mesmo 
endereço de início de segmento pode-se endereçar até 64 Kbytes de memória. A área 
contígua de memória endereçada pelo 8086/88, ao executar um programa, utilizando 
um mesmo endereço de início de segmento é chamada segmento. 
 A Figura 13 mostra como é formado o endereço físico das instruções no 
8086/88. O endereço de início de segmento é, no caso de instruções, sempre definido 
pelo conteúdo do registrador CS ("code segment register") e o "offset" pelo conteúdo 
do registrador IP ("instruction pointer"). 
Para formar o endereço da instrução, o 8086/88 multiplica o conteúdo do registrador 
de segmento CS por 16D e adiciona o resultado ao conteúdo do registrador IP. Note 
que a multiplicação por 16D tem o mesmo efeito de deslocar o conteúdo de CS 4 bits à 
esquerda, preenchendo os 4 bits menos significativos com "0s". 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 37Figura 13: Formação do endereço físico no 8086/88 para acesso a código. 
 
No caso dos endereços de operandos, o microprocessador busca o endereço 
de início de segmento em qualquer dos registradores de segmento (CS, DS, SS e 
ES). Já o "offset" dos endereços de operandos pode envolver até 3 componentes: 
• Base, 
• Índice, e 
• Deslocamento 
 
 A Figura 14 ilustra como o 8086/88 calcula o "offset" e como é formado o 
endereço físico dos operandos. 
Os fatores base, índice e deslocamento podem ser contabilizados ou não para o 
cálculo do "offset" dependendo do modo de endereçamento utilizado pela instrução 
executada. 
 Uma questão a ser ainda esclarecida é: num acesso a um operando qual dos 
registradores de segmento deve ser usado para determinar o endereço de início de 
segmento? De um modo geral vale a seguinte regra: 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 38 
 
 
 
Figura 14: Formação do endereço no 8086/800 (a) para acesso a código, (b) para 
acesso a operando. 
 
• para cesso a código usa-se sempre o registrador CS, 
• para acesso a dados fora da pilha usa-se normalmente 
 DS , 
• para acesso a dados na pilha usa-se SS , 
o conteúdo do registrador BP é usado para compor o endereço efetivo do 
operando, o registrador de segmento é o SS 
 Existem instruções, no entanto, que utilizam o registrador ES ao invés do 
registrador DS para acessar dados. As instruções de manipulação de "strings" 
implicam no uso do registrador ES na formação do endereço efetivo do operando nos 
acessos de escrita. Desta forma a instrução MOVS transfere o byte ou palavra contida 
no endereço (DS:SI) para o endereço (ES:DI). De modo semelhante a instrução 
CMPS compara o byte ou palavra contido no endereço (DS:SI) com o byte ou palavra 
do endereço (ES:DI). Também a instrução SCAS compara o conteúdo do acumulador 
(registrador AL ou AX) com o conteúdo do endereço definido por (ES:DI). 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 39 
 Além disso, é possível forçar o microprocessador a utilizar no cálculo do 
endereço efetivo um registrador de segmento diferente do previsto pela regra acima 
("default"). Nestes casos a instrução recebe um prefixo que impõe a utilizarão de um 
registrador de segmento distinto do definido por essas regras. 
 A instrução 
 
código instrução clocks 
88 9C 00 40 9+EA 
 
por exemplo, move o conteúdo da posição de memória, cujo endereço efetivo é dado 
pelo conteúdo do registrador DS ("default" neste caso) deslocado 4 bits à esquerda, 
adicionado ao valor do deslocamento, que neste caso é o endereço do primeiro byte 
do vetor ARRAY, adicionado ainda ao conteúdo do registrador de índice SI, para o 
registrador BL. Se, ao invés de utilizar o registrador de segmento "default", se deseja 
utilizar, digamos, o registrador ES, a instrução em Assembly toma a seguinte forma: 
 
código instrução clocks 
26 88 9C 00 40 9+EA 
 
 Há casos, no entanto, em que não se pode utilizar outro registrador de 
segmento diferente do "default". Por exemplo, nos acessos a instrução o registrador 
CS é sempre utilizado. Da mesma forma, quando se acessa a pilha utilizando o 
registrador apontador de pilha - SP - necessariamente se utiliza o registrador SS como 
registrador de segmento. 
 O conteúdo dos registradores de segmento é normalmente definido no início da 
execução do programa, utilizando instruções apropriadas. Nada impede porém que o 
conteúdo dos registradores de segmento seja alterado várias vezes ao longo do 
programa. 
 A grande vantagem do uso destes registradores de segmento é que tanto os 
códigos como os dados e a pilha podem ser carregados em qualquer região da 
memória, sem que seja necessário modificar o código objeto. Basta carregar os 
registradores de segmento de modo adequado. 
 O sistema operacional de um microcomputador pessoal, por exemplo, antes de 
carregar um programa na memória, verifica qual a região da memória que está 
disponível naquele momento e carrega o programa da memória de massa naquela 
região. Antes de passar o controle para o programa carregado, o sistema operacional 
carrega os registradores de segmento com os valores adequados. Na maioria dos 
microprocessador de 8 bits, como o 8085, por exemplo, os endereços estão fixos no 
código objeto. Para se alterar a região de memória onde um programa do 8085 será 
carregado é necessário alterar o código objeto. 
 Programas que podem ser carregados em qualquer região da memória sem 
que o código objeto precise ser alterado, são chamados programas relocáveis. 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 40 
 
7 O Mecanismo de Segmentação e as Instruções de Desvio 
 
 Evidentemente o mecanismo de segmentação da memória tem implicações 
sobre o conjunto de instruções do microprocessador. 
 O primeiro aspecto a abordar aqui diz respeito às instruções de desvio: JMP, 
CALL e RET. Existem dois tipos de desvio: o intra-segmento e o inter-segmento. 
 
7.1 Desvios intra-segmento 
 Numa instrução JMP intra-segmento o endereço para onde o programa deve 
ser desviado, pertence ao mesmo segmento onde está armazenada a instrução JMP 
em execução. Neste caso, a instrução deve conter, além do código do JMP, a 
especificação do novo valor do registrador IP. O seguintes exemplos são 
esclarecedores: 
 
código instrução clocks 
E9 00 40 15 
FF E3 11 
FF A7 00 40 18+EA 
 
 No primeiro exemplo o valor a ser carregado no IP é definido na própria 
instrução. O valor codificado na instrução neste caso é na realidade a diferença entre 
o conteúdo atual e o novo conteúdo de IP. O que o microprocessador faz na prática 
é somar este valor contido na instrução ao conteúdo de IP. Este tipo de desvio é 
chamado desvio direto. 
 No segundo e terceiro exemplos tem-se desvios indiretos. No segundo caso o 
conteúdo do registrador BX é copiado no registrador IP. No terceiro exemplo carrega-
se em IP a palavra armazenada no endereço de memória especificado na instrução. 
 Em todos os exemplos acima se diz que o desvio é do tipo próximo (NEAR), um 
sinônimo de desvio intra-segmento. 
 Deve-se distinguir um tipo de instrução de desvio intra-segmento. Quando a 
diferença entre o endereço que contém a instrução JMP e o endereço de desvio está 
entre -128 e 127, pode se utilizar o desvio curto (SHORT). Esta situação é muito 
frequente em pequenos "loops". Neste caso é especificado na instrução o código da 
instrução JMP e a diferença entre o valor atual e o novo valor do registrador IP 
expresso em 8 bits. Este tipo de desvio é chamado desvio relativo. Exemplo: 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 41 
 
código instrução clocks 
EB 0F 15 
 
 Neste caso ao conteúdo de IP é acrescido o valor 0FH. Observe que o código 
neste caso é mais compacto. 
 
código instrução clocks 
E9 78 01 15 
 
 Observe que o primeiro byte do código do JMP é diferente em cada caso. 
 
 
7.2 Desvios inter-segmento 
 Diz-se que o desvio é do tipo inter-segmento, quando o endereço para onde o 
programa deve desviar está em outro segmento. Neste caso é preciso especificar na 
instrução os novos valores para os registradores IP e CS, como nos exemplos abaixo. 
 
código Instrução clocks 
EA 00 30 34 02 15 
FF AC 28 00 24+EA 
 
 No primeiro exemplo têm-se um desvio direto, e no segundo caso um desvio 
indireto. Diz-se em ambos os casos que o desvio é dotipo distante (FAR). 
 
 
7.3 Desvios condicionais 
 Para desvios condicionais o processador só permite desvios do tipo curto 
direto, em que a distância entre a instrução e o endereço de desvio está na faixa -128 
e 127. Exemplo: 
 
código Instrução clocks 
76 3F 16 ou 4 
 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 42 
7.4 Instruções CALL 
 A subrotina para instruções CALL é semelhante. Há 5 formas distintas de se 
chamar uma subrotina, conforme mostram os exemplos a seguir. 
 
 
código Instrução clocks 
E8 00 40 ; direto próximo 19 
FF D3 ; indireto próximo 16 
FF 10 ; indireto próximo 21+EA 
9A 00 03 27 11 ; direto longo 28 
FF AD 00 04 ; indireto longo 37+EA 
 
 Uma diferença importante entre os CALLs próximos e distantes deve ser 
mencionada aqui. Instruções CALL intra-segmento (próximas) salvam na pilha apenas 
o conteúdo do IP para o retorno, portanto uma palavra de 16 bits. Quando ocorre um 
CALL inter-segmento (distantes), são salvos na pilha tanto o conteúdo de IP quanto o 
de CS, portanto duas palavras de 16 bits. 
 
7.5 Instruções RET 
 De modo análogo ao que ocorre com a instrução CALL, existem dois tipos de 
instruções de retorno: o primeiro para o retorno de subrotinas distantes e outro para o 
retorno de subrotinas próximas. As instruções do primeiro tipo restauram apenas o 
conteúdo do IP, enquanto as do segundo tipo restauram tanto IP quanto CS. 
Exemplos: 
 
 
 
código instrução clocks 
CB ; intra-segmento (próximo 8 
CA 08 00 ; intra-segmento (próximo) 12 
C3 ; inter-segmento (distante) 18 
C2 08 00 ; inter-segmento (distante) 17 
 
 Deve-se deixar claro que o programador não precisa se preocupar com o tipo 
de instrução a utilizar em cada caso. O próprio montador Assembly identifica qual é o 
tipo de instrução adequado para cada situação e produz o código correspondente. 
 Antes de concluir esta seção cabe relacionar este assunto com o que foi 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 43 
discutido na seção 3, sobre convenção de passagem de parâmetro e alocação de 
variáveis locais em subrotinas. O exemplo considerado então se baseava numa rotina 
próxima. Se a subrotina EXEMPLO fosse do tipo distante a instrução CALL 
armazenaria na pilha os valores de CS e de IP. A distância do conteúdo de BP em 
relação a cada parâmetro de entrada seria maior, mais exatamente acrescida de 2. 
 
8 Operação EU + BIU - Pré-busca de Instruções 
 Já foi mencionado no início do texto que o 8086/8088 é constituído de duas 
unidades capazes de operar independentemente. A EU, que cuida exclusivamente da 
execução das instruções, e a BIU, que cuida exclusivamente da comunicação com o 
restante do sistema. Quando a EU necessita alguma informação da memória, seja 
para ler o código de uma instrução ou ler/escrever um operando, ela gera uma 
solicitação à BIU que providencia a execução do acesso. 
 Associada à BIU existe uma fila de instruções com capacidade de 6 bytes no 
8086 e 4 bytes no 8088, onde a BIU vai armazenando códigos de instruções que 
ainda não começaram a ser executadas, mas que o serão "provavelmente" logo em 
seguida. Na verdade a BIU vai carregando bytes armazenados na memória em 
endereços consecutivos àquele que contém a instrução presentemente sendo 
executada. Devido à tendência do microprocessador de executar instruções na 
mesma ordem em que estas estão armazenadas na memória, há uma alta 
probabilidade de que, ao a EU solicitar à BIU o código da próxima instruções, este já 
se encontre armazenado na fila de instruções. Neste caso a EU não necessitará 
aguardar ociosa até que a BIU vá à memória buscar as instruções, para só então 
iniciar sua execução. Ao contrário, a EU poderá iniciar imediatamente a execução da 
instrução. 
 O esquema de pré-busca de instruções executado pela BIU erra na estimativa 
de qual será a próxima instrução a ser executada quando ocorrem instruções de 
desvio. Nestes casos a BIU providencia o esvaziamento da fila de instruções e passa 
a carregar bytes/palavras da memória a partir do endereço da nova instrução. 
 A BIU inicia um acesso de pré-busca de instrução sempre que as seguintes 
duas condições estiverem satisfeitas: 
1. há pelo menos 2 bytes (1 byte no caso do 8088) livres na fila 
de instruções. 
2. não existe nenhuma solicitação de acesso ao barramento 
pendente vinda da EU. 
 
 
 A Figura 15 ilustra as ações do 8086 e o conteúdo da fila de instruções quando 
o 8086 executa uma instrução. Admite-se que esta instrução esteja contida em dois 
bytes e que a fila se encontra vazia imediatamente antes do início da execução. Esta 
instrução gasta 7 ciclos de relógio para calcular o endereço efetivo do operando que 
se encontra na memória e mais 6 ciclos de relógio para executar a operação. 
A EU está ativa quando está executando instruções e inativa quando espera 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 44 
que a BIU lhe forneça um dado ou instrução. A BIU só está ativa quando atende 
alguma solicitação da EU ou quando há pelo menos 2 (no 8088 1) bytes livres na fila 
de instruções. Quando estas duas condições estão satisfeitas ao mesmo tempo, a 
prioridade é sempre dada à solicitação da EU. Quando chega uma solicitação da EU 
enquanto a BIU realiza uma busca de instrução, a solicitação da EU só passa a ser 
atendida depois de que o acesso que está em andamento for completado. Neste caso 
a EU é forçada a esperar ociosa. 
 
 
 1º ciclo 2º ciclo 3º ciclo 4º ciclo 5º ciclo 6º ciclo 
 
E 
U 
 
B 
I 
U 
 
Figura 15: Diagrama de atividades da EU e da BIU 
 
 
 
 
9 Tempo de Execução das Instruções 
 
 O exemplo apresentado na seção anterior torna claro que o tempo consumido 
na execução de um programa depende tanto das instruções como da seqüência em 
que estas instrução são executadas. Um mesmo conjunto de instruções pode ter um 
tempo de execução distinto dependendo da ordem em que as instruções do conjunto 
são executadas. Esta característica dificulta a tarefa de determinar por inspeção de 
um programa em Assembly o tempo de execução correspondente. 
 Nesta seção é descrito um procedimento que permite estimar o tempo de 
execução de um programa a partir de uma simples inspeção das instruções que o 
constituem. 
 Na descrição das instruções nas seções anteriores, é apresentado no lado 
direito de cada uma o número de ciclos de relógio necessários para executá-la. Nas 
instruções que envolvem operandos da memória "+EA" denota o número de ciclos de 
relógio (clocks) adicionais necessários para calcular o endereço efetivo do operando. 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 45 
A Tabela 4 apresenta os tempos de cálculo do endereço efetivo em número de ciclos 
de relógio. 
Para as instruções de desvio, os valores incluem os ciclos adicionais para 
reiniciar a fila de instruções, bem como o tempo necessário para trazer da memória a 
instrução contida no endereço de destino. Para os desvios condicionais são dados 
dois valores separados por um "/". O valor mais alto corresponde à situação em que o 
desvio se consuma e o valor mais baixo à situação contrária. 
 
 
 Componentes do Endereço Efetivo clocks 
 somente deslocamento 6 
 somente base ou índice 
 
5 
 deslocamento +base ou índice 
 
9 
 base + índice BX+SI ou BX+DI 
 BP+SI, BP+ DI 
7 
8 
 
 deslocamento BP+DI+deslocamento
+ base BX+SI+deslocamento
+ índice BP+SI+deslocamento
 BX+DI+deslocamento
11 
11 
12 
12 
 
Tabela 4: Tempo consumido no cálculo do endreço efetivo dos operandos em número 
de ciclos de relógio. 
 
 Além disso, deve-se acrescentar 4 ciclos de relógio para cada instrução que 
referencia uma palavra de 16 bits contida num endereço ímpar, pois o 8086 só é 
capaz de ler uma palavra de 16 bits num único acesso se o byte menos significativo 
da palavra estiver num endereço par. Se esta condição não for satisfeita, o 8086 gera 
dois acessos, cada um referenciando uma das duas metades da palavra. 
 Quando se utiliza um 8088 deve ser acrescentado 4 ciclos para todos os 
acessos a operandos de 16 bits, independentemente de estarem ou não 
armazenados em endereços pares. 
 Quando se utiliza um prefixo definindo um registrador de segmento diferente do 
"default", devem ser acrescentados mais dois ciclos de relógio. 
 O tempo total de execução de um trecho de programa pode ser obtido 
multiplicando-se o tempo de execução de cada instrução particular pelo número de 
vezes que ela é executada. A soma destes produtos produz uma estimativa otimista, 
mas bastante aproximada do valor real. 
 Vários fatores podem aumentar o tempo de execução relativamente a esta 
estimativa. Estes tempos admitem que as instruções estão disponíveis na fila de 
instruções assim que a EU está pronta para executá-las. Quando se tem uma 
sequência de instruções rápidas (com menos do que 2 ciclos de relógio) a fila de 
instruções pode esvaziar e obter-se um tempo de execução maior. 
 Um outro aspecto evidenciado no exemplo da seção anterior, é que a interação 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 46 
entre a EU e a BIU pode ter efeitos sobre o tempo de execução. Se a EU necessita 
buscar um operando da memória, ela poderá ter que esperar até que a BIU complete 
o acesso em andamento antes de iniciar o acesso solicitado pela EU. Eventuais 
ciclos espera no acesso a operandos podem também afetar o tempo de execução 
(vide exercício 27). 
 A partir de experimentos realizados pelo fabricante do integrado, concluí-se, 
contudo, que este método de estimativa produz valores próximo dos valores reais. Os 
tempos de execução para outros processadores da família podem ser obtidos nos 
data sheets específicos. O procedimento para estimativa é, contudo, 
aproximadamente o mesmo para todos eles. 
 
10 Exercícios 
1ª Questão 
Sejam m e k dois números hexadecimais de 32 bits armazenados respectivamente 
nos registradores DX:AX e CX:BX, de tal forma que AX e BX contém os 16 bits 
menos significativos de m e k respectivamente. Escreva um trecho de programa em 
ASM86 que subtraia k de m e coloque o resultado em DX:AX. Se m < k o resultado 
produzido deve ser zero. 
 
2ª Questão 
Repita o exercício anterior admitindo que m e k estão armazenados respectivamente 
a partir dos endereços MMMM e KKKK. DX:AX deve conter o resultado. 
 
3ª Questão: 
Escreva um trecho de programa em ASM86 que multiplique o conteúdo do 
registrador AL pelo conteúdo do registrador CL, deixando o resultado em AX. Você 
não poderá usar a instrução MUL ou IMUL. Utilize sucessivas adições. 
 
4ª Questão: 
Escreva um trecho de programa em ASM86 que divida o conteúdo do registrador DX 
pelo conteúdo do registrador AX, deixando o quociente inteiro em AX. Você não 
poderá usar a instrução DIV ou IDIV. Utilize sucessivas subtrações. 
 
5ª Questão: 
Escreva um trecho de programa em ASM86 que eleve o conteúdo do registrador AX 
ao conteúdo do registrador DX. O resultado de 32 bits deve ser colocado no par de 
registradores CX:AX. Caso o valor obtido não possa ser representado em 32 bits, o 
conteúdo de DX:AX deverá ser nulo. 
 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 47 
6ª Questão: 
Escreva um trecho de programa em ASM86 que zere todo o registrador AL, se o seu 
nibble2 menos significativo for igual a zero e carregue o valor 0FFH em AL, caso 
contrário. 
 
7ª Questão: 
Escreva um trecho de programa em ASM86 que produza nos bits de ordem ímpar os 
correspondentes bits do registrador BL, e nos bits de ordem par de AL os 
correspondentes bits de CL. 
 
8ª Questão: 
Escreva um trecho de programa em ASM86 que produza nos bits de ordem par de 
AL o ou exclusivo dos bits correspondentes dos registradores BL e CL, e nos bits de 
ordem ímpar mantenha o mesmo valor inicial. 
 
9ª Questão: 
Escreva um trecho de programa em ASM86 que faça o ou exclusivo entre os dois 
nibbles2 do registrador AL. 
 
10ª Questão: 
Escreva um trecho de programa em ASM86 que transforme um número em formato 
BCD armazenado em AL no seu correspondente valor hexadecimal Você não pode 
usar as instruções de multiplicação, divisão, e de ajuste a BCD. 
 
11ª Questão: 
Escreva um trecho de programa em ASM86 devolva no registrador CL a paridade do 
conteúdo de AX, isto é, se o número de 1s em AX for ímpar, CL=0, e CL=1, caso 
contrário. 
 
12ª Questão: 
Você tem uma região da memória no segmento apontado por DS do tipo: 
BUFFER DB 80 DUP(?) 
onde são armazenados strings de caracteres vindos de um teclado. Um string pode 
ter no máximo 80 caracteres e é sempre terminado pelo caracter "CR" (0DH). 
Escreva uma subrotina em ASM86 que determine o tamanho do string desta região. 
Admita que os registradores de segmento estão convenientemente carregados. 
 
13ª Questão: 
A tabela abaixo é construída de tal maneira que o conteúdo de i-ésimo elemento é 
exatamente o correspondente código EBCEDIC de i, onde i está codificado em 
ASCII. 
CONV_TAB DB 64 DUP(0H) 
 DB 1 20H 
 DB 9 DUP(0H) 
 
2 Nibble é o termo em inglês que denota os quatro bits de cada uma das metades de um byte. 
 Linguagem Assembly Família Intel 
 
 
última revisão Ago/2007 48 
 DB 7 'ç','.','<','(','+',0h,'&' 
 D B 9 DUP(0H) 
 DB 8 '!','$','*',')',';',' ','-','/' 
 DB ..... 
 
Você tem ainda duas regiões da memória no segmento apontado por DS do tipo: 
 
BUFFER_ASCII DB 80 DUP(?) 
BUFFER_EBCDIC DB 80 DUP(?) 
 
Na primeira região são armazenados strings de caracteres vindos de um teclado. Um 
string pode ter no máximo 80 caracteres e é sempre terminado pelo caracter "CR" 
(0DH). Escreva um programa em ASM86 que coloque na segunda região de 
memória o string produzido pelo teclado, devidamente traduzido para o código 
EBCDIC. 
 
14ª Questão: 
Embora o 8086/8088 possua instruções de multiplicação e divisão inteira, escreva 
um programa (MULT) que multiplique dois números inteiros sem sinal m, 
armazenado em AH, e k, armazenado em AL, utilizando o seguinte algoritmo 
 
MULT(m,k)=[(k x 20 x m0]+[(k x 21 x m1]+...[(k x 27 x m7] 
 
O resultado deve estar no registrador AX. 
 
15ª Questão: 
Escreva um programa que divida o conteúdo de AX pelo conteúdo de AL, utilizando 
algoritmo análogo ao do exercício anterior, sem usar as instruções de divisão do 
8086/8088. O quociente deve ser colocado em AL e o resto em AH. 
 
16ª Questão: 
Escreva uma rotina (SROT) que tome o parâmetro de entrada, um valor de 16 bits, e 
troque de posição o byte mais e o byte menos significativo, retornando este valor em 
AX. O parâmetro de entrada é passado para a subrotina SROT pelo programa

Outros materiais