Índice> <1> <2> <3> <4> <5> <6> <7> <8> <Página Principal>

CAPÍTULO 3: 
PROGRAMA�ÃO ASSEMBLY

Conte�do:
3.1.Construindo programas em Assembly
3.2.Processo Assembly
3.3.Pequenos programas em Assembly
3.4.Tipos de instruções
			--------------- // ---------------
                             
3.1.Construindo programas em Assembly.
3.1.1.Software necessário
3.1.2.Programação Assembly
                       
3.1.1.SOFTWARE NECESSÁRIO
Para que possamos criar um programa, precisamos de algumas ferramentas:
 Primeiro de um editor para criar o programa fonte.
 Segundo de um montador,um programa que ir  transformar nosso fonte num programa objeto.
 Terceiro, de um linker (ligador) que irá gerar o programa executável a
partir do programa objeto.
O editor pode ser qualquer um que dispusermos. O montador será o TASM macro
assembler da Borland, e o linker será o TLINK, também da Borland.
Nós devemos criar os programas fonte com a extensão .ASM para que o TASM
reconheça e o transforme no programa objeto, um "formato intermediário" do
programa, assim chamado porque ainda não é um programa executável e tão
pouco um programa fonte. O linker gera a partir de um programa .OBJ, ou da
combinação de vários deles, um programa executável, cuja extensão é
normalmente .EXE, embora possa ser .COM dependendo da forma como for montado
e ligado.
                                   
3.1.2.PROGRAMA�ÃO ASSEMBLY
Para construirmos os programas com o TASM, devemos estruturar o fonte de
forma diferenciada ao que fazíamos com o programa debug.
É importante incluir as seguintes diretivas assembly:
.MODEL SMALL
Define o meio de memória a usar em nosso programa
.CODE
Define as instruções do programa, relacionado ao segmento de código
.STACK
Reserva espaço de memória para as instruções de programa na pilha
END
Finaliza um programa assembly

Vamos programar
Primeiro passo
Use qualquer editor para criar o programa fonte. Entre com as seguintes
linhas:
Primeiro exemplo
; use ; para fazer comentários em programas assembly
.MODEL SMALL ;modelo de memória
.STACK       ;espaço de memória para instruções do programa na pilha
.CODE        ;as linhas seguintes são instruções do programa
  mov ah,01h ;move o valor 01h para o registrador ah
  mov cx,07h ;move o valor 07h para o registrador cx
  int 10h    ;interrupção 10h
  mov ah,4ch ;move o valor 4ch para o registrador ah
  int 21h    ;interrupçãoo 21h
END          ;finaliza o código do programa
Este programa assembly muda o tamanho do cursor.

Segundo passo
Salvar o arquivo com o seguinte nome: exam1.asm
Não esquecer de salvá-lo no formato ASCII.

Terceiro passo
Usar o programa TASM para construir o programa objeto.
Exemplo:
C:\>tasm exam1.asm
Turbo Assembler  Version 2.0  Copyright (c) 1988, 1990 Borland International
Assembling file:   exam1.asm
Error messages:    None
Warning messages:  None
Passes:            1
Remaining memory:  471k
O TASM só pode criar programas no formato .OBJ, que ainda não podem ser
executado...

 

Quarto passo
Usar o programa TLINK para criar o programa executável.
Exemplo:
C:\>tlink exam1.obj
Turbo Link  Version 3.0 Copyright (c) 1987, 1990 Borland International
C:\>
Onde exam1.obj ‚ o nome do programa intermediário, .OBJ. O comando acima
gera diretamente o arquivo com o nome do programa intermediário e a extensão
.EXE. É opcional a colocação da extensão .obj no comando.

Quinto passo
Executar o programa executável criado.
C:\>exam1[enter]
Lembre-se, este programa assembly muda o tamanho do cursor no DOS.
			--------------- // ---------------
                          
3.2.Processo Assembly.
3.2.1.Segmentos
3.2.2.Tabela de equivalˆncia
                                 
3.2.1.SEGMENTOS
A arquitetura dos processadores x86 força-nos a usar segmentos de memória
para gerenciar a informação, o tamanho destes segmentos é de 64Kb.A razão
de ser destes segmentos é que, considerando que o tamanho máximo de um número
que o processador pode gerenciar é dado por uma palavra de 16 bits ou registrador,
assim não seria possível acessar mais do que 65536 locais da memória usando 
apenas um destes registradores. Mas agora, se a memória do PC é dividida em 
grupos de segmentos, cada um com 65536 locais, e podemos usar um endereço ou
registrador exclusivo para encontrar cada segmento, e ainda fazemos cada endereço
de um específico slot com dois registradores, nos é possível acessar a quantidade
de 4294967296 bytes de memória.
Desta forma, para que o montador seja capaz de gerenciar os dados, se faz
necessário que cada informação ou instrução se encontre na área
correspondente ao seu segmento. O endereço do segmento é fornecido ao
montador pelos registradores DS, ES, SS e CS. Lembrando um programa no
Debug, observe:
1CB0:0102 MOV AX,BX
O primeiro número 1CB0, corresponde ao segmento de memória que está sendo
usado, o segundo é uma referência ao endereço dentro do segmento, é um
deslocamento dentro do segmento offset.
O modo usado para indicar ao montador com quais segmentos vamos trabalhar ‚
fazendo uso das diretivas .CODE, .DATA e .STACK.
O montador ajusta o tamanho dos segmentos tomando como base o n�mero de
bytes que cada instru‡�o assembly precisa, j  que seria um desperd�cio de
mem�ria usar segmentos inteiros. Por exemplo, se um programa precisa de
apenas 10Kb para armazenar dados, o segmento de dados seria apenas de 10Kb e
n�o de 64Kb, como poderia acontecer se feito manualmente.

                                   
3.2.2.TABELAS DE EQUIVALÊNCIA
Cada uma das partes numa linha de código assembly ‚ conhecida como token,
por exemplo:
MOV AX,Var
Aqui temos três tokens, a instrução MOV, o operador AX e o operador VAR. O
que o montador faz para gerar o código OBJ é ler cada um dos tokens e
procurar a equivalência em código de máquina em tabelas correspondentes,
seja de palavras reservadas, tabela de códigos de operação, tabela de
símbolos, tabela de literais, onde o significado dos mnemônicos e os
endereços dos símbolos que usamos serão encontrados.
A maioria dos montadores são de duas passagens. Em síntese na primeira
passagem temos a definição dos símbolos, ou seja, são associados endereços a
todas as instruções do programa. Seguindo este processo, o assembler lê MOV
e procura-o na tabela de códigos de operação para encontrar seu equivalente
na linguagem de máquina. Da mesma forma ele lê AX e encontra-o na tabela
correspondente como sendo um registrador. O processo para Var é um pouco
diferenciado, o montador verifica que ela não é uma palavra reservada, então
procura na tabela de símbolos, encontrando-a ele designa o endereço
correspondente, mas se não encontrou ele a insere na tabela para que ela
possa receber um endereço na segunda passagem. Ainda na primeira passagem é
xecutado parte do processamento das diretivas, é importante notar que as
diretivas não criam código objeto. Na passagem dois são montadas as
instruções, traduzindo os códigos de operações e procurando os endereços, e é
gerado o código objeto. 
Há símbolos que o montador não consegue encontrar, uma vez que podem ser
declarações externas. Neste caso o linker entra em ação para criar a
estrutura necessária a fim de ligar as diversas possíveis partes de código,
dizendo ao loader que o segmento e o token em questão são definidos quando o
programa ‚ carregado e antes de ser executado.
			--------------- // ---------------
                                      
3.3.Mais programas.
Outro exemplo
Primeiro passo
Use qualquer editor e crie o seguinte:
;exemplo2
.model small
.stack
.code
 mov ah,2h  ;move o valor 2h para o registrador ah
 mov dl,2ah ;move o valor 2ah para o registrador dl
            ;(‚ o valor ASCII do caractere *)
 int 21h    ;interrupção 21h
 mov ah,4ch ;função 4ch, sai para o sistema operacional
 int 21h    ;interrupção 21h
end         ;finaliza o programa
Segundo passo
Salvar o arquivo com o nome: exam2.asm
Não esquecer de salvar em formato ASCII.
Terceiro passo
Usar o programa TASM para construir o programa objeto.
C:\>tasm exam2.asm
Turbo Assembler  Version 2.0  Copyright (c) 1988, 1990 Borland International
Assembling file:   exam2.asm
Error messages:    None
Warning messages:  None
Passes:            1
Remaining memory:  471k
Quarto passo
Usar o programa TLINK para criar o programa executável.
C:\>tlink exam2.obj
Turbo Link  Version 3.0 Copyright (c) 1987, 1990 Borland International
C:\>
Quinto passo
Executar o programa:
C:\>exam2[enter]
*
C:\>
Este programa imprime o caracter * na tela.
 
			--------------- // ---------------
                                      
3.4.Tipos de instruções.
3.4.1.Movimento de dados
3.4.2.Operações lógicas e aritméticas
3.4.3.Saltos,laços e procedimentos
                                   
3.4.1.MOVIMENTO DE DADOS
Em qualquer programa há necessidade de se mover dados na memória e em
registradores da CPU; há vários modos de se fazê-lo: pode-se copiar os dados
da memória para algum registrador, de registrador para registrador, de um
registrador para a pilha, da pilha para um registrador, transmitir dados
para um dispositivo externo e vice-versa.
Este movimento de dados ‚ sujeito a regras e restri‡�es, entre elas:
*Não é possível mover dados de um local da memória para outro diretamente; é
necessário primeiro mover o dado do local de origem para um registrador e
então do registrador para o local de destino.
*Não é possível mover uma constante diretamente para um registrador de
segmento; primeiro deve-se mover para um registrador.
É possível mover blocos de dados através de instruções movs, que copia uma
cadeia de bytes ou palavras; movsb copia n bytes de um local para outro; e
movsw copia n palavras. A última das duas instruções toma os valores dos
endereços definidos por DS:SI como o grupo de dados a mover e ES:DI como a
nova localização dos dados.
Para mover dados há também estruturas chamadas pilhas, onde o dado é
introduzido com a instrução push e é extraído com a instrução pop.
Numa pilha o primeiro dado a entrar é o último a sair, por exemplo:
  PUSH AX
  PUSH BX
  PUSH CX
Para retornar os valores da pilha referentes à cada registrador ‚ necessário
seguir-se a ordem:
  POP CX
  POP BX
  POP AX
Para a comunicação com dispositivos externos o comando de saída é usado para
o envio de informações a uma porta e o comando de entrada é usado para
receber informação de uma porta.A sintaxe do comando de saída:
OUT DX,AX
Onde DX contém o valor da porta que ser usada para a comunicação e AX
contém a informação que ser enviada.A sintaxe do comando de entrada:
IN AX,DX
Onde AX é o registrador onde a informação ser  armazenada e DX contém o
endereço da porta de onde chegar a informação.
 
                                  
3.4.2.OPERAÇÕES LÓGICAS E ARITMÉTICAS
As instruçõess de operações lógicas são: and, not, or e xor. Elas trabalham a
nível de bits em seus operadores. Para verificar o resultado das operações usamos 
as instruções cmp e test. As instruções usadas para operações algébricas são: para
adição add, para subtração sub, para multiplicação mul e para divisão div.
Quase todas as instruções de comparaçãoo são baseadas na informação contida
no registrador de flag. Normalmente os flags do registrador que podem ser
manuseados diretamente pelo programador são os da direção de dados DF, usado
para definir as operações sobre cadeias. Uma outro que pode também ser
manuseado é o flag IF através das instruções sti e cli, para ativar e
desativar as interrupções.

 

                                   
3.4.3.SALTOS, LOOPS E PROCEDIMENTOS
Saltos incondicionais na escrita de programas em linguagem assembly são
dados pela instrução jmp; um salto é usado para modificar a sequência da
execução das instruções de um programa, enviando o controle ao endereço
indicado, ou seja, o registrador contador de programa recebe este novo
endereço. Um loop, também conhecido como interação, é a repetição de um processo um
certo número de vezes até atingir a condição de parada.
*****************************************************************************