You are on page 1of 22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

Regis Mainframe
example menu

MVS
Introducao
Comandos
Mensagens
Tasks de MVS

JES

Create account or Sign in

Search this site

Search

contact

Assembler Intel Introduo


Este um curso de Assembler, para intel, retirado de um site, que est citado no fim da
pagina, por isso no tenho tanto conhecimento a respeito do assunto, mas espero
realmente que ajude a tirar dvidas a respeito.

O que Assembler?
Assembler conseguiu ser uma das minhas linguagens favoritas para trabalhar.
No que seja uma linhguagem fcil no incio, mas quando voc fica familiar com ela,
voc entende o quo lgica ela .

Introduo
Comandos
Mensagens

IMS
IMS Introduo
Ferramentas
Mensagens de IMS

Assembler uma linguagem de baixo nvel, que voc pode usar em seus programas
para acelerar tarefas lentas. Basicamente ela consite de sentenas que representam
instrues em linguagem de mquina, e, como ela est prxima ao cdigo de mquina,
ela rpida.
H muito tempo atrs, quando o 8086 apareceu (sim, existiam humanos na Terra nessa
poca:), programar no era uma tarefa fcil. Quando os primeiros computadores foram
desenvolvidos, a programao tinha que ser feita em cdigo de mquina, que _no_ era
uma tarefa fcil, e assim o Assembler nasceu.

CICS
Por que us-lo?
CICS Introduo
Mensagens
Comandos

DB2
DB2 Introduo
Mensagens

JOB
Introduo
JCL

Ferramentas de
Schedule

Como eu disse antes, Assembler veloz. Ele tambm permite a voc falar com a
mquina a nvel de hardware, e lhe d muito maior controle e flexibilidade sobre o PC.
Uma das outras vantagens do Assembler que ele permite a voc impressionar seus
amigos com pginas de cdigo aparentemente incompreensvel.
No est vendo eles aglomerados em volta de voc e impressionados/rindo de sua
nerdeza? :)

LIO 1 - Registradores
Quando voc est trabalhando com Assembler, voc tem que usar registradores.
Voc pode imagin-los como sendo vari veis j definidas para voc. Os mais comuns
esto listados abaixo:
AX - o acumulador. Compreende AH e AL, os bytes alto e baixo de AX. Comumente
usado em operaes matemticas e de E/S.
BX - a base. Compreende BH e BL. Comumente usado como uma base ou registrador
apontador.

Introduo

CX - o contador. Compreende CH e CL. Usado frequentemente em loops.

Autosys

DX - o deslocamento, similar ao registrador de base. Compreende DH e DL. Acho que


voc est pegando o esprito da coisa agora.

Ca-7
Comandos de Ca-7
Control_M Mainframe
Control_M Desktop
Control_M Active Schedule
Jobmaster
OPC
http://regismain.wikidot.com/assembler

Estes registradores so definidos como registradores de uso geral pois podemos


realmente armazenar qualquer coisa que quisermos neles. So tambm registradores de
16 bits, o que significa que podemos armazenar um inteiro positivo de 0 a 65535, ou um
inteiro com sinal de -32768 to 32768.
Incidentalmente, o assunto do alto e do baixo byte destes resgistradores causou muita
confuso no passado, logo, tentarei dar alguma explicao aqui.
1/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

ZEKE
Cdigos de Abend

FERRAMENTAS
DO SISTEMA
SDSF, ISPF, TSO e Dataset
IOF
SAM

SHUTDOWN e IPL
Introducao
Comandos e Procedimentos

HARDWARE
Tipos de Device
Configuracoes
Comandos
Mensagens
Tasks De Hardware
DASD Ref Codes

AX tem um intervalo de 0 at FFFFh. Isto significa que voc tem um intervalo de 0 at


FFh para AH e AL. (Se sabe pouco sobre hexadecimal, no se preocupe. O prximo
tutorial vai falar sobre ele.)
Agora, se ns tivermos que armazenar 0A4Ch em AX, AH conter 0Ah, e AL conter
4Ch. Sacou? Este um conceito muito importante, e eu falarei sobre ele mais
profundamente no prximo tutorial.
Os registradores de segmento: - ta da!
Estes so outros registradores que ns no vamos ver nos primeiros tutorias, mas
vamos v-los em maior profundidade mais tarde. Eles so imensamente teis, mas
podem ser tambm perigosos.
*CS** - o segmento de cdigo. O bloco de memria onde o cdigo armazenado.
NO brinque com esse, a menos que saiba o que est fazendo.
DS - o segmento de dados. A rea na memria onde os dados so armazenados.
Durante operaes de bloco, quando grandes blocos de dados so movidos, este o
segmento a que a CPU comumente se refere.
ES - o segmento extra. Apenas outro segmento de dados, mas este comumente
usado quando se quer acessar o vdeo.
SS - no, no o exrcito alemo. o segmento de pilha, em que a CPU armazena
endereos de retorno de subrotinas. Tome cuidado com ele. :)
Alguns outros que voc vai comumente usar:

VTAM
Introduo
Tasks do VTAM
Mensagens
Comandos de VTAM

STORAGE
Storage
Mensagens Storage
HSM
Comandos HSM
VSAM

PRODUTOS CA

SI - o ndice de fonte. Frequentemente usado para movimentaes de blocos de


instrues. Este um ponteiro que, com um segmento, geralmente DS, usado pela
CPU para leitura.
DI - o ndice de destino. Novamente, voc o usar muito. Um outro ponteiro que, com
um segmento, geralmente ES, usado para escrita pela CPU.
BP - o apontador da base, usado em conjunto com o segmento de pilha. Ns no vamos
us-lo muito.
SP - o apontador da pilha, comumente usado com o segmento de pilha. NO brinque
com isso de jeito nenhum. :|
Por enquanto voc deveria saber o que so registradores. H outros registradores
tambm, e coisas conhecidas como flags, mas ns no iremos a eles agora.
-

LIO 2 - O conjunto de instrues do 8086:


PRODUTOS CA
CAVIEW
CASPOOL
CA-SMR
SYSVIEW

SEGURANA

Okay, ento voc j aprendeu sobre registradores, mas, como us-los, e como se
codifica em Assembler? Bem, primeiro voc precisa de algumas instrues. As seguintes
instrues podem ser usadas em todas as CPU's do 8086 para cima.
MOV <dest>, <valor> - MOVE. Esta instruo permite MOVER um valor para uma
posio na memria.
Ex.: MOV AX, 13h

Segurana
RACF

AUTOMAO

Isso deveria mover 13h (19 em decimal) para o registrador AX. Logo, se AX valia antes
0, ele agora seria 13h.
ISSO APENAS MOVE UM VALOR PARA UM REGISTRADOR, NO FAZ NADA MAIS.
Ex.: (Em Pascal) AX := $13;

Automao
INT <nmero> - INTERRUPO. Esta instruo gera uma interupo.
http://regismain.wikidot.com/assembler

2/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

OUTRAS TASKS
DE SISTEMA
OUTRAS TASKS

MQ Series
MQ Series Introducao
MQ Series Comandos e
Mensagens

ASSEMBLER
Assembler

Voc pode pensar nisso como sendo quase uma procedure.


Ex.: INT 10h
Geraria a interrupo 10h (16 em decimal). Agora, o que isso faria depende do contedo
do registrador AH, entre outras coisas. Por exemplo, se AX = 13h e a interrupo 10h
foi gerada, o vdeo seria colocado no modo 320x200x256.
Mais precisamente:
AH seria igual a 00 - seleciona a subfuno do modo, e AL seria igual a 13h - modo
grfico 320x200x256.
Contudo, se AH = 2h, e a interrupo 16h foi gerada, isso instruiria a CPU para checar
se alguma tecla pressionada est no buffer do teclado.
Se AH = 2h, e BH = 0h e a interrupo 10h foi gerada, ento a CPU moveria o cursor
para a posio X em DL e posio Y DH.
NO SE PREOCUPE COM ISSO POR ENQUANTO! NS FALAREMOS NISSO MAIS TARDE,
COM MAIS DETALHES.

CONTADOR

ADD <dest> <valor> - ADICIONA. Esta instruo soma um nmero ao valor


armazenado em dest.
Ex: MOV AX, 0h ; AX agora igual a 0h
ADD AX, 5h ; AX agora igual a 5h
ADD AX, 10h ; AX agora igual a 15h

Welcome page

Bem simples, no?

What is a Wiki Site?

SUB <dest> <valor> - SUBTRAI. Acho que d pra voc adivinhar o que isso faz.

How to edit pages?


How to join this site?
Site members
Recent changes
List all pages
Page Tags
Site Manager

Page tags
It seems you have no tags
attached to pages. To
attach a tag simply click
on the tags button at the
bottom of any page.

Add a new page

Ex: MOV AX, 13h ; AX agora igual a 13h (19 dec)


SUB AX, 5h ; AX agora igual a 0Eh (14 dec)
DEC <registrador> - DECREMENTA algo.
Ex: MOV AX, 13h ; AX agora igual a 13h
DEC AX ; AX agora igual a 12h
INC <registrador> - INCREMENTA algo.
Ex: MOV AX, 13h ; Adivinha
INC AX ; AX = AX + 1
JMP <posio> - PULA para uma posio.
EG: JMP 020Ah ; Pula para a instruo em 020Ah
JMP @MyLabel ; Pula para @MyLabel.
NO SE PREOCUPE SE ISTO UM POUCO CONFUSO - VAI FICAR PIOR! H OUTRAS 28
INSTRUES JUMP PARA APRENDER, TALVEZ MAIS. FALAREMOS NELAS MAIS TARDE.
CALL <procedimento> - CHAMA uma subfuno.

new page
edit this panel

EG: Procedure MyProc;


Begin { MyProc }
{}
End; { MyProc }
Begin { Main }
Asm
CALL MyProc ; Adivinha o que isso faz!
End;

http://regismain.wikidot.com/assembler

3/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

End.
Ou: CALL F6E0h ; Chama subfuno em F6E0h
LOOP <rtulo/label> - Faz LOOPS (repetio) durante um certo tempo.
EG: MOV CX, 10h ; Isto o porque de CX ser
; chamado de registro CONTADOR.
; 10h = 16
@MyLabel:
; alguma coisa
; mais coisa
LOOP @MyLabel ; At que CX = 0
; Note: CX decrementado
; a cada vez. No decremente-o
; voc mesmo (DEC CX).
; ISSO DEVERIA SE REPETIR 16 vezes - i.e., 10 em hexadecimal.
LODSB - Carrega um byte
LODSW - Carrega uma word
STOSB - Armazena um byte
STOSW - Armazena uma word
Estas instrues so usadas para pr ou conseguir algo numa posio na memria. O
registrador DS:SI, (lembra que ns falamos sobre isso antes, sobre SI ser o ndice de
fonte?), aponta para a localizao de onde queremos obter os dados, e DS:DI aponta
para onde colocaremos informaes.
claro, no somos obrigados a usar DS - poderia ser ES por exemplo.
Meu procedimento PutPixel colocar um byte em ES:DI.
De qualquer modo, imagine que temos a seguinte configurao na memria:
Posio na memria 06 07 08 09 10 11 12
Valor 50 32 38 03 23 01 12
Quando ns usamos LODSB ou STOSB, ele retorna ou pega um nmero de AL.
Assim, se DS:SI apontava para 07 e executssemos uma instruo LODSB, AL seria
agora igual a 32.
Agora, se ns apontssemos DS:DI para 11, colocando, diria, 50 no registrador AL, e
executasse STOSB, ento teramos o seguinte resultado:
Posio na Memria 06 07 08 09 10 11 12
Valor 50 32 38 03 23 50 12
OBS.: Quando usamos LODSB/STOSB, usamos AL. Isto porque estaremos mexendo
com um nmero de 8 bits (um byte), apenas. Podemos
armazenar um nmero de 8 bits em AL, AH, ou AX, mas no podemos armazenar um
nmero de 16 bits em AH ou AL porque eles so
REGISTRADORES DE 8 BITS.
Como resultado, quando usarmos LODSW ou STOSW, ns devemos usar AX e no AL,
j que estaremos pegando/colocando um nmero de
16 bits.
MOVSB - Move um byte
MOVSW - Move uma word
Como exemplo vamos pegar um byte de DS:SI e mand-lo para ES:DI.
Em DS:SI:
http://regismain.wikidot.com/assembler

4/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

Posio de Memria 06 07 08 09 10 11 12
Valor 50 32 38 03 23 50 12
Em ES:DI:
Posio de Memria 06 07 08 09 10 11 12
Valor 10 11 20 02 67 00 12
Se apontarmos DS:SI para a posio 07, apontarmos ES:SI para a posio 11 e
executarmos MOVSB, o resultado em ES:DI pareceria com:
Em ES:DI:
Posio de Memria 06 07 08 09 10 11 12
Valor 10 11 20 02 67 32 12
ESPERO QUE VOC PEGUE A IDIA GERAL. CONTUDO, CLARO, NO TO SIMPLES.
POSIES DE MEMRIA NO SO ARRUMADOAS EM FORMA DE ARRAY, EMBORA EU
DESEJASSE MUITO QUE FOSSEM. QUANDO FOR MOVER/PEGAR/COLOCAR, VOCE
ESTAR MEXENDO COM UMA POSIO TAL COMO: 100:102H. AINDA ASSIM, VOC
DEVERIA PEGAR A IDIA.
REP - REPETE o nmero de vezes especificado no registrador CX.
Um REP na frente de um MOVSB/LODSB/STOSB causaria a repetio da instruo.
Logo:
Se CX = 5, e se ES:DI apontava para 1000:1000h, ento REP STOSB armazenaria o que
estava no registrador AL na posio 1000:1000h 5 vezes.
De qualquer modo, no ltimo nmero eu disse que estaria discutindo sobre hexadecimal,
segmentos + offsets, mais algumas intrues e algumas procedures contendo assembler
que voc poderia realmente usar.
Ento, l vamos ns, com segmentos e offsets!

LIO 3 - Segmentos e Offsets


Antes de explorarmos o grande e mau mundo dos segmentos e offsets, h umas
terminologias que voc precisar conhecer.
O BIT - a menor parte de dados que podemos usar. Um bit - um oitavo de um byte
pode ser ou um 1 ou um 0. Usando esses dois dgitos podemos fazer nmeros em
BINRIO ou BASE 2.
EX.: 0000 = 0 0100 = 4 1000 = 8 1100 = 12 10000 = 16
0001 = 1 0101 = 5 1001 = 9 1101 = 13
0010 = 2 0110 = 6 1010 = 10 1110 = 14
0011 = 3 0111 = 7 1011 = 11 1111 = 15
O NIBBLE, ou quatro bits. Um nibble pode ter um valor mximo de 1111 que 15 em
decimal. aqui que o hexadecimal entra. Hex baseado naqueles 16 nmeros, (0-15), e
quando escrevemos em hex, usamos os 'dgitos' abaixo:
0123456789ABCDEF
Hexadecimal na verdade muito fcil de se usar, e, apenas como curiosidade, eu acho
que os Babilnios usava um sistema de numerao em BASE 16.
IMPORTANTE > Um nibble pode aguentar um valor at Fh < IMPORTANTE
O BYTE - o que mais usaremos. O byte tem 8 bits de tamanho - isso 2 nibbles, e o
nico valor que voc vai conseguir colocar num registrador de 8 bits. EX.: AH, AL, BH,
BL,
Um byte tem um valor mximo de 255 em decimal, 11111111 em binrio, ou FFh em
http://regismain.wikidot.com/assembler

5/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

hexadecimal.
A WORD - outra unidade comumente usada. Uma word um nmero de 16 bits, e
capaz de armazenar um nmero at 65535. Isso 1111111111111111 em binrio, e
FFFFh em hex.
Obs.: Por causa de uma word ser quatro nibbles, tambm representada por quatro
dgitos hexadecimais.
Obs.: Isto um nmero de 16 bits, e corresponde aos registradores de 16 bits. Ou seja,
AX, BX, CX, DX, DI, SI, BP, SP, DS, ES, SS e IP.
A DWORD, ou double word consiste de 2 words ou 4 bytes ou 8 nibbles ou 32 bits.
Voc no vai usar muito as double words nestes tutoriais, mas vamos mencion-las
mais tarde quando falarmos de PROGRAMAO EM 32 BITS.
Uma DWORD pode armazenar de 0 a 4,294,967,295, que FFFFFFFFh, ou
11111111111111111111111111111111. Espero que haja 32 um's l atrs.
A DWORD tambm o tamanho dos registradores extendiddos de 32 BITS, ou seja,
EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP e EIP.
O KILOBYTE, 1024 bytes, NO 1000 bytes. O kilobyte igual a 256 double-words,
512 words, 1024 bytes, 2048 nibbles ou 8192 BITS.
O MEGABYTE, ou 1024 kilobytes. Isso 1,048,576 bytes ou 8,388,608 bits.
Agora que j cobrimos a terminologia, vamos dar uma olhada mais de perto como
aqueles registradores so estruturados. Ns dissemos que AL e AH eram registradores
de 8 bits, logo, eles no deveriam se parecer com algo assim?
AH AL
Neste caso, ambos AH e AL = 0, OU 00h e 00h. Como resultado, para calcular AX
usamos: AX = 00h + 00h. Quando digo + eu quero dizer, 'ponha junto' no AX = AH
MAIS AL.
Assim, se AH era igual a 00000011 e AL era igual a 0000100, para calcular AX ns
devemos fazer o seguinte.
1) Pegue os valores hexadecimais de AH e AL.
00000011 = 03h 00010000 = 10h
2) Combine-os.
AX = AH + AL
AX = 03h + 10h
AX = 0310h
E a voc consegue o resultado. No to macetoso assim.
Okay, agora vamos ver os registradores de 16 bits:
AX

AH AL
De onde podemos ver que AX = 00000000 e 00000000, ou 0000000000000000.
Agora por ltimo, vejamos como um registrador de 32 bits se parece:
EAX
AX
AH AL
http://regismain.wikidot.com/assembler

6/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

No muito difcil, espero. E se entendeu isso, voc est pronto para SEGMENTOS e
OFFSETS.

Uma Arquitetura Segmentada


H muito, muito tempo atrs, quando a IBM construiu o primeiro PC, no era costume
programas terem mais de 1 megabyte - eca, os primeiros XT's tinham apenas 64K de
RAM! De qualquer modo, vendo que os projetistas do XT no consideravam aplicaes
enormes, decidiram dividir a memria em SEGMENTOS, pequenas reas de memria
RAM que voc pode colocar APENAS uma tela virtual
para grficos em modo 320x200x256.
claro, voc pode acessar mais de um megabyte de RAM, mas voc tem que dividi-la
em segmentos para us-la, e esse o problema. obvio, com programao em 32 bits
d pra acessas at 4GB de RAM sem usar segmentos, mas isso uma outra histria.
Segmentos e offsets so apenas um mtodo de especificar uma posio na memria.
EG: 3CE5:502A

SEG OFS
Okay, aqui est a especificao:
Um OFFSET = SEGMENT X 16
Um SEGMENT = OFFSET / 16
Algums registradores de segmento so:
CS, DS, ES, SS e FS, GF - Obs.: Os ltimos 2 so registradores que s existem em 386
ou superiores.
Alguns registradores de offset so:
BX, DI, SI, BP, SP, IP - Obs.: Quando em modo protegido, voc pode usar qualquer
registrador de uso geral como um registrador de offset - EXCETO IP.
Alguns segmentos e offsets comuns so:
CS:IP - Endereo do cdigo executando no momento.
SS:SP - Endereo da posio atual da pilha.
OBS.: NO SE INTROMETA COM ELES !
Assim quando nos referirmos a segmentos e offsets, faremos dessa forma:
SEGMENTO:OFFSET
Um bom exemplo seria:
A000:0000 - que na verdade corresponde ao topo esquerdo da tela VGA em modo
colorido 320x200x256.
FATO ENGRAADO A RAM da VGA comea em A000h
Ufa! Isso foi muito para o segundo tutorial. Contudo, ainda no terminamos. Esse
negcio de AX, AH, AL um conceito que voc pode no ter sacado ainda, ento l
vamos ns:
MOV AX, 0 ; AX = 0
MOV AL, 0 ; AL = 0
MOV AH, 0 ; AH = 0
MOV AL, FFh ; AL = FFh
http://regismain.wikidot.com/assembler

7/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

; AX = 00FFh
; AH = 00h
INC AX ; AX = AX + 1
; AX = 0100h
; AH = 01h
; AL = 00h
MOV AH, ABh ; AX = AB00h
; AH = ABh
; AL = 00h
-

A Pilha
A pilha uma caracterstica muito til de que podemos tirar vantagem. Pense nela como
uma pilha de papis numa bandeja de ENTRADA. Se voc pe algo no topo, ela ser a
primeira a ser tirada.
medida que voc adiciona algo pilha, o apontador de pilha DECREMENTADO, e
quando tira, INCREMENTADO.
E na prtica:
MOV AX, 03h ; AX = 03h
PUSH AX ; PUSH AX na pilha (coloca no topo)
MOV AX, 04Eh ; AX = 04Eh
; Faa alguma coisa uma soma?
POP AX ; AX = 03h
Ou:
MOV AX, 03h ; AX = 03h
PUSH AX ; Adiciona AX pilha
MOV AX, 04Eh ; AX = 04Eh
; Faa alguma coisa uma soma?
POP BX ; BX = 03h
Voc acabou de aprender duas instrues:
PUSH <registrador> - PUSH (coloca algo na pilha), e
POP <registrador> - POP (retira ele de volta).
tudo o que voc precisa de aprender sobre pilha - por enquanto.
Por ltimo, algumas procedures que demonstram algo disso tudo. Note que os
comentrios foram DELIBERADAMENTE REMOVIDOS. seu dever tentar coment-los.
Note tambm, que algumas novas instrues so introduzidas.
Procedure ClearScreen(A : Byte; Ch : Char); Assembler;
Asm { ClearScreen }
mov ax, 0B800h
mov es, ax
xor di, di
mov cx, 2000
mov ah, A
http://regismain.wikidot.com/assembler

8/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

mov al, &Ch


rep stosw
End; { ClearScreen }
Procedure CursorXY(X, Y : Word); Assembler;
Asm { CursorXY }
mov ax, Y
mov dh, al
dec dh
mov ax, X
mov dl, al
dec dl
mov ah, 2
xor bh, bh
int 10h
End; { CursorXY }
Procedure PutPixel(X, Y : Integer; C : Byte; Adr : Word); Assembler;
Asm { PutPixel }
mov ax, [Adr]
mov es, ax
mov bx, [X]
mov dx, [Y]
xchg dh, dl
mov al, [C]
mov di, dx
shr di, 2
add di, dx
add di, bx
stosb
End; { PutPixel }
Procedure Delay(ms : Word); Assembler;
Asm { Delay }
mov ax, 1000
mul ms
mov cx, dx
mov dx, ax
mov ah, 86h
int 15h
End; { Delay }

O que so flags?
As proceures acima com comentrios.
Um programa s em assembler. Voc vai precisar pelo menos do DEBUG, embora TASM
e TLINK sejam uma boa idia.
Bem-vindos ao terceiro tutorial da srie. No ltimo tutorial eu disse que estaramos
discutindo mais algumas instrues, flags e um verdadeiro programa em Assembly.
Durante este tutorial, voc achar os livros "Peter Norton's Guide to Assembler", "Peter
Norton's Guide to the VGA Card", ou qualquer
um dos livros "Peter Norton's Guide to" muito teis. Voc no pode programar em
Assembler sem saber pra que so todas as interrupes
e o que so todas as subfunes.
Eu lhe recomendo conseguir uma cpia desses livros assim que possvel.

Um Programa Assembly
http://regismain.wikidot.com/assembler

9/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

Eu geralmente no escrevo cdigo 100% em Assembly. muito mais conveniente usar


uma linguagem de alto nvel como C ou Pascal, e usar Assembly para acelerar os bits
lentos. Contudo, voc pode querer se torturar e escrever umaaplicao completamente
em Assembly, ento aqui vai a configurao bsica:
DOSSEG - diz CPU como organizar o segmento
MODEL - declara o modelo que vamos usar
STACK - quanta pilha vamos alocar?
DATA - o qu vai no segmento de dados
CODE - o qu vai no segmento de cdigo
START - o incio do seu cdigo
END START - o fim do seu cdigo
Okay, agora vamos dar uma olhada no programa de exemplo em que eu no farei
absolutamente nada!
DOSSEG
.MODEL SMALL
.STACK 200h
.DATA
.CODE
START:
MOV AX, 4C00h ; AH = 4Ch, AL = 00h
INT 21h
END START
Vamos ver em detalhes. Abaixo, cada uma das frases acima est explicada.
DOSSEG - isto ordena os segmentos na ordem:
Segmentos de Cdigo;
Segmentos de Dados;
Segmentos de Pilha.
No se preocupe muito com isso por enquanto, apenas inclua at que voc saiba o que
est fazendo.
MODEL - isso permite CPU determinar como seu programa est estruturado. Voc
pode ter os seguintes MODELos:
1) TINY - tanto cdigo quanto dados se encaixam no mesmo segmento de 64K.
2) SMALL - cdigo e dados esto em segmentos diferentes, embora cada um tenha
menos de.
3) MEDIUM - cdigo pode ser maior que 64K, mas os dados tm que ter menos que
64K.
4) COMPACT - cdido menos de 64K, mas dados podem ter mais que 64K.
5) LARGE - cdigo e dados podem ter mais que 64K, embora arrays no possam ser
maiores que 64K.
6) HUGE - cdigo, dados e arrays podem ter mais de 64K.
STACK - isso instrui ao PC para arrumar uma pilha to grande quanto for especificado.
DATA - permite a voc criar um segmento de dados. Por exemplo:
http://regismain.wikidot.com/assembler

10/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

MySegment SEGMENT PARA PUBLIC 'DATA'


; Declare alguns bytes, words, etc.
MySegment ENDS
Isso similar a CONSTANTES in Pascal.
CODE - permite a voc criar um segmento de c digo. Ex.:
MyCodeSegment SEGMENT PARA PUBLIC 'CODE'
; Declare algo
MyCodeSegment ENDS
START - Apenas um label para dizer ao compilador onde a parte principal do seu
programa comea.
MOV AX, 4C00h ; AH = 4Ch, AL = 00h
Isso move 4Ch para ah, que coincidentemente nos traz de volta ao DOS.
Quando a interrupo 21h chamada e AH = 4Ch, de volta ao DOS l vamos ns.
INT 21h
END START - Voc no tem imaginao?
Okay, Espero que voc tenha entendido tudo isso, porque agora ns vamos mesmo
fazer algo.
Neste examplo ns vamos usar a interrupo 21h, (a interrupo do DOS), para
imprimir uma string. Para ser preciso, vamos usar a subfuno 9h, e ela se parece com
isso:
INTERRUPO 21h
SUBFUNO 9h
Requer:
AH = 9h
DS:DX = ponteiro FAR para a string a ser impressa. A string deve ser terminada com
um sinal $.
Assim, aqui est o exemplo:
DOSSEG
.MODEL SMALL
.STACK 200h
.DATA
OurString DB "Isto uma string de caracteres. "
DB "Voc no tem imaginao? Coloque algo interessante aqui!$"
.CODE
START:
MOV AX, SEG OurString ; Move o segmento onde OurString est
MOV DS, AX ; para AX, e agora para DS
MOV DX, OFFSET OurString ; Offset de OurString -> DX
MOV AH, 9h ; Subfuno de imprimir strings
INT 21h ; Gera a interrupo 21h
MOV AX, 4C00h ; Subfuno de sada para o DOS
http://regismain.wikidot.com/assembler

11/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

INT 21h ; Gera a interrupo 21h


END START
Se voc assemblar isso com TASM - TASM SEJALADOQUEVOCECHAMOUELE.ASM ento
linkar com TLINK - TLINK SEJALADOQUEVOCECHAMOUELE.OBJ voc vai conseguir um
arquivo EXE de cerca de 652 bytes. Voc pode usar estes programas no DEBUG
com algumas modificaes, mas eu vou deixar isso contigo. Para trabalhar com
Assembler puro voc precisa de TASM e TLINK, embora eu ache que MASM faria o
mesmo trabalho muito bem.
Agora vamos ao cdigo com um pouco mais detalhado:
MOV AX, SEG OurString ; Move o segment onde OurString est
MOV DS, AX ; para AX, e agora para DS
MOV DX, OFFSET OurString ; Move o offset onde OurString est localizado
MOV AH, 9h ; Subfuno de escrita de strings
INT 21h ; Gera a interrupo 21h
Voc vai notar que tivemos que usar AX para por o endereo do segmento de OurString
em DS. Voc vai descobrir que no d pra referenciar um registrador de segmento
diretamente em Assembler. Na procedure PutPixel do ltimo tutorial, eu movi o
endereo da VGA para AX, e ento para ES.
A instruo SEG tambm introduzida. SEG retorna o segmento onde a string OurString
est localizada, e OFFSET retorna, adivinha o qu?, o offset do incio do segmento para
onde a string termina.
Note tambm que ns usamos DB. DB no nada de especial, e significa Declare Byte,
que o que tudo o que ela faz. DW, Declare Word e DD, Declare Double Word tambm
existem.
Voc poderia ter tambm colocado OurString segmento de cdigo, a vantagem que
estaria CS apontando para o mesmo segmento que OurSting, de modo que voc no
tem que se preocupar em procurar o segmento em que OurString est.
O programa acima no segmento de cdigo seria mais ou menos assim:
DOSSEG
.MODEL SMALL
.STACK 200h
.CODE
OurString DB "Abaixo o segmento de dados!$"
START:
MOV AX, CS
MOV DS, AX
MOV DX, OFFSET OurString
MOV AH, 9
INT 21h
MOV AX, 4C00h
INT 21h
END START
Simples, no?
Ns no vamos ver muitos programas s em Assembly de novo, mas a maioria das
tcnicas que usaremos podem ser implementadas em programas s em Assembler.

Ento, o que so flags?


Esta parte para meu companheiro Clive que tem me perguntado sobre flags, ento l
http://regismain.wikidot.com/assembler

12/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

vamos ns Clive, com FLAGS.


Eu no me lembro se j introduzimos a instruo CMP ou no, CMP - (COMPARE), mas
CMP compara dois nmeros e reflete a comparao nos FLAGS. Para us-la voc faria
algo desse tipo:
CMP AX, BX
ento seguir com uma instruo como essas abaixo:
COMPARAES SEM SINAL:
JA - pula (jump) se AX foi MAIOR que BX;
JAE - pula se AX foi MAIOR ou IGUAL a BX;
JB - pula se AX foi MENOR que BX;
JBE - pula se AX foi MENOR ou IGUAL a BX;
JNA - pula se AX foi NO MAIOR que BX;
JNAE - pula se AX foi NO MAIOR ou IGUAL a BX;
JNB - pula se AX foi NO MENOR que BX;
JNBE - pula se AX foi NO MENOR ou IGUAL a BX;
JZ - pula se o flag de ZERO est setado - o mesmo que JE;
JE - pula se AX for IGUAL a BX;
JNZ - pula se o flag de ZERO NO est setado - o mesmo que JNE;
JNE - pula se AX NO for IGUAL a BX;
COMPARAES COM SINAL:
JG - pula (jump) se AX foi MAIOR que BX;
JGE - pula se AX foi MAIOR ou IGUAL a BX;
JL - pula se AX foi MENOR que BX;
JLE - pula se AX foi MENOR ou IGUAL a BX
JNG - pula se AX foi NO MAIOR que BX
JNGE - pula se AX foi NO MAIOR ou IGUAL a BX;
JNL - pula se AX foi NO MENOR que BX;
JNLE - pula se AX foi NO MENOR ou IGUAL a BX;
JZ - pula se o flag de ZERO est setado - o mesmo que JE;
JE - pula se AX for IGUAL a BX;
JNZ - pula se o flag de ZERO NO est setado - o mesmo que JNE;
JNE - pula se AX NO for IGUAL a BX;
NO TO COMUNS:
JC - pula se o flag de CARRY est setado;
JNC - pula se o flag de CARRY NO est setado;
JO - pula se o flag de OVERFLOW est setado;
JNO - pula se o flag de OVERFLOW NO est setado;
JP - pula se o flag de PARIDADE est setado;
JNP - pula se o flag de PARIDADE NO est setado;
JPE - pula se a PARIDADE for PAR - o mesmo que JP;
JPO - pula se a PARIDADE for MPAR - o mesmo que JNP;
JS - pula se o flag de SINAL NO est setado;
JNS - pula se o flag de SINAL est setado.
Ufa! Meus olhos quase secaram depois de olhar pra essa tela por tanto tempo!
De qualquer modo, aqui est com o que eles se parecem:
Flag SF ZF AF PF CF
Bit 07 06 05 04 03 02 01 00
Legenda:
SF - Flag de Sinal;
ZF - Flag de Zero;
AF - Flag Auxiliar;
PF - Flag de Paridade.
CF - Flag de Carry (vai um).
http://regismain.wikidot.com/assembler

13/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

Nota: H MUITO MAIS FLAGS PARA APRENDER. Eles sero vistos num Tutorial mais
frente.
Okay, no ltimo tutorial eu lhe dei algumas procedures, e pedi para voc coment-las.
Eu no queria uma explicao detalhada do que eles faziam - no se espera que voc
saiba isso ainda - apenas um sumrio do que cada comando faz.
Ex.:
MOV AX, 0003h ; AX agora igual a 03h;
ADD AX, 0004h ; AX agora igual a 07h;
Ento, aqui vai o conjunto completo das procedures com comentrios:
{ Esta procedure limpa a tela em modo texto }
Procedure ClearScreen(A : Byte; Ch : Char); Assembler;
Asm { ClearScreen }
mov ax, 0B800h { Move o endereo de vdeo para AX }
mov es, ax { Aponta ES para o segmento de vdeo }
xor di, di { Zera DI }
mov cx, 2000 { Move 2000 (80x25) para CX }
mov ah, A { Move o atributo para AH }
mov al, &Ch { Move o caracter a usar para AL }
rep stosw { Faz isso }
End; { ClearScreen }
Explicao:
Ns zeramos DI, logo igual a 0 - o canto esquerdo da tela. Isto de onde vamos
comear a encher a tela.
Movemos 2000 para CX porque vamos colocar 2000 caracteres na tela.
{ Esta procedure move o cursor para a posio X, Y }
Procedure CursorXY(X, Y : Word); Assembler;
Asm { CursorXY }
mov ax, Y { Move o valor Y para AX }
mov dh, al { Y vai para DH }
dec dh { rotina baseada em ajustar para zero }
mov ax, X { Move o valor de X para AX }
mov dl, al { X vai para DL }
dec dl { rotina baseada em ajustar para zero }
mov ah, 2 { Chama a funo correspondente }
xor bh, bh { Zera BH }
int 10h { faz isso (pe o cursor na posio) }
End; { CursorXY }
Explicao:
A ' rotina baseada em ajustar para zero' realizada porque a BIOS refere-se posio
(1, 1) como (0, 0), e igualmente (80, 25) como (79, 24).
Procedure PutPixel(X, Y : Integer; C : Byte; Adr : Word); Assembler;
Asm { PutPixel }
mov ax, [Adr] { Move o endereo do VGA em AX }
mov es, ax { Joga AX em ES }
mov bx, [X] { Move o valor de X para BX }
mov dx, [Y] { Move o valor de Y para DX }
xchg dh, dl { Daqui pra frente calcula o }
mov al, [C] { offset do pixel a ser plotado }
mov di, dx { e pe este valor em DI. Vamos }
http://regismain.wikidot.com/assembler

14/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

shr di, 2 { ver isso mais tarde - prximo tutorial}


add di, dx { quando falarmos sobre shifts }
add di, bx { versus muls }
stosb { Guarda o byte em ES:DI }
End; { PutPixel }
NOTA: Eu estaria muito interessado em achar uma procedure PutPixel mais rpida que
essa. Eu j vi uma inline que faz isso em metade do tempo, mas mesmo assim, essa
muito quente.
{ Esta procedure uma funo de delay independente de CPU }
Procedure Delay(ms : Word); Assembler;
Asm { Delay }
mov ax, 1000 { Move o nmero de ms em um segundo para AX }
mul ms { Faz AX = nmero de ms a esperar }
mov cx, dx { Prepara para o delay - pe nmero de ms }
mov dx, ax { onde necessrio }
mov ah, 86h { Cria o delay }
int 15h
End; { Delay }
Quase todo o fluido saiu do meus olhos agora - quase meia-noite - ento eu acho
melhor parar. Desculpe se os comentrios so um pouco curtos, mas eu preciso dormir!
No prximo tutorial vamos ver:
Shifts - o que so eles?
Alguns exemplos de CMP/JMP.
Como a memria VGA arrumada, e como acess-la.

ShiftS
Primeiramente porm, devemos terminar aquela coisa de CMP/JMP, e falar de shifts.
Quando se est programando em Assembler, a gente acha que comparaes, shifts e
testar bits so operaes muito comuns.
Um Exemplo de Comparao
Eu no vou perder tempo explicando minuciosamente o seguinte exemplo - ele muito
fcil de entender e voc deve pegar a idia basica seja l como for.
DOSSEG
.MODEL SMALL
.STACK 200h
.DATA
FirstString DB 13, 10, "Este um grande tutorial ou o qu? :) - $"
SecondString DB 13, 10, "NO? NO? O que voc quer dizer, NO?$"
ThirdString DB 13, 10, "Excelente, vamos ouvir voc dizer isso de novo.$"
FourthString DB 13, 10, "Apenas um Y ou N j basta.$"
ExitString DB 13, 10, "Bem, deixa pra l!$"
.CODE
START:
MOV AX, @DATA ; Novo modo de dizer:
MOV DS, AX ; DS -> SEG segmento de dados
KeepOnGoing:
MOV AH, 9
MOV DX, OFFSET FirstString ; DX -> OFFSET FirstString
INT 21h ; Escreve a primeira mensagem

http://regismain.wikidot.com/assembler

15/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

MOV AH, 0 ; Pega uma tecla - armazena-a em AX


INT 16h ; AL - cdigo ASCII, AH - "scan code"
; Ela no ecoa na tela, contudo,
; ns mesmos temos que fazer isso.
PUSH AX ; Aqui ns mostramos na tela o caracter
MOV DL, AL ; note que ns salvamos AX. Obviamente,
MOV AH, 2 ; usando-se AH para imprimir uma string
INT 21h ; destri-se AX
POP AX
CMP AL, "Y" ; Checa se foi teclado 'Y'
JNE HatesTute ; Se foi, continua
MOV AH, 9 ; Mostra a mensagem "Excelente"
MOV DX, OFFSET ThirdString
INT 21h
JMP KeepOnGoing ; Volta ao incio e comea de novo
HatesTute:
CMP AL, "N" ; Certifica que foi teclado 'N'
JE DontLikeYou ; Infelizmente, sim.
MOV DX, OFFSET FourthString ; Pede ao usurio para tentar de novo
MOV AH, 9
INT 21h
JMP KeepOnGoing ; Deixa ele tentar
DontLikeYou:
MOV DX, OFFSET SecondString ; Mostra a string "NO? NO? O que"
MOV AH, 9
INT 21h
MOV DX, OFFSET ExitString ; Mostra a string "Bem, deixa pra l!"
MOV AH, 9
INT 21h
MOV AX, 4C00h ; Volta para o DOS
INT 21hEdit
site-name
.wikidot.com
History Tags Source
Explore
Share on
END START
Voc deveria entender este exemplo, brincar um pouco com ele e escrever algo melhor.
Aqueles com um livro do Peter Norton ou algo semelhante, experimentem as subfunes
do teclado, e veja quais outras combinaes de GetKey existem, ou melhor ainda,
brinque com a interrupo 10h e entre em algum modo de vdeo sobrenatural - um que
seu PC suporte! - e use algumas cores.
Shifts
Um simples conceito, e um que eu j devia ter discutido antes, mas como eu disse - eu
tenho minha prpria maneira desconjuntada de fazer as coisas.
Primeiro voc vai precisar de entender um pouco de aritmtica hexadecimal e binria um assunto que eu _deveria_ ter coberto antes. Eu geralmente uso uma calculadora
cientfica - ei, eu sempre uso uma calculadora, eu no sou estpido! - mas bom ser
capaz de saber como multiplicar, somar e converter entre as vrias bases.
CONVERTENDO DE BINRIO PARA DECIMAL:
De Volta ao Tutorial Um, ns vimos como nmeros binrios se parecem, ento imagine
que eu tenha um nmero binrio de oito dgitos, como:
11001101
O que isso em decimal??? H vrias formas de converter tal nmero, e eu uso a
seguinte, que acredito se provavelmente a mais fcil:
http://regismain.wikidot.com/assembler

16/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

Nmero Binrio 1 1 0 0 1 1 0 1
76543210
Equivalente Decimal 2 2 2 2 2 2 2 2
Equivalente Decimal 128 64 32 16 8 4 2 1
Valor Decimal 128 + 64 + 0 + 0 + 8 + 4 + 0 + 1 = 205

Pegou a idia? Note que para a ltima linha, seria mais preciso escrever:
1 x 128 + 1 x 64 + 0 x 32 + 0 x 16 + 1 x 8 + 1 x 4 + 0 x 2 + 1 x 1
128 + 64 + 0 + 0 + 8 + 4 + 0 + 1
205
Desculpe se isto um pouco confuso, mas difcil explicar sem demonstrar.
Aqui vai outro exemplo:

Nmero Binrio 0 1 1 1 1 1 0 0
76543210
Equivalente Decimal 2 2 2 2 2 2 2 2
Equivalente Decimal 128 64 32 16 8 4 2 1
Valor Decimal 0 + 64 + 32 + 16 + 8 + 4 + 0 + 0 = 124

Obs.:
Voc pode usar esta tcnica com palavras de 16 ou 32 bits tambm, apenas faa do
jeito certo. Ex: Depois de 128, voc escreveria 256, depois 512, 1024 e assim por
diante.
Voc pode dizer se o equivalente decimal ser par ou mpar pelo primeiro bit. Ex.: No
exemplo acima, o primeiro bit = 0, ento o nmero PAR.
No primeiro exemplo, o primeiro bit 1, ento o nmero MPAR.
FATO ENGRAADO: Caso voc no saiba ainda, bit vem de Binary digIT.
CONVERTENDO DE DECIMAL PARA BINRIO:
Isso provavelmente mais fcil que da base-2 para base-10. Para calcular o que 321
seria em binrio, voc faria o seguinte:
321 = 256 X 1
321 - 256 = 65 = 128 X 0
65 = 64 X 1
65 - 64 = 1 = 32 X 0
1 = 16 X 0
1=8X0
1=4X0
1=2X0
1=1X1
E voc obteria o nmero binrio - 101000001. Fcil, n? Vamos tentar outro para ter
certeza que sabemos fazer:
198 = 128 X 1
198 - 128 = 70 = 64 X 1
70 - 64 = 6 = 32 X 0
6 = 16 X 0
6=8X0
6=4X1
6-4=2=2X1
2-2=0=1X0
E isto nos d - 11000110. Note como voc pode checar o primeiro dgito para ver se
voc conseguiu sua converso certa. Quando eu escrevi o primeiro exemplo, eu notei
que eu fiz um erro quando eu chequei o primeiro bit. No primeiro exemplo, eu consegui
0 - no muito bom para um nmero mpar.
http://regismain.wikidot.com/assembler

17/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

Eu entendi o erro e corrigi o exemplo.


CONVERTENDO DE HEXADECIMAL PARA DECIMAL:
Antes de comear, voc deveria saber que o sistema numrico hexadecimal usa os
'dgitos':
0 = 0 (decimal) = 0 (binrio)
1 = 1 (decimal) = 1 (binrio)
2 = 2 (decimal) = 10 (binrio)
3 = 3 (decimal) = 11 (binrio)
4 = 4 (decimal) = 100 (binrio)
5 = 5 (decimal) = 101 (binrio)
6 = 6 (decimal) = 110 (binrio)
7 = 7 (decimal) = 111 (binrio)
8 = 8 (decimal) = 1000 (binrio)
9 = 9 (decimal) = 1001 (binrio)
A = 10 (decimal) = 1010 (binrio)
B = 11 (decimal) = 1011 (binrio)
C = 12 (decimal) = 1100 (binrio)
D = 13 (decimal) = 1101 (binrio)
E = 14 (decimal) = 1110 (binrio)
F = 15 (decimal) = 1111 (binrio)
Voc vai comumente ouvir hexadecimal referenciado como hex, ou base-16 e ela
comumente denotada por um 'h' - ex.: 4C00h, ou um '$', ex.: - $B800.
Trabalhar com hexadecimal no to difcil como pode parecer, e converter pra l ou
pra c bem fcil. Como exemplo, vamos converter B800h para decimal:
FATO ENGRAADO: B800h o endereo inicial do vdeo em modo texto para CGA e
placas superiores.
B = 4096 x B = 4096 x 11 = 45056
8 = 256 x 8 = 256 x 8 = 2048
0 = 16 x 0 = 16 x 0 = 0
0=1x0=1x0=0
Logo B800h = 45056 + 2048 + 0 + 0
47104
Obs.: Para nmeros em hexadecimal maiores que FFFFh (65535 em decimal), voc
somente segue o mesmo procedimento como para
binrio, logo, para o quinto dgito hexadecimal, voc multiplicaria por 65535.
Tecle 16 X X na sua calculadora, e fique apertando =.
Voc ver os nmeros que precisaria usar. O mesmo aplica-se para binrio. Ex.: 2 X X e
= lhe daria 1, 2, 4, 8, 16 etc.
OK, isso pareceu bem fcil. Eu acho que nem precisamos de um segundo exemplo.
Vamos dar uma olhada em:
CONVERTENDO DE DECIMAL PARA HEXADECIMAL:
Mais uma vez, o mesmo tipo de procedimento como usamos para binrio. Logo, para
converter 32753 para hexadecimal, voc faria assim:
32753 / 4096 = 7 (decimal) = 7h
32753 - (4096 x 7) = 4081
4081 / 256 = 15 (decimal) = Fh
4081 - (256 x 15) = 241

http://regismain.wikidot.com/assembler

18/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

241 / 16 = 15 (decimal) = Fh
241 - (16 x 15) = 1
1 / 1 = 1 (decimal) = 1h
Assim, eventualmente temos 7FF1h como resposta. Este no particularmente um bom
processo e requer alguma explicao.
1) Quando voc divide 32753 por 4096 voc consegue 7.9963379 No estamos
interessados no lixo .9963379, s pegamos o 7, j que 7 o maior nmero inteiro que
podemos usar.
2) O resto da operao acima 4081. Devemos agora realizar a mesma operao nisso,
mas com 256. Dividindo 4081 por 256 nos d
15.941406 Novamente, pegamos s o 15.
3) Agora temos um resto de 241. Dividindo isto por 16 nos d 15.0625. Pegamos o 15, e
calculamos o resto.
4) Nosso ltimo resto acontece que um. Dividindo isso por um chegamos a, voc
advinhou - um. VOC NO DEVERIA CONSEGUIR UMA RESPOSTA COM MUITAS CASAS
DECIMAIS AQUI. SE VOC TEM - VOC CALCULOU ERRADO.
um processo muito imundo, mas funciona. Eu no uso isso, exceto quando eu tenho
que usar - eu no sou maluco. Eu uso uma calculadora cientfica, ou a calculadora do
Windows <brrrrr> se eu precisar.
OK, agora que j lidamos com os clculos horripilantes, voc j est pronto para os
shifts. H geralmente 2 formas da instruo shift - SHL (shift left/esquerda) e SHR (shift
right/direita). Basicamente, tudo o que essas instrues fazem deslocar uma
expresso para a esquerda ou direita um certo nmero de bits. Sua principal vantagem
a habilidade de lhe deixar substituir multiplicaes lentas com shifts mais rpidos.
Voc vai achar que isso acelerar pra caramba os algoritmos de pixel/linhas/crculo.
Os PC's esto ficando cada vez mais rpidos a cada dia - um pouco rpido demais pro
meu gosto. De volta aos dias do XT - a multiplicao era realmente lenta - talvez
levando at 4 segundos para certas operaes. Hoje em dia isso no acontece assim,
mas uma boa idia otimizar seu cdigo.
Quando ns plotamos um pixel na tela, temos que encontar o offset do pixel a plotar.
Basicamente, o que fazemos multiplicar a posio Y por 320, somar a posio X, e
somar isso ao endereo A000h.
Assim basicamente, temos: A000:Yx320+X
Agora, seja l quo rpido seu maravilhoso 486 ou Pentium , isso poderia se feito um
pouco mais rpido. Vamos reescrever aquela equao
acima, assim, vamos usar alguns nmeros diferentes:
86
Offset = Y x 2 + Y x 2 + X
Ou:
Offset = Y x 256 + y x 64 + X
Reconhece esses nmeros? Eles parecem terrivelmente com aqueles que ns vimos
naquela tabela de converso binrio-decimal.
Contudo, ns ainda estamos usando multiplicao.
Como podemos incorporar shifts?
Que tal:
Offset = Y SHL 8 + Y SHL 6 + X
Agora, isso _muito_ mais rpido, j que tudo o que o computador tem que fazer um
shift esquerda com o nmero - muito melhor.
http://regismain.wikidot.com/assembler

19/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

Note que o shift esquerda AUMENTA o nmero, e o shift direita DIMINUI o nmero.
Aqui est um exemplo que pode te ajudar se voc ainda est em dvida no que est
acontecendo. Digamos que estamos trabalhando em base-10 - decimal. Agora
Peguemos o nmero 36 como exemplo. "Shiftando" este nmero esquerda de 1,
temos:
36 + 36 = 72
Agora SHL 2:
36 + 36 + 36 + 36 = 144
E SHL 3:
36 + 36 + 36 + 36 + 36 + 36 + 36 + 36 = 288
Notou os neros que se formaram? Havia 2 36's com SHL 1, 4 36's com SHL 2 e 8 36's
com SHL 3. Seguindo este padro, seria justo assumir que 36 SHL 4 equivaler a 36 x
16.
Note porm, o que est realmente acontecendo. Se voc fosse trabalhar com o valor
binrio de 36, que mais ou menos isso: 100100, e ento shiftasse 36 esquerda de 2,
voc teria 144, ou 10010000. Tudo o que a CPU faz na verdade colocar alguns 1's e 0's
extras na posio de memria.
Como outro exemplo, pegue o nmero binrio 1000101. Se fizermos um shift esquerda
de 3, terminaramos com:
1000101
<-- SHL 3
1000101000
Agora vamos deslocar o nmero 45 DIREITA de 2 unidades. Em binrio isso 101101.
De onde:
101101
SHR 2 >
1011
Notou o que ocorreu? muito mais fcil para a CPU apenas mover alguns bits
(aproximadamente 2 unidades de clock), do que multiplicar um nmero. (Pode demorar
at 133 unidades de clock).
Ns vamos usar bastante shifts quando estivermos programando a VGA, assim, tenha
certeza de que voc entendeu os conceitos por trs disso.

PROGRAMANDO A VGA EM ASSEMBLER


Quando ns falamos sobre programar a VGA, ns estamos geralmente falando do modo
13h, ou um de seus parentes. Em VGA padro este o _nico_ modo de usar 256 cores,
e provavelmente um dos modos mais fceis tambm.
Se voc j tentou experincias com a SVGA, voc vai entender o pesadelo que para o
programador dar suporte a todas as diferentes placas SVGA que existem - exceto se
voc usar VESA que o que discutiremos outra hora.
A grande vantagem do modo padro 13h que voc sabe que todas as placas VGA que
existem vo suport-lo. As pessoas hoje frequentemente ignoram o modo 13h, achando
a resoluo muito granulada para os padres de hoje, mas no se esquea
que Duke Nukem, DOOM, DOOM II, Halloween Harry e a maioria dos jogos da Apogee
usam este modo para realizar alguns grandes efeitos.
A grande coisa sobre o modo 13h - isto 320x200x256 caso voc desconhea, que
acessar a VGA RAM incrivelmente fcil. Como 320 x 200 igual a 64,000, possvel
encaixar a tela inteira em um segmento de 64K.
As ms notcias so que o modo padro 13h realmente s te d uma pgina para usar,
http://regismain.wikidot.com/assembler

20/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

seriamente embaraante para scroll e page-flipping. ns vamos cobrir mais tarde estes
assuntos, como entrar em seus prprios modos - e modo X que evitar esses
problemas.
Ento, como entrar no modo padro 13h?
A resposta simples. Usamos a interrupo 10h - interrupo de vdeo, e chamamos a
subfuno 00h - seleciona o modo. Em Pascal, voc poderia declarar uma procedure
como esta:
Procedure Init300x200; Assembler;
Asm { Init300x200 }
mov ah, 00h { Acerta o modo de vdeo }
mov al, 13h { Usa o modo 13h }
int 10h { Faz isso }
End; { Init300x200 }
voc tambm pode ver:
mov ax, 13h
int 10h
Isso perfeitamente correto, e provavelmente economiza um tempo de clock por no
colocar 00h em AH e ento 13h em AL, mas mais correto usar o primeiro exemplo.
OK, ento estamos no modo 13h, mas o que podemos realmente fazer nele, alm de
olhar para uma tela em branco? Poderamos voltar ao modo texto usando:
mov ah, 00h
mov al, 03h
int 10h
Mas isso um pouco idiota. Porque no pintar um pixel?
H inmeros modos de colocar um pixel na tela. O modo mais fcil em Assembler usar
interrupes. Voc faria mais ou menos assim em Pascal:
Procedure PutPixel(X, Y : Integer; Color : Byte); Assembler;
Asm { PutPixel }
mov ah, 0Ch { subfuno de desenhar pixel }
mov al, [Color] { Move a cor a plotar para AL }
mov cx, [X] { Move o valor X para CX }
mov dx, [Y] { Move o valor Y para DX }
mov bx, 1h { BX = 1, p gina 1 }
int 10h { Plota }
End; { PutPixel }
Contudo, mesmo isso sendo em Assembler, no particularmente rpido. Por qu?,
voc pergunta. Porque isso usa interrupo. Interrupes so timas para entar e sair
de modos de vdeo, ligar e desligar o cursor, etc mas no para grficos.
Voc pode imaginar interrupes como uma secretria eletrnica. "A CPU est ocupada
neste momento, mas se voc deixar sua subfuno aps o sinal - ns entraremos em
contato."
No bom. Vamos usar a tcnica que discutimos anteriormente durante shifts. O que
queremos fazer botar o valor da cor que desejamor plotar na VGA diretamente. Para
fazer isso, precisamos mover o endereo da VGA para ES, e calcular o offset do pixel
que queremos plotar. Um exemplo disso mostrado abaixo:
Procedure PutPixel(X, Y : Integer; Color : Byte); Assembler;
Asm { PutPixel }
mov ax, 0A000h { Move o segmento da VGA para AX, }
http://regismain.wikidot.com/assembler

21/22

05/11/2014

Assembler Intel Introduo - Regis Mainframe

mov es, ax { e agora para ES }


mov bx, [X] { Move o valor X para BX }
mov dx, [Y] { Move o valor Y para DX }
mov di, bx { Move X para DI }
mov bx, dx { Move Y para BX }
shl dx, 8 { Nesta parte usamos shifts para multiplicar }
shl bx, 6 { Y por 320 }
add dx, bx { Agora somamos X ao valor acima calculado, }
add di, dx { dando DI = Y x 320 + X }
mov al, [Color] { Pe a cor a plotar em AL }
stosb { Pe o byte, AL, em ES:DI }
End; { PutPixel }
Esta procedure rpida o suficiente para comear, embora eu tenha dado uma muito
mais rpida uns tutoriais atrs que usa uma tcnica genial para pegar DI.
Tenha certeza que entendeu aquela coisa de binrio -> decimal, decimal -> binrio,
decimal -> hex e hex -> decimal. Faa voc mesmo
alguns exemplos de soma e teste suas respostas com a calculadora do Windows.
Voc deve entender shifts. Se voc ainda tem problemas, faa algumas expresses num
papel e teste suas respostas num programa como:
Begin { Main }
WriteLn(45 SHL 6);
ReadLn;
End. { Main }
e/ou a calculadora do Windows.
D uma olhada na parte de VGA, e certifique-se de ter pego a teoria por trs disso,
porque na prxima semana vamos entrar a fundo nisso.

Fonte : http://www.saladoprogramador.hpg.ig.com.br/assembler1.htm
page revision: 4, last edited: 21 Mar 2011, 01:13 (1325 days ago)

Edit

Powered by Wikidot.com

Tags

History

Files

Print

Site tools

+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License

Other interesting sites

Maegica Wiki

SCP

Roboticspedia

Variable Thinking Wiki

Maegica Order In Chaos Online

All that you want to know about


making robots

Life is a word problem

http://regismain.wikidot.com/assembler

22/22