Programando em
Programando em
ASSEMBLY
ASSEMBLY
Uma introdução à programação em Assembly
Uma introdução à programação em Assembly
Arthur Xavier Gomes Ribeiro
Arthur Xavier Gomes Ribeiro
Índice
Introdução ... 4
Registradores ... 4
Instrução MOV ... 5
Instrução LEA ... 5
Interrupções ... 5
Instruções ADD, SUB, MUL e DIV ... 6
Instrução JMP ... 7
O Comando CMP ... 7
A Pilha, o PUSH e o POP ... 8
O DEBUG do DOS ... 8
Primeiro Programa ... 9
A Estrutura de um programa .EXE ... 10
Hello World ... 11
Turbo Assembler ... 11
Introdução
Assembly é uma linguagem de baixo nível, ou seja, ela se comunica diretamente com o processador, sem nenhum tipo de intermediário, apenas o Sistema Operacional .
A linguagem Assembly é uma notação que pode ser compreendida para os opcodes (códigos operacionais da máquina). As instruções dadas ao processador na linguagem Assembly são chamadas de Mnemônicos, pois representam palavras para auxiliar a memorização dos comandos.
Assembly não é uma linguagem compilada, e sim montada usando-se um montador ou Assembler . Isso acontece pois as instruções Assembly correspondem às instruções de máquina de uma forma de 1 para 1, o que acontece no processo de montagem, é simplesmente uma pequena transformação ou tradução do código Assembly diretamente para o código de máquina.
Registradores
A linguagem Assembly , como vimos, é constituída de pequenas instruções chamadas de mnemônicos. Estas instruções servem para mover dados, somar dados, subtrair, dividir, multiplicar, comparar, saltar para um ponto do programa, etc.
Para armazenar valores, são necessários os registradores, que são endereços de memória encarregados de guardar ou receber dados. Os principais registradores de Assembly 16-bits são: AX, BX, CX, DX, DS, ES, SS, CS,SI, DI, BP e SP. Cada um deles (exceto DS, ES, SS, CS, SI, DI, BP e SP) podem guardar 2 bytes, sendo o primeiro byte, ou byte mais alto: AH, BH, CH e DH. E o último byte, ou byte mais baixo: AL, BL, CL, e DL.
Registrador 16-bits
Byte Alto Byte Baixo
AX AH AL
BX BH BL
CX CH CL
DX DH DL
Cada registrador em Assembly tem uma função específica. Vejamos a função de cada um:
AX – Registrador A cumulador
BX – Registrador B ase
CX – Registrador C ontador
DX – Registrador de D ados
DS – Registrador de S egmento de D ados
ES – Registrador de S egmento E xtra
SS – Registrador de S egmento de Pilha/ S tack
CS – Registrador de S egmento de C ódigo
SI – Registrador de Índice da Fonte/ S ource dos Dados
DI – Registrador de Índice do D estino dos Dados
BP – Registrador de P onteiro de B ase
Instrução MOV
A instrução MOV serve para MOVER dados de um lugar para o outro. Sua sintaxe é a seguinte:
MOV destino,fonte
Os seguintes movimentos de dados são permitidos por esta instrução:
MOV memória,acumulador MOV acumulador,memória
MOV registrador de segmento,memória/registrador MOV memória/registrador,registrador de segmento MOV registrador,registrador MOV registrador,memória MOV memória,registrador MOV registrador,dado MOV memória,dado Exemplo:
MOV AX,0241h ;mov registrador,dado
MOV AX,AX ;mov registrador,registrador
MOV DS,AX ;mov reg. De segmento,registrador MOV ES,AX ;mov reg. De segmento,registrador MOV DL,41h ;mov registrador,dado
MOV [BX],DL ;mov memória,registrador
Instrução LEA
A Instrução LEA (Load Effective Address ) carrega o endereço do operador fonte para o destino. Sua sintaxe é a seguinte:
LEA destino,fonte
O uso desta instrução é similar ao uso de MOV destino,offset fonte, mas é mais simplificada.
Interrupções
Interrupções são pausas geradas pelo programa para que a BIOS se dedique ao programa executando suas funções de entrada/saída. Em Assembly , o comando para se usar uma interrupção é INT. Sua sintaxe é:
INT numero_da_interrupção
As Interrupções tem várias funções específicas, que podem ser escolhidas através do valor contido no registrador AH.
A tabela a seguir mostra as principais funções da INT 21h do DOS:
AH Descrição Retorno/Parâmetro 00h Termina o Programa (DOS 2.0 ou anterior)
-01h Leitura do teclado com eco na tela AL = caracter 02h Escreve caracter na tela DL = caracter 07h Leitura do teclado sem eco
Ignora CTRL-Break AL = caracter 08h Leitura do teclado sem eco
Reconhece e executa CTRL-Break AL = caracter 09h Escreve string na tela DS = ponteiro para
string com fim $ 0Ah* Leitura do teclado em buffer DS = ponteiro para
buffer de leitura 4Ch Termina o Programa (mais recomendada)
-• O buffer para leitura do teclado deve ter o formato:
|numero maximo de caracteres | numero de caracteres lidos | string
Exemplo:
mov ah,02h
mov dl,41h ;caracter = A
int 21h ;escreve caracter na tela mov ah,4ch
int 21h ;finaliza o programa
Instruções
ADD, SUB, MUL e DIV
A instrução ADD é usada para somar dois registradores, ou um registrador e um dado. Sua sintaxe é a seguinte:
ADD registrador,registrador ADD registrador,dado
A instrução SUB é usada para, ao contrario da instrução ADD , subtrair dois registradores, ou um registrador e um dado. Sua sintaxe é a mesma da instrução ADD.
A instrução MUL é usada para multiplicar o registrador acumulador (AX) por um outro registrador. O resultado da multiplicação é armazenado em AX, e o resto em DX. Sua sintaxe é a seguinte:
MOV AX,3 MOV BX,2
MUL BX ;multiplica o valor de AX pelo valor de BX
A instrução DIV é usada para, ao contrário da instrução MUL, dividir o registrador acumulador por um outro registrador. Sua sintaxe é a seguinte:
MOV AX,6 MOV BX,3
Instrução JMP
A instrução JMP é usada para fazer um salto incondicional de um ponto do programa para outro, isto é, alterar a execução do programa. Sua sintaxe é a seguinte:
JMP segmento ;no TASM, MASM ou NASM JMP endereço ;no DEBUG do DOS
O Comando CMP
O comando CMP compara dois registradores, ou um registrador e um valor e permite fazer um salto condicional usando as seguintes instruções:
JG – J ump if Greater
JGE – J ump if Greater or Equal JNG – J ump if Not Greater
JNGE – J ump if Not Greater or Equal JE – J ump if Equal
JZ – J ump if Zero
JNE – J ump if Not Equal JNZ – J ump if Not Zero JL – J ump if Lower
JLE – J ump if Lower or Equal JNL – J ump if Not Lower
JNLE – J ump if Not Lower or Equal
Exemplo:
MOV AX,0005h MOV BX,0000h
CMP AX,BX ;compara AX com BX
JGE 0100 ;salta para o endereço 0100 se maior ou igual
---MOV AH,01h INT 21h
CMP AL,2 ;compara AL com 2
A Pilha, o PUSH e o POP
A Pilha de Dados é uma estrutura muito importante em assembly, pois ela nos permite armazenar inúmeros dados de forma simples e eficiente. Podemos imaginar a Pilha como uma pilha de pratos, o primeiro a ser colocado, é o último a ser tirado, senão os pratos caem.
A instrução PUSH armazena um WORD (2 bytes ou 16-bits) na Pilha. Sua sintaxe é a seguinte:
PUSH registrador/word
A instrução POP retira um WORD da Pilha e o armazena em um registrador ou em outro WORD. Sua sintaxe é a seguinte:
POP registrador/word
Exemplos:
MOV AH,01h INT 21h
MOV AH,00h ;zera-se o valor de AH pois AX contém AH e queremos apenas o valor de AL
PUSH AX ADD CX,1 CMP CX,5
JL 0100 ;0100 é o endereço do início do programa no DEBUG do DOS POP AX MOV AH,02h INT 21h SUB CX,1 CMP CX,0
JG 0114 ;a cada linha o endereço aumenta em 2
MOV AH,4Ch INT 21h
O DEBUG do DOS
O DEBUG é uma ferramenta interessante do DOS pois ele apresenta um Assembler , isto é, um montador sequencial de instruções Assembly . Para se iniciar o Assembler do DEBUG , a linha de comando é:
C:\>debug -A
0CFF:0100
Assim que iniciado o Assembler , basta digitar as instruções. Para terminar de editar o código, deve-se apertar ENTER duas vezes. Para executar o código, deve-se digitar –G. Para salvar seu programa em formato .COM, deve-se digitar –W. E, para sair do debug, deve-se digitar –Q.
Primeiro Programa
O nosso primeiro programa no DEBUG deverá pedir o usuário para apertar uma tecla sem escrevê-la na tela. O programa deverá então checar se o usuário apertou a tecla ENTER. Se não, ele deve escrever a letra A na tela. Se sim, deve terminar o programa sem escrever nada.
Tente fazer este programa. A resposta está no final desta apostila.
A Estrutura de um programa
.EXE
A estrutura de um programa .EXE é diferente da estrutura de um programa no DEBUG do MS-DOS . Isto, porque, o programa .EXE é dividido em segmentos.
Para criar programas .EXE, usaremos o montador Turbo Assembler ou TASM, da Borland (vide pág. 12)
A diretiva .MODEL
A diretiva .model define o modelo de memória de um programa .EXE, e deve ser incluída no início do código.
Os modelos de memória são os seguintes:
.model tiny
.model small ;usaremos small para nossos programas .model medium
.model compact .model large .model huge
.model flat ;usado em aplicativos Win32
A diretiva .STACK
A diretiva .stack define o tamanho da pilha. Pode ser usada da seguinte maneira:
.stack tamanho_da_pilha
A diretiva .DATA
A diretiva .data é usada para declaração de variáveis. Pode ser usada da seguinte maneira:
.data
var1 db 10 ;db = define byte. Valor inicial = 10 var2 db ? ;Valor inicial = não definido
var3 db 10 dup(‘$’) ;cria um vetor de tamanho 10 e o preenche com $
var4 dw 32767 ;dw = define word. Tamanho 2 bytes var5 dd 65536 ;dd = define double word. 4 bytes string db ‘String,’$’ ;cria uma string. Terminador $
A diretiva .CODE
A diretiva .code é usada para demarcar o início do código. O código deve começar a ser executado a partir de um segmento:
.code
main: ;segmento de inicio. Pode ter qualquer nome end main ;termina o segmento main
Hello World
O programa a seguir escreve a mensagem “Hello World” na tela e executa uma pequena pausa ao final:
.model small .stack 100h .data msg db 'Hello World','$' .code main: mov ax,@data mov ds,ax mov es,ax mov ah,09
lea dx,msg ;mov dx,offset msg int 21h mov ah,08h int 21h mov ah,4ch int 21h end main
Salve o como hello.asm e compile-o usando o TASM.
Turbo Assembler
O Turbo Assembler da Borland (TASM) é um montador Assembly . Para montar programas usando esta ferramenta, deve-se usar a linha de comando do DOS.
Para montar um arquivo .obj deve-se usar a seguinte linha de comando:
C:\TASM\BIN>TASM hello.asm
Para linkar o arquivo .obj, isto é, transforma-lo em .exe, deve-se usar a deve-seguinte linha de comando:
C:\TASM\BIN>TLINK hello.obj
Como este processo é trabalhoso, é mais fácil usar um arquivo de Script do DOS, um arquivo .bat como este:
@echo off
set program=hello cls
echo ---echo Backup...
copy /v %program%.asm /a %program%.bak /a echo
echo ---..\..\bin\TLINK %program%.obj echo ---pause cls %program%.exe exit
O Script acima faz uma cópia de segurança do arquivo .asm, monta-o usando o TASM, linka-o usando o TLINK e em seguida executa-o, facilitando o uso das linhas de comando.
Apêndice: Primeiro Programa
O código do Primeiro Programa é o descrito abaixo:
0D03:0100 mov ah,08 0D03:0102 int 21 0D03:0104 cmp al,0d 0D03:0106 jne 010A 0D03:0108 je 0112 0D03:010A mov ah,02 0D03:010C mov dl,41 0D03:010E int 21 0D03:0110 jmp 0100 0D03:0112 mov ah,00h 0D03:0114 int 21 0D03:0116