Limbajul Assembler abc-doar



Yüklə 1,03 Mb.
səhifə4/10
tarix16.12.2017
ölçüsü1,03 Mb.
#35021
1   2   3   4   5   6   7   8   9   10

begin

y:=256;

writeln('Numarul initial este: ',y);

y:=Saltexp(y);

writeln('Numarul returnat este: '.y);

end.

Atribuiti diverse valori lui y si observati ca rezultatul final va fi

egal cu y*2*2*2*2*2 (salt binar stanga de 5 ori).

Procedurile se definesc si se apeleaza la fel ca cele din Pascal,dar,

datorita faptului ca nu returneaza valori,este bine ca rezultatul ope-

ratiilor efectuate sa fie finalizat in interiorul procedurii.O aplicatie

foarte frecventa este apelarea unei intreruperi DOS cu ajutorul unei

instructiuni INT.Atunci cand intreruperea solicitata are sub-functii,se

va transfera initial in registrul AH numarul subfunctiei,dupa care se va

putea apela nivelul de intrerupere si se vor colecta din regisrii datele

returnate (Exemplu: INT 21 h are aproape 100 de subfunctii apelabile).

-21-

EXEMPLU: program assmb4;

uses WinCRT;

var zi,luna:byte;

an:word;

ora,min,sec:byte;

procedure datasistem;

begin

asm

mov AH,2ah

int 21h

mov zi,DL

mov luna,DH

mov an,CX

mov AH,2ch

int 21h

mov ora,CH

mov min,CL

mov sec,DH

end;

end;

begin

datasistem;

writeln('data curenta este: ',zi,' :',luna,' :',an);

writeln('este ora: ',ora,' :',min,' :',sec);

end.

In exemplul de mai sus,am scris o procedura care citeste data si ora sis-

temului.Pentru a citi data am apelat intreruperea DOS 21,2A iar pentru a

citi ora am apelat intreruperea 21,2C.Observati ca apelul intreruperii se

face in doua etape:in prima etapa se transfera in registrul AH numarul

suf-functiei DOS (mov AH,2ah sau mov AH,2ch),iar in etapa a doua se ape-

leaza intreruperea (INT 21h).Remarcati si faptul ca intreruperile DOS

sunt notate hexazecimal,motiv pentru care este extrem de important ca

numarul intreruperii si cel al subfunctiei sa fie urmat de litera h.In

caz contrar,valorile vor fi interpretate decimal (BCD=binary coded deci-

mals) si rezultatul intreruperii va fi complet diferit de cel scontat.

Intreruperea 21h,cu subfunctiile sale permite o gama extrem de larga de

operatii si este extrem de uzitata in assembler.Pentru a putea apela

corect nivelurile de intrerupere,trebuie sa aveti un tabel cu intrerupe-

rile DOS(sunt cateva sute de subfunctii),care poate fi descarcat si de

pe Internet.

Cu notiunile prezentate pana acum puteti deja sa proiectati si sa

editati o serie de functii,necesare pentru proiectele d-voastra.Prin

apelul nivelurilor de intrerupere DOS,se pot exploata practic toate

resursele sistemului de operare,direct,eficient si rapid si se pot tran-

sfera in mediul de operare Windows date preluate din sistemul de operare

DOS.Este insa foarte important sa aveti permanent in atentie formatul

datelor cu care lucreti.In assembler,fiecare expresie utilizata are

asociat un tip.Tipul expresiei este o valoare care exprima dimensiunea

memoriei ocupate de expresia respectiva.Dimensiunea de masoara in bytes.

Principalele tipuri predefinite sunt: BYTE 1,WORD 2,DWORD 4,QWORD 8,

TBYTE 10,NEAR 0FFFEH si FAR 0FFFFH.


-22-

Este bine sa existe intotdeauna o corespondenta directa intre tipul

de data al adresei sursa si tipul de data al adresei de destinatie.

Daca utilizati totusi tipuri de data diferite,trebuie ca adresa de

destinatie sa poata prelua datele(Exemplu: o data de tip byte poate

fi transferata intr-un registru de tip word,dar o data de tip word nu

poate fi transferata intr-un registru de tip byte).

EXEMPLU: program assmb5;

uses WinCRT;

var nr1,nr2:byte;

suma:word;

begin

asm

mov ax,9

mov nr1,al

mov bx,5

mov nr2,bl

add al,bl

mov suma,ax

end;

writeln('nr1= ',nr1);

writeln('nr2= ',nr2);

writeln('suma= ',suma);

end.

Observati ca am transferat in registrul ax o valoare numerica,apoi am

transferat valoarea respectiva intr-o variabila de tip byte.

Valorile numerice imediate nu au un tip definit,dar imediat dupa ce au

fost utilizate intr-o expresie,primesc tipul expresiei respective.Astfel,

valorile mai mici de 255 vor genera expresii de tip BYTE iar cele mai

mari vor genera expresii de tip WORD,etc.

Tabelul de corespondenta dintre datele de tip Pascal si cele de tip

assembler este urmatorul:

PASCAL ASSEMBLER

byte byte

shortint byte

word word

integer word

longint dword

string dword

record dword

array dword

pointer dword

real qword

In acest manual,vom utiliza doar date de tip byte si word,si instructiuni

8086,dar este extrem de important sa retineti si sa evaluati corect

tipul datelor,pentru a putea evolua la nivele superioare de procesare.

Atunci cand proiectati o functie noua,trebuie sa aveti in vedere atat

formatul datelor utilizat intern de algoritmul scris in assembler,cat si

formatul datelor de tip Pascal,care vor prelua valorile rezultate in

urma procesarii (Exemplu: data si ora din exemplul precedent.Uneori datele

vor fi citite din intregul registru: CX returneaza anul,iar alte ori se

vor citi dintr-un subregistru: DL returneaza ziua iar DH returneaza luna).


-23-

Regula generala de utilizare a registrilor,in interiorul unei bucle de

tip asm...end este urmatoarea: bucla trebuie sa conserve registrii BP,SP,

SS si DS (pointerii de stiva si registrul pentru cod si data) dar poate

sa modifice fara restrictii registrii AX,BX,CX,DX,SI,DI,ES si Flags.Ca

rezultat,la intrarea intr-o bucla asm...end,compilatorul va cunoaste

doar valoarea registrilor BP,SP,SS si DS dar nu va avea nici un fel de

informatii referitoare la ceilalti registri (care pot avea valori varia-

bile).Din acest motiv,este bine si prudent ca fiecare bucla asm...end sa

fie urmata de o procedura de eliberare a registrilor si de terminare a

executiei.La intrarea intr-o bucla asm...end,valoarea registrilor generali

poate fi diferita de zero.Este bine sa resetati registri la valoarea utila

fara sa apelati valoarea implicita.Pentru terminarea unui program,se poate

solicita un apel la un nivel de intrerupere DOS de tip 21h,cu una dintre

subfunctiile 0-Program Terminate sau 4c-Terminate Process With Return

Code.

EXEMPLU: program assmb6;

uses WinCRT;

var numar,x,y:word;

function multiplu9(x:word):word;assembler;

asm

mov ax,x

mov bx,9

mul bx

mov numar,ax

end;

procedure sfarsit;assembler;

asm

mov ah,4ch

mov al,00

int 21h

end;

begin

for x:=1 to 9 do

writeln('numarul rezultat este: ',multiplu9(x));

writeln('Tastati ENTER !');

readln;

sfarsit;

end.

In exemplul de mai sus,am declarat si definit o functie si o procedura.

Functia calculeaza un multiplu de noua,iar procedura executa terminarea

programului prin apelul unei intreruperi 21,4Ch.

Valorile registrilor generali nu se conserva la iseirea din bucla.In

exemplul de mai sus,dupa iesirea din functia multiplu9(x),valoarea regis-

trului AX va fi zero.Ca rezultat,nu se pot utiliza valorile registrilor

generali decat in interiorul buclei asm...end aflata in executie.

Pentru a evita coruperea datelor,este bine sa executati o procedura

de terminare a executiei,dupa epuizarea operatiilor efectuate intr-o

bucla asm...end sau dupa o suita de functii si proceduri.In acest manual,

pentru a simplifica la maximum exercitiile,si din economie de spatiu,nu

se vor executa buclele de terminare a exemplelor,decat in situatiile in

care este absolut indispensabil.


-24-

DECLARATII

Programul assembler inclus in Pascal accepta trei tipuri de declaratii

pentru variabile si constante.Acestea sunt:DB(define byte),DW(define word)

si DD(define double word).DB genereaza un byte si poate accepta orice

valoare cuprinsa intre -128 si 255,respectiv orice caracter ASCII.DW ge-

nereaza un word si poate accepta orice valoare cuprinsa intre -32768 si

65535 sau o adresa de offset(pointer de tip NEAR).DD genereaza doua cu-

vinte(double word) si poate accepta valori cuprinse intre -2147483648 si

4294967295 sau o adresa de offset(pointer de tip FAR).

Datele generate cu DB,DW si DD vor fi stocate intotdeauna in segmentul

de cod al programului(ocupa din spatiul rezervat programului).

EXEMPLE:

Declaratie Operand Rezultat

DB 0FFH un byte

DB 7,33 doi bytes diferiti

DB 'A' Ord('A')=codul numeric al caracterului

DB 'Hello..',0DH,0AH Un sir + CR/LF

DB 12,"Turbo Pascal" un sir de tip Pascal

DW 0FFFFH un cuvant(doi bytes)

DW 7,3333 doua cuvinte

DW 'A' este identic cu DB 'A',0= Ord('A'),0

DW 'AB' este Ord('A'),Ord('B') adica DB 'A','B'

DW variabila offset-ul variabilei

DW proces offset-ul procesului

Pentru aplicatiile care utilizeaza in Pascal functii si proceduri scrise

in assembler,este mai simplu sa declarati variabilele si constantele cu

ajutorul conventiilor de tip Pascal(adica in afara buclelor asm...end in

sectiunea de interfata a programului).Variabilele si constantele de tip

Pascal pot fi declarate si neinitializate si vor fi stocate in segmentul

de date al programului(nu afecteaza segmentul de cod).

Registrele nu pot prelua sirurile de caractere,dar pot opera cu adresa

variabilei care le contine.

EXEMPLU: program assmb7;

uses WinCRT;

var text1:string;

adr,sg1:word;

pt1:PChar;

begin

text1:='Limbajul de programare Assembler';

asm

mov ax,OFFSET text1

mov bx,SEG text1

mov dx,ax

mov adr,dx

mov sg1,bx

end;

pt1:=ptr(sg1,adr);

writeln(pt1);

end.

In mod normal,assembler nu poate opera cu date de tip string,dar prin

acest mic artificiu se pot face operatii asupra sirurilor de caractere.


-25-

EXEMPLU: program assmb8;

uses WinCRT;

var text1:string;

adr,sg1:word;

pt1:Pchar;

begin

text1:='Limbajul de programare Assembler';

asm

mov ax,OFFSET text1

add ax,24

mov bx,SEG text1

mov dx,ax

mov adr,dx

mov sg1,bx

end;

pt1:=ptr(sg1,adr);

writeln(pt1);

end.

Exercitiul este identic cu precedentul,dar am efectuat in offset-ul

adresei un salt de 24 de bytes.In ambele exercitii,am utilizat in bucla

asm...end doar adresa sirului de caractere,impartita in doua variabile

de tip word,care contin segmentul si respectiv offset-ul variabilei.

Dupa ce am efectuat eventualele operatii asupra adresei,am reconstituit

un pointer de tip PChar din segmentul si offset-ul variabilei.

Deoarece operatiile cu adresele variabilelor sunt extrem de importante

este utila o sinteza a principalelor elemente.

1. -registrii procesorului 8086 pot accepta valori de maximum 2 bytes

2. -procesorul 8086 segmenteaza memoria in 65536 de segmente,fiecare seg-

ment avand atasat un fragment de 65536 de bytes de memorie.Adresa din

interiorul fiecarui segment poarta numele de OFFSET si poate lua orice

valoare intre 0 si 65536.

3. -ca rezultat,procesorul 8086 poate opera cu date incluse in memorie,pe

o extindere maxima de 65536 x 65536 = 4294967296 bytes(4 Gb).

4. -adresele pot fi reprezentate binar,octal,decimal sau hexazecimal,dar

cea mai frecventa reprezentare este cea in format hexazecimal

EXEMPLU: SEGMENT OFFSET

binar 00000000 00000001 00000000 00000001

hexazecimal 1 : 1

sau :

decimal 15: 65536

hexazecimal 1F: 0FFFFH

Rezulta un format pe 32 de biti,unde atat valoarea segmentului cat si cea a

offset-ului poate fi cuprinsa intre 0 si 65536,in reprezentarea decimala

sau respectiv 00000H si 0FFFFH in reprezentarea hexazecimala.

5. -pentru a efectua operatii asupra adreselor trebuie ca adresele sa fie

reprezentate in acelasi format,si este necesar ca formatul respectiv

sa poata fi acceptat de registrii de procesor.

EXEMPLE: procesorul 8086 nu poate accepta adrese cu format mai mare de

32 de biti,deoarece registii au maxim 16 biti (2 x 16 = 32 )

procesorul 80386 are registrii de 32 de biti si ca rezultat

poate opera cu adrese de 64 de biti (32/segment + 32/offset)


-26-

6. -pentru a efectua operatii cu adrese,trebuie ca formatul adresei sa

fie acceptat de catre programul assembler cu care se apeleaza.

Adresele de 16 biti se pot utiliza exclusiv pentru programe mai

mici de 64 K.Adresele de 32 de biti,sunt adresele curente si sunt

acceptate de toate compilatoarele si aproape toate tipurile de

procesoare actuale.

Pentru a opera cu adrese mai mari,teoretic adresele se pot frag-

menta astfel incat sa fie cuprinse in patru registrii.Astfel,o

adresa poate fi subimpartita astfel:

Base + Index + Scale + Displacement

unde: Base este un registru de 32 de biti,Index este tot un registru

de 32 de biti(cu exceptia ESP),Scale este 1,2,4 sau 8 iar Displace-

ment este tot un registru de 32 de biti (offset-ul).

Pentru incepatori,nu este recomandabil sa opereze decat cu adrese

de 32 de biti.

7. -limitele operatiilor posibile sunt determinate de procesorul instalat

sistemul de operare instalat si programul assembler utilizat.
ETICHETE (Labels)

Se utilizeaza pentru a putea efectua salturi in program.Sunt formate din

identificator urmat de doua puncte.Exemple: NUME1: Nume2: AB1_3: etc.

Etichetele locale,pot fi utilizate doar in interiorul buclelor asm...end,

incep cu semnul @ si se termina cu :.Identificatorul se poate forma din

orice combinatie de litere(A..Z),cifre(0..9),semne _ sau @.

EXEMPLU: program assmb9;

uses WinCRT;

var nr,zz:word;

begin

nr:=7;

writeln('Valorile initiale sunt: ',nr,' si : ',zz);

asm

mov ax,nr

inc ax

jmp @@nume1

add ax,9

mov bx,nr

@@nume1:

add ax,2

mov nr,ax

jmp @@nume2

dec ax

mov bx,ax

@@nume2:

add ax,10

mov bx,ax

mov zz,bx

end;

writeln('Valorile finale sunt: ',nr,' si : ',zz);

end.

Pentru a evalua rezultatul salturilor puteti include instructiunile de

salt (jmp) intre acolade (astfel bucla se va executa fara nici un salt).


-27-

Etichetele locale nu pot fi utilizate in afara buclelor asm...end,

deoarece ar fi interpretate ca fiind adresele unor variabile.In afara

buclelor asm...end,se vor utiliza etichetele de tip Pascal (declarate cu

label+identificator).

Chiar si in interiorul buclelor,este bine sa se utilizeze doua sau

mai multe semne @ inaintea identificatorului,pentru a putea distinge de

la prima vedere locatia etichetelor in program.In plus,compilatoarele si

emulatoarele sau programele de analiza automata pot contine functii care

nu fac distinctia dintre buclele begin...end si cele de tip asm...end si

vor interpreta eronat valoarea identificatorului.

Este bine sa aveti o conventie proprie de formare a denumirilor,astfel

incat sa le regasiti cat mai usor in etapa de depanare a programului.
OPERANZI SI OPERATORI

Pentru formarea expresiilor,am utilizat in exemplele precedente doar

instructiuni 8086,registri si/sau valori imediate.

Pentru formarea expresiilor,assembler-ul integrat in Pascal recunoaste

toate tipurile de date de tip Pascal:constante,variabile,arii de date,

structuri,functii si proceduri,unitati,etichete etc. la care se adauga

si BYTE,WORD,DWORD,QWORD,TBYTE,NEAR,FAR(tipuri assembler predefinite).

In plus,recunoaste si trei constante speciale: @Code(returneaza adresa

segmentului de cod),@Data(returneaza adresa segmantului de date) si

@Result(returneaza offset-ul variabilei rezultate dupa evaluarea unei

functii-nu se poate utiliza in afara functiilor).

Nu se pot utiliza urmatoarele tipuri de date:

-functiile si procedurile standard din unitati (Exemplu: writeln() )

-ariile speciale Mem,MemW,MemL,Port,PortW

-sirurile,numerele in virgula mobila si constantele de setare

-functiile si procedurile declarate cu inline

-etichetele declarate in alt modul de program (Exemplu: in unitati)

-simbolul @Result nu se poate utiliza in afara unei functii

Toate variabilele declarate cu VAR,vor fi interpretate de catre assembler

ca pointeri spre adrese in format de 32 de biti,iar dimensiunea lor va fi

intotdeauna 4(adresa de 4 bytes=doi registri de 16 biti=32 biti).

Pentru a accesa continutul unei variabile,trebuie sa incarcati pointerul

sau si apoi sa accesati adresa spre care pointeaza.

Pentru datele structurate sub forma de inregistrari,structuri si obiecte,

se vor accesa membrii structurilor la fel ca si in Pascal,cu ajutorul ope-

ratorului de selectie (.).

Regulile de formare a expresiilor nu sunt rigide.Daca se respecta regulile

de mai sus,se pot forma expresii diferite ca forma,dar care determina

exact acelasi rezultat:

EXEMPLU: asm

mov AX,(Rect PTR ES:[DI]).B.X

mov AX,Rect(ES:[DI]).B.X

mov AX,ES:Rect[DI].B.X

mov AX,Rect[ES:DI].B.X

mov AX,ES:[DI].Rect.B.X

end;

Toate expresiile din bucla de mai sus genereaza acelasi cod masina si au

aceeasi semnificatie: incarca in AX continutul din ES,membrul X din Rect.B


-28-

Pentru formarea expresiilor din exemplul precedent,s-au utilizat si o

serie de simboluri,denumite operatori,care efectueaza un anumit tip de

operatie asupra datelor.Operatorii acceptati de assemblerul Pascal sunt:

CATEGORIE OPERATOR REZULTAT (ce face)

precedenta & -inlocuieste un identificator

( ) -include o subexpresie

[ ] -marcheaza o adresa de memorie

. -selecteaza un membru al structurii

unari HIGH -returneaza byte-ul cel mai inalt

LOW -returneaza byte-ul inferior

+ -plus unar

- -minus unar

: -inlocuieste un segment

OFFSET -returneaza offset-ul adresei

SEG -returneaza segmentul adresei

TYPE -returneaza tipul(dimensiunea)

PTR -determina tipul

* -multiplicator

/ -divizor

MOD -divide cu rest (modul din x)

Yüklə 1,03 Mb.

Dostları ilə paylaş:
1   2   3   4   5   6   7   8   9   10




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin