Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web

ASM - Limbaj de asamblare

"Un programator nu ajunge niciodata la nivel de expert daca nu trece prin dezvoltarea de programe ASM."

INDEX:

  1. Despre limbajul ASM
  2. Date generale. Arhitectura procesorului
  3. Structura unui program ASM
  4. Instructiuni ASM
  5. Intreruperi si functii importante
  6. Tehnici + Tips&Tricks
  7. 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:
Mai sunt si patru registri de segment: 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:
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: 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:
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: 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 :
  1. Instructiuni de transfer
  2. Instructiuni aritmetice
  3. Instructiuni logice
  4. Instructiuni pentru siruri
  5. Instructiuni de salt
  6. 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:
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: