ASM - Limbaj de asamblare
"Un programator nu ajunge niciodata la nivel de expert
daca nu trece prin dezvoltarea de programe ASM."
INDEX:
- Despre limbajul ASM
- Date generale. Arhitectura procesorului
- Structura unui program ASM
- Instructiuni ASM
- Intreruperi si functii importante
- Tehnici + Tips&Tricks
- Exemple la instructiuni si programe ASM
1. Despre limbajul ASM:
Limbajul de asamblare(ASM) permite intelegerea
la nivel de amanunt a ceea ce se intampla in realitate
intr-un calculator.
Exista mai multe motive pentru care programarea
in ASM este necesara. Codul generat in ASM este,
in general, foarte rapid. Programele complexe au
scrise in ASM modulele critice. Exista si situatii
cand avem nevoie de accesul la dispozitive I/O
sau locatii de memorie.
Pe scurt, limbajul de asamblare ofera viteze de
executie si acces la hardware care nu pot fi
disponibile(cel mai adesea) in limbajele de nivel
inalt(Pascal, C, Visual C, Visual Basic, Java).
2. Date generale.Arhitectura procesorului:
Unitatea de baza a informatiei memorate in calculator
este bitul. Acesta reprezinta o cifra binara(0 sau 1)
Modelul hardware al acestuia este bistabilul (sau
flagul). Un grup de bistabili formeaza un registru.
Un byte(sau octet) este format din 8 biti.De exemplu,
01001011 ocupa un byte. Informatia ce poate fi
codificata intr-un registru poate lua valori intre
00000000 si 11111111.Numarul de combinatii este
de 256(28).
Registrii procesorului:
AX, BX, CX, DX, BP, SP, SI, DI - acestia sunt.
Cei cu x se pot imparti in doua(partea high si low).
astfel: ah, al, bh, bl, ch, cl, dh, dl.
Functiile lor sunt:
- AX este registrul acumulator
- BX este registrul de baza general
- CX este registrul contor
- DX este registrul de date
- BP este registrul de baza pentru stiva
- SP este registrul indicator de stiva
- SI este registrul index sursa
- DI este registrul index destinatie
Mai sunt si patru registri de segment:
- CS - segmentul de cod (code)
- DS - segmentul de date (date)
- SS - segmentul de stiva (stack)
- ES - segmentul de date suplimentar (extra)
De mentionat ca in ASM se folosesc bazele 2 si 16(rar si 8).
Trecerea dintr-o baza in alta se face astfel:
25510 = 111111112 = FF
16 = 3778
Numerotarea in ASM
incepe de la 0(atentie!).
Byte-ul este unitatea ce exprima volumul memoriei
unui calculator. Deoarece dimensiunea memoriei
este un multiplu de 2, multiplii pentru bytes sunt
puteri ale lui 2(nu 10, 100, 1000...).
Astfel:
- kilo = 1024 bytes
- mega = 1024 kilo = 10264576 bytes
- giga = 1024 mega = 10264576 kilo = 1073741824 bytes
In memoria calculatorului trebuie memorate si
caractere(litere, cifre, caractere speciale).
Aici se foloseste codul ASCII(American Standard
Code for Information Interchange).
Iata cateva coduri speciale utilizate mai des:
- CR (carriage return) - muta cursorul la inceputul
liniei. Cod = 13 (sau D)
- LF (line feed) - trece la linie noua. Cod = 10 (sau A)
- BS (backspace) - deplaseaza cursorul cu o
pozitie la stanga. Cod = 8
- DEL (delete) - sterge caracterul indicat de
cursor. Cod = 127 (sau 7F)
- BEL (bell) - emite un sunet. Cod = 7
- FF (form feed) - avanseaza hartia de la
imprimanta la pagina noua. Cod = 12 (sau C)
- SP (space sau blank) - spatiu. Cod = 32(sau 20)
In paranteza este codul in hexa(baza 16). In ASM
acesta se scrie codh(ex: 16h, 198h...).In zecimal
nu apare h-ul.
Observati ca ENTER este tocmai CR si LF.
Registrul de Flaguri(sau bistabili) este:
- CF (carry flag) - semnifica transport la
operatii
- PF (parity flag) - numarul de octeti low e impar
- AF (auxilliary carry flag) - transport din
bitul 4 al rezultatului
- ZF (zero flag) - e 1 daca rezultatul operatiei e 0
- SF (sign flag) - e 1 daca bitul high e 1
- OF (overflow flag) - e daca s-a depasit domeniul
de definitie
- TF (trap flag) - e 1 daca se forteaza o intrerupere
- IF (interrupt flag) - e 1 daca se iau si intreruperile
hardware
- DF (direction flag) - precizeaza sensul de
variatie al adreselor la operatiile cu siruri
3. Structura programelor ASM:
Instructiunile si datele trebuie scrise intr-un
segment. Forma generala a directivei SEGMENT este:
nume SEGMENT [aliniere] [combinare] [nume clasa]
nume ENDS.
Tipurile de date utilizate in ASM:
- Byte (1 octet) - intreg pe 8 biti cu semn
sau caracter ASCII. Se defineste cu DB(define Byte)
- Word (2 octeti) - intreg pe 16 biti sau 2
caractere ASCII. Se defineste cu DW (define word)
- Duble Word (4 octeti) - intreg pe 32 biti
sau numar real simplu. Se defineste cu DD (define double)
- Quad Word (8 octeti) - intreg pe 64 biti sau
real dublu. Se defineste cu DQ (quad word)
- Ten Bytes (10 octeti) - intreg impachetat sau
real complex. Se defineste cu DT (define ten)
Exemple
Directiva ASSUME realizeaza o conexiune simbolica
intre definirea segmentelor logice si registrele
de segment. Exemple
Modelul de mamorie(model) poate fi de mai multe
tipuri: tiny(pentru fisierele COM), small, medium,
compact, large si huge.
Sirurile de caractere sau cifre se declara cu DUP.
Un sir de caractere trebuie sa se termine cu '$'
daca doriti sa-l afisati.
Constantele simbolice cu EQU.Comentariile se scriu
dupa semnul ;. Exemple
Un scurt exemplu
de program ASM. Programele ASM se compileaza astfel:
TASM nume.asm apoi TLINK nume.obj.
4. Instructiuni ASM:
Se pot grupa in :
- Instructiuni de transfer
- Instructiuni aritmetice
- Instructiuni logice
- Instructiuni pentru siruri
- Instructiuni de salt
- Instructiuni complexe
Instructiuni de transfer:
Instructiunea MOV (transfera date):
forma: MOV destinatie, sursa
efect: destinatie := sursa
Instructiunea PUSH (salveaza date in stiva):
forma: PUSH sursa
efect: salveaza sursa(ce poate fi un registru)
Instructiunea POP (reface date din stiva):
forma: POP destinatie
efect: se transfera continutul stivei in destinatie
Nota: Numarul de PUSH este, in general, egal cu cel de POP.
Instructiunea XCHG (exchange):
forma: XCHG destinatie, sursa
efect: interschimba destinatia cu sursa.
Instructiunea IN:
forma: IN destinatie, port
efect: citeste de la portul dat in destinatie.
nota: destinatia poate fi doar AX sau AH.
Instructiunea OUT:
forma: OUT destinatie, port
efect: scrie la portul dat valoarea destinatiei.
nota: destinatia poate fi doar AX sau AL.
Instructiunea LEA (load effective adress):
forma: LEA registru, sursa
efect: copiaza adresa efectiva a sursei in registru
nota: este echivalenta cu MOV registru, OFFSET sursa
Instructiunea PUSHF (push flags):
forma: PUSHF
efect: salveaza toti registrii in stiva
Instructiunea POPF:
forma: POPF
efect: reface toti registrii din stiva
Exemple
Instructiuni aritmetice:
Instructiunea ADD:
forma: ADD dest, sursa
efect: aduna sursa la dest.
Instructiunea INC:
forma: INC dest
efect: creste dest. cu 1
Instructiunea SUB:
forma: SUB dest, sursa
efect: scade sursa din dest.
Instructiunea DEC:
forma: DEC dest
efect: scade dest. cu 1
Instructiunea NEG:
forma: NEG dest
efect: schimba semnul(0 - dest)
Instructiunea MUL:
forma: MUL sursa
efect: inmulteste AX cu sursa
Instructiunea DIV:
forma: DIV sursa
efect: imparte AX la sursa
nota: in AL e catul si-n AH restul.
Instructiunea SHR:
forma: SHR operand, contor
efect: operand e impartit la 2contor
Instructiunea SHL:
forma: SHL operand, contor
efect: operand e inmultit cu 2contor
Exemple
Instructiuni logice(sunt cele cunoscute...):
Sunt 5 la numar: NOT, AND, TEST, OR si XOR.
Exemple
Instructiuni pentru siruri:
Instructiunea MOVSB:
forma: MOVSB
efect: se transfera un octet de la DS:SI la ES:DI
Instructiunea LODSB:
forma: LODSB
efect: incarca in AX(sau AL) un octet de la DS:SI
Instructiunea: STOSB
forma: STOSB
efect: depune la ES:DI octetul din AX(sau AL)
Exemple
Instructiuni de salt:
JMP - Salt neconditionat
JMP @1 - sare la eticheta @1
Salt conditionat:
se folosesc dupa CMP a, b
JE @1 - jump if equal(if a = b then jump @1)
JNE @1 - jump if not equal(if a != b then jump @1)
JL @1 - jump if less(if a < b then jump @1)
JLE @1 - jump if less or equal(if a <= b then jump @1)
JG @1 - jump if great(if a > b then jump @1)
JGE @1 - jump if great or equal(if a >= b then jump @1)
JZ @1 - jump if zero(if a = 0 then jump @1)
JNZ @1 - jump if not zero(if a != 0 then jump @1)
Instructiunea de ciclare LOOP:
sintaxa: LOOP eticheta
sare la eticheta de CX ori.
Exemple
Instructiuni complexe:
Subprograme:
Proceduri:
Nume proc [parametri]
[instructiuni]
ret
Nume endp
Macro-uri:
Nume macro [parametri]
[instructiuni]
Nume endm
Procedurile se apeleaza cu call: call nume_proc
Variabilele si etichetele proprii subprogramelor
se declara cu LOCAL: Local et1, Local a db 67...
Exemple
5. Intreuperi si functii importante:
Intreruperea presupune oprirea programului in
executie si apelarea unor rutine predefinite.Se
apeleaza cu INT nr.intrerupere + 'h'(int 21h, int 33h)
Principalele intreruperi sunt:
- INT 10h - functii pentru ecran
- INT 14h - functii pentru floppy(I/O)
- INT 15h si 16h - functii pentru tastatura
- INT 17h - functii pentru imprimanta
- INT 21h - functii DOS
- INT 33h - functii pentru mouse
Incep prin a descrie cateva functii importante
din fiecare intrerupere(dupa fiecare functie se
apeleaza INT si numarul intreruperii):
INT 10h - Screen
Initializarea modului grafic:
Pentru EGA:
mov ax, 10h(640x350)
mov ax, 0dh(320x200)
mov ax, 0fh(640x200)
mov ax, 03h(textmode)
mov ax, 10h(640x350)
Pentru VGA:
mov ah, 0h apoi
mov al, 11h(640x480, 2 colors)
mov al, 12h(640x480, 16 colors)
mov al, 13h(640x480, 256 colors)
Putpixel (merge cam incet...):
mov ah, 0ch
mov bh, 0
mov cx, x ; coord. pe x
mov dx, y ; coord. pe y
mov al, color ; culoarea
mov bh, x - muta cursorul text la (x, y)
mov dx, y
mov ah, 2
mov bh, 7 - sterge ecranul(e mai eficient inittext)
mov ax, 600h
mov cx, 0
mov dx, 24 * 256 + 79; 25 linii, 79 coloane
mov ah, 1 - ascunde cursorul text
mov ch, 32
mov cl, 7
INT 15h - Keyboard
mov ah, 86h - DELAY
mov cx, partea high in ms.
mov dx, partea low in ms
INT 16h - Keyboard
mov ah, 0 - asteapta o tasta
mov ah, 1 - verifica daca a fost apasata o tasta
jnz et2 ; sare la et2 daca a fost apasata
mov ah, 03h - seteaza viteza tastei
mov al, 05h ; merge si mov ax, 0305h...
mov bl, (0 - 1fh) unde 0 e rapid si 1fh incet
mov bh, (0..3) un de 0 e rapid si 3 e incet
INT 21h - DOS
mov ah, 01h - citeste in AL un caracter si-l afiseaza
mov ah, 02h - tipareste caracterul din DL
mov dl, caracter
mov ah, 08h - citeste in AL fara ecou
mov ah, 09h - afiseaza sirul de la DS:SI
mov ah, 4ch - iese in DOS (obligatoriu un program
se termina cu asta)
mov ah, 31h - iese in DOS, programul ramanand rezident(TSR)
mov ah, 2bh - seteaza data BIOS-ului
mov cx, an
mov dh, luna
mov dl, zi
mov ah, 2dh - seteaza ceas-ul BIOS-ului
mov ch, ora
mov cl, minute
mov dh, sec.
mov dl, sutimi de sec.
INT 33h - Mouse
In modul text coord. trebuie shr 3(impartite la 8)
mov ax, 0 - initmouse (mai rapid e xor ax,ax)
mov ax, 1 - afiseaza cursor
mov ax, 2 - ascunde cursor
mov ax, 3 - incarca in bx butonul(1, 4, 2) si-n cx si dx, coord.
mov ax, 4 - seteaza cursorul la x, y
mov cx, x
mov dx, y
mov ax, 07h - seteaza limitele pe X
mov cx, limita minima pe x
mov dx, limita maxima pe x
mov ax, 08h - seteaza limitele pe Y
mov cx, limita minima pe Y
mov dx, limita maxima pe Y
mov ax, 1ah - senzitivitatea(mickeys/sec)
mov bx, senz. pe x
mov cx, senz. pe y
mov dx, dx ;mai bine xor dx, dx
Nu uitati ca la sfarsitul fiecarei functii sa
apelati intreruperea!
Pentru exemple de programe cu functii click
aici .
6. Tehnici + Tips&Tricks:
Tehnici de programare in ASM:
Evaluarea conditiilor logice. Decizii simple si compuse:
Fie secventele pseudocod:
IF (conditie) THEN ramuraIF
ELSE ramuraELSE(poate lipsi)
Scrierea ei in ASM este:
evalueaza conditie
salt conditionat daca e falsa la et1
et2:ramura true
jmp et3(sare in alta parte)
et1:ramura else
IF (cond1) AND (cond2) THEN ramuraIF
ELSE ramuraELSE
In ASM devine:
eval. cond1
salt daca e falsa la et2
eval. cond2
salt daca e falsa la et2
et1:ramuraIF... jmp et3
et2:ramuraELSE
IF (cond1) OR (cond2) THEN ramuraIF
ELSE ramuraELSE
In ASM se scrie:
eval. cond1
salt if true la et2
eval. cond2
salt if true la et2
et1:ramuraELSE ... jmp et3
et2:ramuraIF
WHILE (cond) DO ramura
ASM:
et1:eval. cond
if false jump et2
ramura
jmp et1
et2:
REPEAT ramura UNTIL(cond)
ASM:
et1:ramura
eval. cond.
if false jump et2
jmp et1
et2:
FOR i = L1 TO L2 DO ramura
ASM:
mov cx, L1 ; se incarca L1
et1:ramura
inc cx ; creste cx
cmp cx, L2 ; comparam cu L2
jl et1 ; reia bucla daca nu s-a ajuns la L2
La DOWNTO se scade cx-ul...
Mai elegant e cu LOOP(dar merge doar de la 1)
mov cx, L2
et1:ramura
loop et1; se opreste singur cand a ajuns la L2
Click aici
pentru exemple la aceste tehnici.
Tips&Tricks:
Scriu aici rutine interesante sau mai subtile:
CLI si HLT blocheaza sistemul.
Afisarea unui caracter special: 7 scoate sunet
XOR AX, AX e mult mai rapida ca mov ax, 0
Uneori e nevoie de o mica pauza. Fie utilizati
comanda NOP(care de fapt e XCHG AX, AX...) fie
puneti in CX un numar mare(gen 10000) si dati
et1:loop et1 care cicleaza de CX ori nimic(adica
pierde timp...).
Sa presupunem un sir in DS(presupunand ca variabila
cu sirul e sir1, acesta se incarca cu mov ax, sir1
apoi mov ds, ax). sir1[SI] este caracterul SI din sir1.
Va puteti juca cu faza asta, scriind un sir citit.
O alta rutina frumoasa e jucatul cu cele 3 LED-uri
de la tasta. Aceasta se face astfel:
mov al, 0edh
out 60h, al
mov cx, 10000
et1:loop et1(pauza pentru transmiterea corecta)
mov al, LED(1..7, 2 e NUM, 1 SCROLL, 4 CAPS. Se
accepta si sume, aprinzandu-se mai multe...)
out60h, al
O puteti folosi in combinatie cu ah = 1 din 16h
(care verifica o tasta) pentru a canta pe LED-uri...
Citirea fara ecou pe ecran(caracterul e citit in
AL) e utilizata pe la parole...
Aveti grija cu TSR-urile!!!
Daca doriti sa creati fisiere .COM puneti la inceput
.model tiny si apoi org 100h. Acestea se Tlink-eaza
ci tlink /t [nume].obj
Puteti include fisiere externe (cu macro-uri sau
proceduri) cu include "nume_fisier" dupa .model (...)
Poti face bar in modul grafic cu FOR...
Vezi exemplele !
Copyright 2001 © Gheorghe Stefan, mail: ste_fanus@k.ro
Utilitare ASM pentru download:
tasm.exe (Turbo Assembler),
td.exe (Turbo Debugger),
tlink.exe (Turbo Linker).
Proiecte asm colegi: proiecte.rar
Bibliografie:
- "Programare in limbaj de asamblare", Gheorghe Musca,
Editura Teora, 1996
- Tech Help! v4.0 Copyright © by Flambeaux
Software, Inc., 1990