Escolar Documentos
Profissional Documentos
Cultura Documentos
1 Introduo
Este texto constitui uma pequena introduo ao assembler NASM(Netwide Assembler). Embora
contenha algumas notas relacionadas com a arquitectura de computadores e programao em
baixo-nvel, no um manual de programao. Pretende ser apenas um auxiliar para apoiar os
primeiros passos na programao em assembly usando este assembler.
O primeiro conceito que importa esclarecer precisamente a distino entre aqueles dois termos
realados a itlico. Assim, o termo assembly refere-se linguagem de programao, que tambm
designada por linguagem de baixo-nvel, uma vez que se encontra intimamente relacionada com o
processador a que se destina. Deste modo, cada processador, de cada fabricante(Intel, AMD,
Motorola,...), tem o seu prprio assembly, j que cada um tem estrutura interna diferente, mas o termo
assembly aplica-se a todos eles (i.e. no h uma linguagem assemblyIntel ou assemblyAMD, tal
como existe Pascal ou C). O que acontece dizer-se que se est a utilizar o assembly do Pentium, do
Athlon, ou do Motorola68000. Em princpio, um programa que utilize o assembly do Pentium no ser
executado por um processador de outro fabricante, a menos que sejam compatveis entre si.
Pelo seu lado, o termo assembler (montador em ingls) refere-se a um programa que permite
facilitar o trabalho com a linguagem assembly, fazendo com que esta se assemelhe um pouco mais a
uma linguagem de alto-nvel. De facto, torna-se muito complicado para os programadores humanos
escrever programas usando a linguagem pura do processador (linguagem-mquina), a qual
constituda por um conjunto mais ou menos extenso de bits (ex: a instruo mov ah,40h, muito
usada em assembly, corresponde a 1011010010000000 - bits a nica coisa que as mquinas
entedem !). O assembler atribui nomes (mnemnicas) aos conjuntos de bits que constituem as
instrues do processador, facilitando a sua compreenso pelos humanos. O assembler tambm chama
a si a execuo de um conjunto de aces necessrias para que um programa possa ser executado
(p.ex. o controlo de certos registos do processador), escondendo essas operaes ao programador.
Antes de passar anlise dos aspectos mais relevantes relacionados com a escrita de programas em
assembly usando o NASM, convm rever alguns conceitos referentes ao tratamento da informao por
parte dos computadores digitais.
2 Codificao da informao
Os computadores digitais usam bits para representar a mais pequena quantidade de informao. De
facto, um bit (binary digit) assume apenas um de dois estados possveis designados por false e true,
habitualmente representados respectivamente por F e T ou 0 e 1 (neste texto ser utilizada a
segunda terminologia). Esta codificao diz-se binria precisamente porque existem apenas dois
estados possveis para um bit. Em termos de implementao fsica esses dois estados so traduzidos
pela no existncia de uma grandeza elctrica como corrente ou tenso para o caso do 0 e pela
existncia de um certo valor para essa grandeza, habitualmente o valor de tenso de 5V, para o caso do
1. Se com um bit podem ser representados dois estados (0,1), ento com dois bits podem
representar-se quatro estados (00,01,10,11), trs bits permitem oito casos, etc; de cada vez que se
acrescenta um bit duplicam os casos. A regra que com n bits podem codificar-se m = 2 n casos.
A expresso da significncia posicional constante do AnexoC, indica o modo como os bits podem
ser usados para representar valores numricos usando apenas os algarismos binrios 0 e 1, tal como as
pessoas o fazem usando os algarismos decimais de 0 a 9.
Os nmeros so frequentemente representados noutras bases para alm da binria, para simplificar
o seu tratamento. Como a informao contida num bit pequena (apenas 0 ou 1) torna-se necessrio
trabalhar com um grande nmero deles para representar informao realmente til. Assim, recorre-se
ao agrupamento dos bit em unidades maiores (byte, Kbyte,...) ou ainda representao dos valores
noutras bases de numerao, o que corresponde ao agrupamento dos bit em unidades maiores (p. ex.
cada algarismo hexadecimal formado por quatro algarismos binrios). A partir daqui define-se uma
aritmtica binria, que permite realizar as operaes aritmticas usando dados binrios, tal como na
aritmtica decimal.
A expresso da significncia posicional indica o modo como valores numricos decimais podem
ser representados em binrio e vice-versa; trata-se de uma relao matemtica entre nmeros, bem
definida e que no deixa ambiguidades na representao. Maiores dificuldades surgem na
representao em binrio de grandezas no numricas como, por exemplo, os caracteres alfabticos ou
os sinais de pontuao. Note-se que a necessidade de traduzir estes valores para binrio decorre do
facto de que os bits(zeros e uns) so o nico tipo de informao que os computadores digitais podem
armazenar e tratar. Ora no fcil estabelecer uma relao entre smbolos alfanumricos e valores
numricos, a menos que essa relao seja estabelecida de alguma forma arbitrria. Por exemplo, ao
carcter A pode ser atribudo o valor 00 ou 111 ou qualquer outro, sem que algum deles esteja mais
correcto que os outros. Deste modo surgiram vrias propostas de tabelas que relacionam os caracteres
alfanumricos com valores binrios, entre elas a tabela ASCII (American Standard Code for
Information Interchange). Esta tabela, que se encontra no AnexoA, indica o valor binrio
correspondente a cada um dos caracteres alfanumricos que o computador pode tratar (a verso
original usava 7 bits, permitindo codificar 27=128 smbolos entre letras, dgitos e sinais de pontuao,
sem acentos; posteriormente foi expandida para 8 bits codificando 28=256 smbolos, de modo a
contemplar os acentos e outros caracteres especiais). Outro exemplo a tabela UNICODE a qual
utiliza 16 bits para representar de forma internacional e nica qualquer smbolo, facilitando a escrita
do software (os primeiros 256 caracteres so iguais aos da tabela ASCII). O problema do UNICODE
que s suporta 64K (216=65536) smbolos, mas h mais de 200 000 smbolos em todas as lnguas do
mundo; embora no seja ainda universalmente usado, o Windows e Java j o usam como standard.
Seja qual for a tabela utilizada, os cdigos que a compem so os utilizados sempre que um
carcter alfanumrico recebido do teclado para ser armazenado num ficheiro, ou enviado para o
ecr ou para uma impressora.
1
O AnexoB descreve o modo como estes conceitos podem ser comprovados recorrendo ao utilitrio DEBUG
h e l l o hello
65h e
teclado 68h h
6Ch l
6Fh o
Situao diferente ocorre quando o valor introduzido pelo teclado corresponde a um valor
numrico, como um inteiro. Tomando como exemplo o valor 741 (valor em base decimal), tal como
no caso anterior cada tecla gera o cdigo ASCII que lhe corresponde, ou seja 37h+34h+31h. Se este
valor for armazenado num ficheiro de texto tudo se passa como anteriormente. Ao ler o ficheiro
aqueles cdigos so de novo convertidos para os caracteres ASCII e no ecr aparecer 741. O primeiro
aspecto que importa entender que o que aparece no ecr sempre texto, portanto 741 por assim
dizer a palavra 741 (tal como no caso anterior a palavra era hello), ou, dito de outro modo, trata-se
do smbolo 7, seguido do smbolo 4, seguido do smbolo 1. Cada um daqueles smbolos no tem
qualquer relao com os outros, apenas esto dispostos em sequncia; parece um nmero apenas
porque estamos habituados a interpretar como nmeros as sequncias de smbolos formadas por
algarismos.
Mas, e se este valor deve ser tratado como um nmero inteiro? Por exemplo se for necessrio
operar sobre ele, como multiplic-lo por outro? claro que no podem aplicar-se operaes
aritmticas sobre sequncias de smbolos, preciso fazer com que essas sequncias sejam nmeros.
No exemplo em estudo preciso fazer com que a sequncia 741 deixe de ser um 7 encostado a
um 4 por sua vez encostado a um 1 e passe a ser 7*102+4*101+1*100=741.
O que dever ento fazer um programa ao ler um valor para uma varivel do tipo inteiro? Enquanto
no se carrega na tecla Enter o buffer de teclado vai armazenando os cdigos ASCII das teclas que
vo sendo introduzidas (37h+34h+31h no exemplo). A partir do momento em que se carrega no Enter
indica-se mquina que a introduo do valor terminou e que a sequncia de cdigos deve ser
convertida para um inteiro. A primeira operao obter o valor numrico de cada algarismo a partir do
respectivo cdigo ASCII. Ora como o cdigo ASCII dos algarismos dado pela soma de 30h com o
prprio algarismo, basta retirar este 30h a cada cdigo lido, para obter o valor numrico. No exemplo
em estudo isso corresponde a fazer: 37h-30h=7, 34h-30h=4, 31h-30h=1. Como a mquina sabe que
foram introduzidas trs teclas, torna-se fcil aplicar a frmula 7*102+4*101+1*100 de modo a obter
741. Note-se que este 741 agora um valor numrico e no meramente trs caracteres alfanumricos
seguidos. Sendo assim, e para que possa sofrer operaes aritmticas as quais so necessariamente
O diagrama a seguir esquematiza o que acontece quando a sequncia de teclas 741 tratada
como uma cadeia de caracteres (texto) ou como um valor numrico (inteiro).
ficheiro de texto
37h 34h 31h
741
7 4 1 31h 1
34h 4
teclado 37h 7 37h 34h 31h
Converso Converso
p/binrio ficheiro de inteiros
p/ASCII
E5h 02h
74110=02E5h (little endian) 02E5h=74110
2
O termo endian tem origem no livro As viagens de Gulliver e refere-se questo de qual dos lados os ovos
devem ser quebrados.
N
teste.com (executvel)
3 Passo: executar o programa; verificar se o
resultado o esperado, caso contrrio o programa Executar
ainda contm erros que devem ser corrigidos. >teste
ERROS ? S
Fim
(*) Para executar o NASM pode ser usado um comando do tipo: nasm -f bin <filename> -o <output>
em que: -f bin significa que vai ser gerado um ficheiro binrio (correspondente extenso .COM)
<filename> o nome do ficheiro com o programa fonte
-o <output> especifica o nome do ficheiro de sada
Este comando, que ser usado para qualquer outro programa, um tanto extenso e sujeito a erros. Por
isso foi criado o ficheiro batch GO.BAT quer permite simplificar o seu uso.
O uso deste batch : >GO <ficheiro_fonte> (sem indicar a extenso)
exemplo >GO teste (o ficheiro tem extenso asm, mas omitiu-se ao chamar o GO)
NOTA: nas aulas prticas este processo ser realizado de forma simplificada, recorrendo-se ao uso de
um IDE (Integrated Development Environment), que permite editar e assemblar dentro do mesmo
aplicativo (NasmIDE).
Os programas executveis gerados pelo NASM so do tipo .COM, ficheiros em binrio puro, os
quais devem ser carregados e executados a partir do endereo 100h. Para esse efeito, todos os
programas devem comear com a directiva org 100h, seguidos de trs seces (text, data e bss)
segundo o esquema abaixo:
section .text
contm as instrues executveis
( instrues )
section .data
dados que tm valor inicial
( dados inicializados )
section .bss
reserva espao para guardar dados
(dados no inicializados)
Estas seces podem ser colocadas por outra ordem (ao criar o programa executvel, o NASM
acaba sempre por colocar a section .text no incio)
5.1 Comentrios: comeam por ; tudo o que lhe seguir ignorado pelo assembler. Podem ser
aplicados a uma linha inteira ou apenas a parte. boa ideia comentar as partes do programa cujo
significado seja menos evidente (principalmente ao fim de algum tempo), como sejam os algoritmos
utilizados, significado das variveis, etc.
<instruo> uma das instrues (mnemnicas) do NASM (ex: mov, add, jmp)
Exemplo:
mov al , 5 ;coloca o valor inteiro 5 no registo al
cont: dec al ;define a label cont e decrementa de uma unidade o valor do registo al
jnz cont ;salta (jump) para a linha anterior (aonde foi definida a label cont) se no
;resultou zero da ltima operao aritmtica realizada (que foi dec al)
3
O NASM dispe de vrias outras; apresentam-se aqui apenas as que vo ser usadas nas aulas prticas
NOTA: o nome de uma varivel representa o endereo de memria que foi atribudo a essa varivel,
mais propriamente o endereo do byte inicial dessa varivel.
Ex: variveis var1 tipo byte, var2 do tipo word (2 byte) e msg do tipo cadeia de caracteres:
endereos .
. contedo da
de memria .
var1 = E5h 1byte
varivel var1
n-1
var2 = 0001h endereo da varivel var1 n E5h
endereo da varivel var2 n+1 01h contedo da
msg = UBI n+2 00h varivel var2
endereo da varivel msg n+3 55h(U)
n+4 42h(B) contedo da
n+5 49h(I) varivel msg
n+6
n+7 .
.
.
referncias ao endereo das variveis (i.e., sua posio na memria ) no levam parntesis
ex: mov dx, ind2 ;move o endereo da varivel ind2 para o registo dx (dx n+3)
endereos efectivos: qualquer operando de uma instruo que faz referncia memria.
Exs:
mov al, [msg] ;coloca no registo al o 1 byte do contedo da varivel msg (al 55h=U)
mov ah, [msg+1] ;coloca no registo ah o 2 byte do contedo da varivel msg (ah 42h=B)
mov bl, [msg+2] ;coloca no registo ah o 3 byte do contedo da varivel msg (bl 49h=I)
5.6 O NASM no memoriza os tipos das variveis: quando se declaram variveis usando as
pseudo-instrues para dados inicializados ou no-inicializados, o NASM apenas memoriza o
endereo de memria que foi atribudo varivel (para lhe poder aceder), mas esquece
imediatamente o tipo dessa varivel. Isto implica que o NASM obriga a que se indique o tipo de
uma varivel sempre que esta referida.
Ex1:
bytevar: resb 1 ;declara a varivel bytevar como sendo um byte (8 bit)
mov [bytevar],10 ;provoca erro, pois o NASM esqueceu o tipo de bytevar, no conseguindo
;atribuir-lhe o valor 10
mov byte [bytevar],10 ;assim o NASM j consegue atribuir o valor varivel
Ex2:
wordvar: resw 1 ;declara a varivel wordvar como sendo uma word (16 bit)
mov [wordvar],100 ;provoca erro, pois o NASM esqueceu o tipo de wordvar, no
;conseguindo atribuir-lhe o valor 100
mov word [wordvar],100 ;assim o NASM j consegue atribuir o valor varivel
6 Tipos de dados
1)Number: o NASM usa a numerao decimal por defeito, ou seja, quando se escreve um nmero ele
interpreta-o como estando em decimal; so ainda possveis a notao hexadecimal, octal e binria.
2)Character: uma constante deste tipo consiste num mximo de quatro caracteres entre plicas ou aspas
(se forem usadas as plicas dentro da constante podero aparecer as aspas e vice-versa)
Ex: ab , abcd , xy, yx
3)String: s so possveis de usar com as pseudo-instrues DB, DW, DD. Uma constante do tipo
string semelhante a uma do tipo character, apenas maior.
Ex:
msg db Ola mundo db Ola , , mundo - string
msg1 db Bola db B,o,l,a - uma string devido a pertencer pseudo-instruo db,
apesar de que tendo s quatro caracteres poderia ser considerada character
org 100h
section .text
mov ah, 40h ;ah 40h (funo de escrita)
mov bx, 1 ;bx 1 (1=ecr)
mov cx, 9 ;cx 9 (nmero de caracteres a escrever )
mov dx, msg ;dx endereo da varivel "msg" (dx aponta para os dados a escrever)
int 21h ;provoca a execuo da aco (escrita)
mov ah, 4Ch ;ah 4Ch (funo para terminar a execuo de um programa)
int 21h ;provoca a execuo da aco (termina o programa)
section .data
msg db Ola mundo ;define a varivel "msg"
ORG 100h
SECTION .TEXT
MOV ah, 40h ;ah 40h (FUNO DE ESCRITA)
Mov BX, 1 ;bx 1 (1=ecr)
MOV cx, 9 ;cx 11 (nmero de caracteres a escrever )
mOV DX, MSG ;dx endereo da varivel "msg" (dx aponta para os dados a escrever)
INT 21h ;PROVOCA a execuo da aco (escrita)
moV AH, 4Ch ;ah 4Ch (funo para terminar a execuo de um programa)
INT 21H ;provoca a EXECUO da aco (termina o programa)
SECTion .DATA
msg DB Ola mundo ;DEFINE A VARIVEL "msg"
Programa Execuo
programa termina
instrues assembly CPU l as instrues e executa-as
1) atribuio de valores apropriados aos registos do processador (ver pg. 19), de acordo com a funo
pretendida - estas funes esto contidas no sistema operativo e so chamadas atravs de interrupts
encontrando-se tabeladas a partir da pg. 20. A tabela contm o cdigo da funo e uma breve
descrio e ainda os valores de entrada e os registos aonde devem ser colocados bem como os valores
de sada que a funo devolve nos registos do processador.
2) chamada ao interrupt - note-se que a atribuio de valores aos registos de entrada s por si no
provoca a execuo da aco, sendo necessrio executar o interrupt correspondente aco pretendida
cont. do exemplo anterior
int 21h ao chegar a esta instruo (interrupt) o processador vai verificar os valores contidos nos
registos (que foram l previamente colocados) e ento executa a aco correspondente, neste caso uma
aco de escrita no ecr; se esta instruo no for colocada no programa, o processador no far aco
alguma, mesmo que os valores dos registos de entrada estejam correctamente atribudos.
3) de modo a terminar correctamente a execuo dos programas e o CPU poder continuar com as suas
tarefas, todos os programas devem terminar com a sequncia (caso contrrio o PC pode bloquear):
mov ah, 4Ch ;ah 4Ch (funo para terminar a execuo de um programa)
int 21h ;provoca a execuo da aco (termina o programa)
NOTA: ateno escrita das instues, em particular das chamadas aos interrupts
ex: int 21h contm pelo menos um espao entre int e 21h e no esquecer o h
O Debug um utilitrio que permite executar um conjunto de funes de baixo-nvel, tais como
criar e executar pequenos programas em assembly, testar se um programa funciona correctamente,
executando-o passo a passo, aceder directamente memria ou ao disco, etc. Com o DEBUG
possvel espiar o que se passa no interior da mquina.
O Debug funciona em modo DOS(Disk Operating System) pelo que preciso abrir uma janela
deste tipo para o executar. Para o fazer deve seleccionar MS-DOS prompt no menu
Iniciar\Programas do Windows (isto pode variar um pouco com a verso do sistema operativo). O
Debug chama-se escrevendo somente debug sem argumentos ou ento colocando frente o nome de
um ficheiro que se quer tratar. Em qualquer caso o prompt muda para "-" indicando que o programa
est espera de comandos. Um desses comando o ? que a ajuda e mostra os comandos
disponveis. Outro comando o Q que permite voltar ao DOS; uma vez a retorna-se ao Windows
escrevendo exit.
Pessoas Computadores
Facilidade no reconhecimento de smbolos,
Apenas dois estados bsicos: ligado(0) e desligado(1)
estados ou nveis
Base decimal (B=10) Base binria (B=2)
De acordo com a expresso de significncia posicional que rege os sistemas de numerao, tem-se
que para um cdigo binrio constitudo por n bits, o seu valor em decimal (base 10) :
n
M 10 = Ai * B i = An * B n + An 1 * B n 1 + ... + A1 * B 1 + A0 * B 0
i =0
Note-se que para um certo nmero n de bits o maior valor decimal representado 2n-1
O caso n=10 (Kbit) assume especial importncia. O prefixo K significa 1000=103 em decimal, em
que 10 a base da numerao decimal e 3 o expoente a que esta deve ser elevada para obter 1000.
De acordo com este princpio, para em binrio obtermos o valor de K, deveramos elevar a base 2 a um
expoente tal que se obtivesse 1000, ou seja 1000=2n, s que no existe nenhum expoente inteiro que
verifique aquela relao; o valor mais prximo 10, obtendo-se 210=1024, pelo que em binrio
K=1024.
240 1024*1Gbyte=1 099 511 627 776 byte T (Tera) - Tbyte 1012
2)ENDEREOS
SP Stack Pointer: controle da pilha (stack)
BP Base Pointer: registo base de endereamento
SI Source Index: indexador de origem (strings)
3)SEGMENTO
CS Code Segment: acesso ao cdigo
4)CONTROLO
IP Instruction Pointer: indica a localizao das instrues na memria
FLAGS Indicadores do estado do processador
OF DF IF TF SF ZF AF PF CF
As flags indicam o estado do processador, sendo afectadas por certas operaes como as aritmticas e
lgicas. TF, IF e DF so flags de comando (so instrues do utilizador ao processador); as restantes
so flags de status (destinam-se a serem lidas para testar a ocorrncia do acontecimento respectivo).
AH=10H
Sada:
DH=valor actual de Red (R)
CH=valor actual de Green (G)
CL=valor actual de Blue (B)
Sada Destri: AX, SP, BP, SI, DI
NOTAS: 1) os modos marcados a cinza sero os utilizados nas aulas prticas (modo 03h = default)
2) modos acima de 10CH no so suportados por todas as cartas VGA