Documente Academic
Documente Profesional
Documente Cultură
ENGENHARIA DE COMPUTAÇÃO
SISTEMAS DIGITAIS
SISTEMAS DIGITAIS
Tutor: Victor
SEMESTRE 2006.2
Março de 2007
Feira de Santana - Bahia
-2-
Sumário
1 - Introdução .............................................................................................. 4
4 - Conclusão .............................................................................................. 10
7 – Referências.......................................…………………………………………….. 11
-3-
Introdução
-4-
Assembly x Emu8086
-5-
Código Asm para ordenação de um vetor
-6-
instrução, o endereço passado ao registrador si é o endereço do primeiro valor do vetor, que
no caso corresponde a 12. Em seguida, é movido para o registrador ah o valor ocupado no
endereço de memória que si aponta. A notação do uso dos colchetes implica que o que está
sendo passado a ah não é o endereço que si guarda, mas sim o valor que está no endereço de
memória ao qual si aponta. De igual forma, é passado para al, o segundo elemento do vetor,
que corresponde à parte decimal do primeiro valor. O incremento a si indica o deslocamento
no vetor. Tem-se então o primeiro valor em ponto flutuante armazenado. Para armazenar o
segundo, incrementou o vetor e foi usado o registrador di para apontar o endereço
correspondente. Os registradores bh e bl foram utilizados para armazenar a parte alta e baixa
do segundo valor, respectivamente.
A instrução test, na forma como foi utilizada, compara o número de vec[0], e logo
depois de vec[2] (partes inteiras dos dois primeiros números), com o número binário
10000000b. Isso funciona como uma instrução a fim de saber se o número que ocupa certo
trecho do vetor é positivo ou negativo. O primeiro bit de um número binário indica o sinal: 0
indica positivo e 1 indica negativo. A instrução então testa o número e avalia o flag “zf”. O
salto jnz só é feito caso o número testado seja negativo. Faz-se o teste com os dois números.
Se um dos dois (ou mesmo os dois), forem negativos, o programa é direcionado para um
rótulo afim de fazer a troca necessária. O rótulo foi denominado de negativo1.
Se os dois testes forem feitos e não acontecerem os saltos, isso implica que os dois
valores são positivos. Daí faz-se uma comparação entre eles. Pode acontecer três coisas: O
primeiro ser maior que o segundo, eles serem iguais, ou o primeiro menos que o segundo.
Caso a primeira situação ocorra, faz-se um salto a um rótulo chamado troca, que fará a troca
das partes inteiras e fracionárias,a partir da instrução ja (above jump- pule se maior). Se não
-7-
ocorrer, o primeiro número só pode ser igual ou menor ao segundo. Se não for igual, o
programa executa o bloco2, que agora tratará do segundo e terceiro número. A instrução jne
faz saltar se não for igual. Como só existia duas possibilidades, se não for igual só pode ser
menor então, não precisando fazer nenhuma alteração. Por fim, caso seja igual, resta
comparar a parte fracionária, fazendo a troca se necessário.
negativo1:
test vec[2],10000000b
jz bloco2
test vec[0],10000000b
jz troca
cmp ah,bh
ja troca
jne bloco2
cmp al,bl ;compara as partes fracionarias
jb troca
jmp bloco2
Entretanto, se em um dos testes o número fosse negativo, o programa passa a ser
executado no rótulo negativo1. Esse rótulo nada mais é do que algo semelhante ao rótulo
troca. Todavia, há alguns variantes. O número 2,5 é maior que 2,4, por exemplo. Todavia,
-2,5 não é menor que -2,4. Isso seria interpretado de má forma caso o rotulo chamado fosse
troca. Esse último analisaria os primeiros números. Como são iguais, analisaria o segundo,
as partes fracionárias, e faria a troca uma vez que 5 é maior que 4.
Se o programa passou a ser executado em negativo1, isso quer dizer que o primeiro
ou o segundo valor do vetor é negativo, daí testar novamente, agora dentro do bloco se o
segundo valor é negativo. Caso ele seja positivo,isso evidencia que o primeiro é negativo e,
logo, não devem ser feitas trocas entre eles e o programa passa para bloco2. Entretanto, se
for negativo, o primeiro valor é testado. Caso ele seja positivo, a troca é feita, uma vez que o
segundo valor é negativo.
Se nenhum dos testes implicar em valores positivos, isso implica que os dois valores
são negativos. Faz-se então a comparação de ah com bh. A troca é feita caso ah seja maior
que bh. Resta as opções igual ou menor. Usando a instrução jne, o salto é feito se não for
igual, logo menor, ou seja, não precisa fazer a troca. Todavia, se for igual, faz–se a
comparação de al com bl. A troca só é feita caso al seja menor que bl, uma vez que, para
negativos, funciona diferente, como já foi explicado.
-8-
troca:
push ax
mov [si],bh
mov [si+1],bl
pop bx
mov [di],bh
mov [di+1],bl
jmp bloco1
-9-
Conclusão
Trabalhar com números em ponto flutuante é uma tarefa de precisão. Esse código em
Assembly não abusou da precisão uma vez que operou sob 16 bits: oito para a parte inteira e
oito para a parte fracionária. Ou seja, existem 256 possibilidades de números para cada. Em
contrapartida, se fosse trabalhado com 32 bits, as possibilidades aumentariam de 256 para
65536. Mudaria algumas coisas no código como ,por exemplo, ao contrário de usarmos ah e
al, para armazenar um número decimal, usaríamos ax e bx, uma vez que cada um deles
corresponde a 16 bits.
A outra forma de trabalhar com 32 bits seria usar um co-processador 8087, conforme
já foi dito no decorrer do relatório. Esse co-processador permitiria a entrada direta com
números em ponto flutuante. Sob alguns tipos de instruções diferentes, um programa
desenvolvido para esse co-processador trabalha os valores de um vetor desordenado de
números numa pilha de registradores de 32 bits, que vai de st0 a st7, logo oito registradores.
Os valores do vetor poderiam ser transpostos para essa pilha e, assim, o código executável,
acompanhado da diretiva #fasm#, que faz com que o compilador entenda que os valores
estão em ponto flutuante, faria a ordenação do vetor.
Quando se opera com números positivos e negativos no mesmo vetor, as 256
possibilidades de números se dividem: de -127 a 128, ou -128 a 127. O número -2, por
exemplo, corresponde a 254, caso ele seja visto como um inteiro sem sinal. Isso pode
complicar a execução do código caso, por exemplo, os valores -255,12 e 238,40 estejam
presentes no vetor. A diferença entre eles é um número consideravelmente maior que 256.
A linguagem Assembly não é uma linguagem de alto nível. Sua codificação não é
simples e nem tão pouco sugestiva. Todavia, trabalhar com linguagens de baixo nível
diminui as instruções e torna as execuções mais práticas e rápidas. Daí programas serem
montados de forma mista, concatenando duas ou mais linguagens. É válido lembrar ainda
que, no processo de compilação de um programa de alto nível, o compilador se incube de
codificar as instruções para linguagens mais baixas, até alcançar a mais baixa possível, a
linguagem binária. Uma compilação de um programa em linguagem C, por exemplo, gera
um código referente em Assembly enquanto não alcança a forma binária.
- 10 -
Referências
4 –http://www.mikroelektronika.co.yu/portuguese/product/books/picbook/capitulo4.htm
- 11 -