Escolar Documentos
Profissional Documentos
Cultura Documentos
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.
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
3.2 Comandos
Existem dois tipos de comandos na linguagem Assembly-86 (ASM86):
instruções e diretivas.
última revisão Ago/2007 4
Linguagem Assembly Família Intel
aulas de laboratório.
3.2.1.1 Constantes
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ção de 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.
; TABELA DB 50 DUP(?)
; TABELA DD 50 DUP(?)
SOMA_OUTRO:
; 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
última revisão Ago/2007 8
Linguagem Assembly Família Intel
deva contê-las para que o montador funcione corretamente, este texto limita-se a
mencioná-las sem discutir em detalhes o seu papel.
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
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
Endereço
Efetivo
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.
última revisão Ago/2007 10
Linguagem Assembly Família Intel
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.
BX ou BP
ou Endereço
SI ou DI Efetivo
JMP [AX]
CALL [DX]
BX ou BP
+
Figura 6: Ilustração do modo de endereçamento com base.
Endereço
Efetivo
SI ou DI
+ Endereço
Efetivo
BX ou BP
+ Endereço
Efet-ivo
SI ou DI
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
última revisão Ago/2007 14
Linguagem Assembly Família Intel
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)
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
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
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
3.4.5.3 Multiplicação
MUL r MUL BL 70-77
MUL CX 118-133
3.4.5.4 Divisão
DIV r8 DIV CL 80-90
(sem sinal)
(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,
CWD CWD 5
AAA AAA 4
DAA DAA 4
AAS AAS 4
DAS DAS 4
AAM AAM 83
AAD AAD 60
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
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
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
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
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)
JA DESTINO 16 ou 4
Como JMP ‘alvo’, desde JC CX
que ‘cond’ seja satisfeita.
Se (CX) ≠ 0, (IP)←alvo
Se (CX) ≠ 0 e, (ZF) =0
então (IP) ← alvo
Se (CX) ≠ 0 e, (ZF) ) =0
então (IP) ← alvo
JCXZ alvo JCXZ ROTINA 18 ou 6
Se (CX)=0,
então (IP) ← alvo
PUSHF PUSHF 10
(SP) ←(SP) -2
((SP)) ←flags
(CF) ← 00
CMC 2
(CF) ← (CF)
STC 2
(CF) ←00
CLD CLD 2
(DF) ← 0
STD STD 2
(DF) ← 1
CLI CLI 2
(IF) ← 0
STI STI 2
(IF) ← 1
IN AX,DX IN AX,DX
4 Subrotinas
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
Figura 9: Exemplo do uso de passagem de parâmetros e criação de variáveis locais
pela pilha.
endereço
baixo →
Endereço
alto → Í SP
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
Figura 14: Formação do endereço no 8086/800 (a) para acesso a código, (b) para
acesso a operando.
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:
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
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.
E
U
B
I
U
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
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.
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.
última revisão Ago/2007 47
Linguagem Assembly Família Intel
DB 7 'ç','.','<','(','+',0h,'&'
DB 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(?)
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
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
principal através da pilha, utilizando o mecanismo de passagem de parâmetros visto
neste material.
17ª Questão:
Escreva uma subrotina (TWOCP) em ASM-86 que calcule o complemento de dois de
um valor de 32 bits contido nos registradores DX:AX. O valor complementado deve
retornar no próprio par de registradores DX:AX. O conteúdo dos demais
registradores não pode ser modificado por TWOCP.
18ª Questão:
Escreva uma subrotina (LOG) em ASM-86 que calcule o ln(x+1). O valor de x é um
número inteiro menor do que 256, expresso em 16 bits e é passado a LOG pela
última revisão Ago/2007 48
Linguagem Assembly Família Intel
pilha, usando o método apresentado neste material. O resultado deverá ser devolvido
em 16 bits ao programa principal no registrador AX. Utilize a aproximação de Taylor:
x2 x3 x 4 x5
ln( x + 1) = x − + − +
2 3 4 5
Você já dispõe da subrotina POWER que eleva o conteúdo do primeiro parâmetro,
ao valor do segundo parâmetro retornando o resultado em AX. Ambos os parâmetros
são valores inteiros menores do que 256,expressos em 16 bits, passados através da
pilha. POWER não altera o conteúdo de nenhum registrador a menos de AX. Se
ocorrer overflow, seu programa deve retornar o valor zero. Crie uma variável
temporária que contenha os valores parciais do cálculo do logaritmo.
19ª Questão:
Escreva uma rotina (INTER) em ASM-86 que determine a intersecção entre dois
conjuntos de números de 8 bits. Os parâmetros de entrada são todos expressos em
16 bits e são passados à rotina na seguinte ordem: endereço inicial do vetor
contendo o primeiro conjunto, número de elementos do primeiro conjunto, endereço
inicial do vetor contendo o segundo conjunto, número de elementos do segundo
conjunto, endereço inicial do vetor contendo o conjunto intersecção. Além disso, a
subrotina deve retornar em AX a cardinalidade do conjunto intersecção. Admita que
não há repetições de números num mesmo conjunto, e que ambos os conjuntos têm
pelo menos um elemento.
20ª Questão:
Escreva a rotina (MEDIA) em ASM-86 que calcule a média de n números (x1, x2, ...,
xn) inteiros, sem sinal, expressos em um byte. Os parâmetros - endereço a partir de
onde estão armazenados os números e n - são expressos em 16 bits e são
passados a MEDIA pela pilha, conforme a convenção vista em aula. O resultado, de
16 bits, deve ser passado ao programa principal pelo registrador AX. O flag Carry,
deverá quando setado que houve overflow.
21ª Questão:
Escreva uma rotina (SORT) em ASM-86 que faça o sort dos bytes contidos num
determinado vetor. O endereço inicial do vetor, bem como o número de elementos
deste vetor, são passados à rotina pela pilha. Os elementos do vetor são números
inteiros com sinal. Utilize variáveis auxiliares locais.
22ª Questão:
Escreva a rotina MAXIMO em ASM86 que determine o maior de um conjunto de n
números inteiros sem sinal expressos em 16 bits. O valor de n, expresso em 16 bits,
e os n bytes são passado a MAXIMO pela pilha, conforme o método discutido neste
material. O maior valor encontrado deve retornar no registrador AX. Escreva a rotina
de modo que todos os parâmetros de entrada sejam retirados da pilha antes de
retornar ao programa principal. Utilize uma variável local para conter o valor máximo
temporário.
23ª Questão: Escreva uma subrotina (ESCALAR) em ASM-86 que execute o produto
escalar entre dois vetores de inteiros de 16 bits com sinal. O tamanho dos vetores
(expresso em 16 bits) e o endereço inicial de cada um dos dois vetores de entrada,
bem como o do endereço do vetor de saída são passados à rotina pela pilha. O
resultado deve retornar ao programa principal pelo registrador AX. Admita que não
haverá overflow nos cálculos parciais. Utilize variável(eis) local(is).
24ª Questão
O programa abaixo soma as palavras contidas numa tabela armazenada na memória
a partir do endereço TABLE, deixando o resultado no registrador AX. Codifique este
trecho de programa em ASM86.
SUB AX,AX
MOV CX,25 ;carrega CX c/ tamanho da tabela
MOV SI,50
ADD_NEXT: SUB SI,2
ADD AX,TABLE[SI]
LOOP ADD_NEXT
25ª Questão
Repita o exercício anterior para a rotina abaixo. Este programa controla um canal de
comunicação assíncrono.
26ª Questão
O programa abaixo é um gerador de números aleatórios. Repita o exercício anterior
para este programa.
MOV SAVE,AX
SUB DX,DX
MOV CX,6
DIV CX
MOV AX,DX
RET
RANDOM ENDP
27ª Questão:
O programa abaixo calcula o fatorial de um número maior do que zero colocado em
AX. Estime o tempo de execução da rotina abaixo em função do conteúdo de AX.
Admita que os acessos a dados estão afetados de ciclos de espera, conforme a
tabela abaixo:
leitura escrita
dados na pilha 1 2
dados fora da pilha 3 4
28ª Questão:
Nas subrotinas descritas abaixo, ALFA é uma constante. Estime o tempo de
execução das subrotinas em função de ALFA, desde o instante em que inicia sua
execução até o momento em que ocorre o retorno ao programa principal. Observe se
vale a pena utilizar as instruções de manipulação de string neste caso, do ponto de
vista do desempenho. Admita que cada acesso de leitura ou escrita a dados é
afetado respectivamente por um ou dois ciclos de espera.
29ª Questão:
Escreva seqüências de instruções equivalentes a cada uma das instruções de
manipulação de string. Determine em seguida o tempo de execução da instrução de
"string" e da seqüência equivalente. Compare os resultados.