Limbajul Assembler abc-doar


in stiva rezultatul si inlocuieste ST cu valoarea 1.Rezultatul



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

in stiva rezultatul si inlocuieste ST cu valoarea 1.Rezultatul

trebuie recuperat din ST(1) (dupa o operatie FXCH).Rezultaul

este exprimat in radiani(valori intre 2**(-63) si 2**(63)).

FPATAN -Calculeaza arctangenta raportului y/x unde x este in ST si y

este valoarea din ST(1).Rezultatul in ST,exprimat in radiani.
Instructiunea F2XM1 este foarte usor de exploatat:

EXEMPLU: program assmb99;

{$N+)

uses WinCRT;

begin

a:=0.12345;

asm

FLD a

F2XM1

FST b

end;

writeln('2 la puterea (',a:2:4,'-1) este:',b:5:5);

end.
Pentru FYL2X si FYL2XP1 este importanta ordinea de transfer a valorilor:

EXEMPLU: program assmb100;

{$N+}

uses WinCRT;

var a,b,c:double;

begin

a:=7;

b:=5;

asm

FLD b

FLD 1

FYL2X

FST c

end;

writeln('rezultatul pentru 5x(log2 7) este: ',c:6:6);

end.

Instructiunea FYL2XP1 este identica dar adauga 1 la valoarea x.Astfel

FYL2XP1 cu x=7 si y=5 este identica cu FYL2X cu x=8 si y=5.Cele doua

instructiuni se pot utiliza si sinergic,pentru a calcula rezultatul

fata de puterea imediat urmatoare a lui x.Ambele sunt utile pentru

calculul logaritmic.


-86-

Pentru calculul tangentei si arctangentei,se poate utiliza un algoritm

elementar de genul:

EXEMPLU: program assmb101;

{$N+}

uses WinCRT;

var a,b,c,d:double;

begin

a:=17533.17;

b:=9339.23;

asm

FLD b

FLD a

FPTAN

FXCH

FST c

FLDZ

FLD b

FLD a

FPTAN

FST d

end;

writeln('Tangenta(b/a) este: ',c:8:8);

writeln('Arctangenta (b/a) este: ',d:8:8);

end.
Un alt set de instructiuni este utilizat pentru controlul ramificatiilor

din program (dar poate fi utilizat si pentru a compara doua valori cu

scopul de a le sorta,etc...).

In urma comparatiei dintre cele doua valori,se poate utiliza una dintre

instructiunile de salt conditionat.Instructiunile din acest set utili-

zeaza registrul de stare,respectiv grupurile de biti denumite C0,C1,C2 si

C3 (sau Z; C; A; si S; )-vezi tabelul prezentat la descrierea registrilor.

Procesorul 8087 nu contine nici o instructiune care sa permita accesul

la registrul de status.Din acest motiv,pentru a putea evalua valoarea

acestui registru,se apeleaza la instructiunea FSTW AX,care transfera

valoarea registrului de status 8087 in registrul AX 8086.Este singura

instructiune care permite schimbul de date dintre cele doua procesoare.

In rest,toate operatiile de transfer trebuiesc intermediate prin varia-

bile de memorie.Din AX,valoarea poate fi exploatata ca atrare,sau se

poate transfera byte-ul AH in registrul FLAGS cu ajutorul instructiunii

SAHF.In acest caz,bitul de control C0 8087 devine CF(carry flag) 8086,

CZ devine PF(parity flag) iar CA devine ZF(zero flag).Bitul de control

C1 nu este transferat si nici nu este necesar pentru evaluare.In conti-

nuare,flagurile 8086 pot fi utilizate pentru salturi conditionate cu

ajutorul instructiunilor ja,jae,jb,jbe,jz etc.

Deoarece acest gen de control al ramificatiilor din program implica

un numar destul de mare de operatii,este bine sa utilizati o schema

grafica in care sa marcati fiecare operatie efectuata (nu va bazati pe

memorie sau pe intuitie).Intr-o varianta mai simpla,controlul ramificatii-

lor din program se poate realiza si in functie de byte-ul superior din

valoarea transferata in AX (fara apel la flagurile 8086).


-87-

Instructiunile pentru compararea operanzilor sunt:

FCOM -Compara ST cu ST(1) (vezi tabelul de la pagina 75)

FCOM ST(nr) -Compara ST cu ST(nr)

FCOM mem -Compara ST cu mem

FICOM mem -Compara ST cu numarul intreg mem

FTST -Compara ST cu zero

EXEMPLU: program assmb102;

{$N+}

uses WinCRT,WinProcs;

var a:double;b:word;

begin

a:=1.17;

asm

FLD a

FLDPI

FCOM

FSTSW AX

mov b,AX

end;

writeln('Valoarea registrului de stare este: ');

writeln(LOBYTE(b),'-',HIBYTE(b));

end.

Valoarea returnata este 32-48,care in reprezentare binara este:

0010 0000 - 0011 0000 .Se observa ca flagurile CF,PF si ZF au valoarea

zero,deci valoarea din ST este mai mare decat cea comparata din ST(1).

(se evalueaza bitii 0, 2 si 6 din valoarea byte-ului superior)

Pentru a efectua o ramificatie simpla se poate utiliza byte-ul superior:

EXEMPLU: program assmb102;

{$N+}

uses WinCRT,WinProcs;

var a:double;b:word;

begin

writeln('Introduceti un numar : ');

read(a);

asm

FLD a

FLDPI

FCOM

FSTSW AX

mov b,AX

end;

if HIBYTE(b) = 112 then

writeln('Numarul introdus este egal cu PI ');

if HIBYTE(b) = 49 then

writeln('Numarul introdus este mai mare decat PI');

if HIBYTE(b) = 48 then

writeln('Numarul introdus este mai mic decat PI');

end.

112 reprezentatr binar este 0111 0000 (adica C0 = 0, C2 = 0 si C3 = 1)

49 reprezentat binar este 0011 0001 (adica C0 = 1, C2 = 0 si C3 = 0)

Pentru a testa precizia,introduceti 3.14...si cat mai multe zecimale.


-88-

Registrul de STATUS are urmatoarea structura (pe biti):

B Z TOP C A S N * P U O Q D I

unde:

I -invalid operation

D -denormalized operand

Q -division of nonzero by zero

O -overflow

U -underflow

P -inexact (precision)

N -indicates a pending interrupt

iar C,A,Z si S sunt bitii de control C0,C1,C2 si C3
Registrul CONTROL are urmatoarea structura (pe biti):

x x x IC RC PC N x PM UM OM QM DM IM

unde:

IC -infinity control

RC -rounding control

PC -precision control

iar PM,UM,OM QM,DM si IM sunt controlul flagurilor din registrul STATUS
Pentru compararea operanzilor si extragerea stivei se pot utiliza urma-

toarele instructiuni:

FCOMP -Compara ST cu ST(1) si extrage ST

FCOMP ST(nr) -Compara ST cu ST(nr) si extrage ST

FCOMP mem -Compara ST cu mem si extrage ST

FICOMP mem -Compara ST cu numarul intreg mem si extrage ST

FICOMPP ST(nr) -Compara ST cu ST(nr) si apoi extrage din stive de doua

ori.Atat sursa cat si destinatia sunt distruse.

Se utilizeaza la fel ca si FCOM (vezi si tabelul de la pagina 75) dar

cu rezerva ca registrul ST este anulat prin extrgaerea din stiva.
Un alt set de instructiuni permite transferul datelor de control.Aceste

instructiuni sunt:

FLDCW mem2byte -Incarca cuvantul de control

FSTCW mem2byte -Memoreaza cuvantul de control

FSTSW mem2byte -Memoreaza cuvantul de stare

FLENV mem14byte -Incarca mediul

FSTENV mem14byte -Memoreaza mediul

FRSTOR mem94byte -Restaureaza starea

FSAVE mem94byte -Salveaza starea

FSTSW AX -memoreaza datele in registrul AX 8086
Aceste instructiuni se utilizeaza pentru controlul si/sau depanarea pro-

cesorului 8087.Nu sunt indicate incepatorilor.Pentru utilizarea lor

corecta este bine sa consultati si literatura de specialitate,sau cel

putin cateva articole de pe Internet.In principiu,cele notate cu mem2byte

utilizeaza variabile de tip word si opereaza cu un registru de stare sau

de control,cele notate mem14byte opereaza cu cei sapte registri de control

(STATUS,CONTROL,TAG,INSTRUCTION,ADDRESS,DATA,ADDRESS) iar cele notate cu

mem94byte opereaza cu toate datele din procesor (cei 8 registri generali

de cate 10 bytes si cei 7 registri de control de cate 2 bytes).


-89-

EXEMPLU: program assmb104;

{$N+}

uses WinCRT,WinProcs;

var a,b:word;

begin

a:=1133;

asm

FLDCW a

FST b

end;

writeln('Cuvantul de control este: ',b);

writeln('adica: ',LOBYTE(b),'-',HIBYTE(b));

end.

Pentru a controla modul de rotunjire a zecimalelor sau precizia de

calcul,trebuie sa alegeti cu atentie valoarea transferata in registrul

de control atfel incat bitii 8-9 si respectiv 10-11 din reprezentarea

binara a valorii respective sa respecte una dintre conditiile prezentate

la pagina 75.

In exemplul de mai sus,valoarea 109-4 in reprezentare binara este:

0110 1101 - 0000 0100

deci grupul de biti 8-9 este 1 0 adica precizia este de 53 de biti

iar grupul de biti 10-11 este 1 1 adica rotunjirea este prin trunchiere
Alte instructiuni 8087 sunt:

FINIT -Repozitiveaza coprocesorul si restaureaza conditiile implicite

FCLEX -Sterge toate flagurile si indicatoarele busy

FINCSTP -adauga 1 la pointerul de stiva din cuvantul de stare

FDECSTP -scade 1 din pointerul de stiva din cuvantul de stare

FFREE ST(nr) -marcheaza registrul respectiv ca fiind gol.Valoarea nu este

stearsa dar nu mai poate fi accesata

FNOP -copiaza ST in ST(opratie nula),determina o intarziere

EXEMPLU: program assmb105;

{$N+}

uses WinCRT;

var a,b:double;

begin

a:=133.775;

asm

FLD a

FNOP

FFREE ST(0)

FST b

FCLEX

FINIT

end;

writeln(b);

end.

In exemplu de mai sus,FFREE blocheaza registrul ST si determina o eroare,

dar FCLEX sterge flag-ul iat FINIT restaureaza conditia implicita.FNOP

determina doar o intarziere de un ciclu (nu afecteaza registrii).In

absenta instructiunii FCLEX,programul returneaza un mesaj de eroare.


-90-

UNITATI SI BIBLIOTECI DLL

-se editeaza si exploateaza la fel cu cele editate in Pascal.

EXEMPLU: unit asmunit1;

INTERFACE

{$N+}

uses WinCRT;

var raza,rezultat,xxx,yyy:double;

function arie(xxx:double):double;

function volum(xxx:double):double;

IMPLEMENTATION

function arie(xxx:double):double;

begin

writeln('Introduceti raza: ');

read(raza);

xxx:=2;

asm

FLD raza

FMUL raza

FLDPI

FMUL

FLD xxx

FMUL

FST rezultat

end;

writeln('Aria hemisferei este: ',rezultat:15:10);

end;

function volum(xxx:double):double;

begin

writeln('Introduceti raza: ');

read(raza);

xxx:=4;

yyy:=6;

asm

FLD reza

FMUL raza

FMUL raza

FLDPI

FMUL

FLD xxx

FMUL

FLD yyy

FDIV

FST rezultat

end;

writeln('Volumul hemisferei este: ',rezultat:15:10);

end;

begin

end.

Dupa compilare,cele doua functii din unitatea asmunit1 pot fi apelate

dupa ce unitatea a fost introdusa in memorie cu USES...Observati ca nu

mai sunt necesare unitatile WinTypes si WinProcs.


-91-

Pentru exploatarea unitatii se poate utiliza un algoritm de genul:

EXEMPLU: program assmb106;

{$N+}

uses WinCRT,asmunit1;

var valoare1:double;

begin

valoare:=arie(valoare1);

valoare1:=volum(valoare1);

end.
Nu uitati sa compilati unitatea inainte de a o apela.Daca nu aveti

nici pana acum o unitate de functii proprii,este bine sa incercati sa

scrieti prima functie sau procedura.Unitatile cu functii si proceduri

editate in assembler prezinta o serie de avantaje.In primul rand se

reduce spatiul ocupat in memoria de operare de unitatile accesorii din

Pascal.In al doilea rand,creste viteza de executie.Pentru a executa o

singura operatie,aceasta optimizare este absolut insesizabila (cateva

nanosecunde),dar in cazul in care operatia respectiva este repetata de

cateva milioane de ori (cum este cazul browserelor de Internet),optimi-

mizarea este substantiala si se masoara in secunde sau chiar zeci de

secunde.In al treilea rand,editarea de unitati proprii asigura un grad

foarte mare de flexibilitate,pentru probleme si situatii extrem de dife-

rite.

In cazul in care editati unitati exclusiv pentru uzul personal,puteti

sa aplicati orice metode de programare doriti,cu conditia sa va puteti

rezolva problema propusa.In cazul in care doriti a unitatile respective

sa poata fi utilizate si de altii,trebuie sa respectati cu strictete

toate regulile de format si exprimare incluse in standardele IEEE pentru

Pascal si respectiv pentru Assembler.Este bine ca unitatile sa poarte

denumiri cat mai simple,clare si sugestive.Pentru a simplifica munca de

depanare,insotiti unitatea furnizata si de fila .pas din care a fost

generata.Daca unitatea contine un numar mare de functii,este bine sa

fie insotita si de o fila de sinteza in care sunt prezentate pe scurt

doar functiile existente si conventiile de apelare a lor.Daca unitatile

contin functii mai greu de evaluat la prima vedere,este bine sa editati

si o fila de tip text,in care sa explicati detaliat modul de exploatare

al fiecarei functii,domeniul de reprezentare,principalele tipuri de

aplicatii,descrierea mediului (enviroment) in care trebuie apelata pentru

performante optime,modul de apelare,eventualele limite sau exceptii ne-

rezolvate,etc.

Pentru variabilele utilizate in unitati este bine sa utilizati iden-

tificatori cu nume cat mai lung si explicit,pentru a evita supraincarcarea

identificatorilor (Exemplu: daca doua sa mai multe unitati utilizeaza

variabile denumite x si y,incarcarea acestor unitati in cadrul unui

singur program va genera conflicte de identificator,sau va executa ope-

ratiile dupa un algoritm eronat,bazat pe proximitatea identificatorului).

In cazul unitatilor,toate variabilele declarate in modulul denumit INTER-

FACE vor fi transferate in memoria de operare in etapa de compilare a

programului care apeleaza uniatatea respectiva,si vor ramane in memoria

de operare pana la sfarsitul programului.Din acest motiv,este bine sa

va limitati la variabilele absolut necesare pentru executia functiilor.


-92-

In unitati,functiile si procedurile pot fi ordonate si sistematizate sub

forma de obiecte,care vor fi utilizate apoi sub forma de module.

EXEMPLU:

unit asmunit2;

INTERFACE

{$N+)

uses WinTypes,WinProcs,OWindows,ODialogs,WinCRT,Strings;

type PTW = ^TW;

TW = object(TWindow)

ED1,ED2:PEdit;

BT1:PButton;

PS1,PS2:PStatic;

constructor Init(AParent: PWindowsObject;ATitle:PChar);

procedure Buton(var Msg: TMessage);virtual id_First + 10;

end;

TDlgApp = object(TApplication)

procedure InitMainWindow;virtual;

end;

IMPLEMENTATION

constructor TW.Init(AParent: PWindowsObject; ATitle: PChar);

begin

inherited Init(AParent,ATitle);

PS1:=New(PStatic,Init(@Self,201,'Introduceti raza:',30,50,150,20,0));

PS2:=New(PStatic,Init(@Self,202,'Aria cercului este:',330,50,150,20,0));

ED1:=New(PEdit,Init(@Self,301,'',30,90,140,30,30,False));

ED2:=New(PEdit,Init(@Self,302,'',330,90,140,30,30,False));

BT1:=New(PButton,Init(@self,101,'Calculeaza',200,200,90,20,True));

end;

procedure TW.Buton(var Msg:TMessage);

var text:PChar;nrx:double,n:integer;sss:string;

begin

text:=' ';

ED1^.GetLine(text,30,0);

Val(text,nrx,n);

asm

FLD nrx

FMUL nrx

PLDPI

FMUL

FST nrx

end;

Str(nrx:15:6,sss);

StrPCopy(text,sss);

ED2^.SetText(text);

end;

procedure TDlgApp.InitMainWindow;

begin

MainWindow :=New(PTW,Init(nil,'Aria cercului:'));

end;

begin

end.


-93-

Obiectul din unitatea asmunit2 poate fi apelat astfel:

EXEMPLU: program assmb107;

{$N+}

uses asmunit2;

var cerc:TDlgApp;

begin

cerc.Init(nil);

cerc.Run;

cerc.Done;

end.

Observati nu mai este necesara nici o alta unitate Pascal Standard.

Obiectul din unitatea editata,este executabil ca un modul independent.
Pentru a edita biblioteci DLL,regulile sunt la fel ca in Pascal:

EXEMPLU: library asmDLL1;

{$N+}

function sfera(raza1:double):double;export;

var n1,n2,volum:double;

begin

n1:=4;

n2:=3;

asm

FLD raza1

FMUL raza1

FMUL raza1

FLDPI

FMUL

FLD n1

FMUL

FLD n2

FDIV

FST volum

end;

sfera:=volum;

end;

exports

sfera index 1;

begin

end.

Dupa compilare,biblioteca nou creata poate fi utilizata,cu conditia sa

fie arhivata in acelasi director cu programul din care a fost apelata.

Bibliotecile DLL editate in assembler prezinta toate avantajele pe care

le ofera bibliotecile DLL in general,la care se adauga supletea si

viteza de executie generata de apelul direct al procesorului.

In exemplul de mai sus,puteti observa faptul ca nu am apelat la nici

o bibliotecta Pascal Standard.Cu exceptia diractivei de precompilare

{$N+} necesara pentru activarea procesorului 8087 si implicit a for-

matelor de numere reale,nu a fost necesara incarcarea bibliotecilor

clasice WinCRT,WinTypes si WinProcs.Se realizeaza astfel o economie

semnificativa de memorie.In plus,definitia functiei nu se incarca in

memorie decat in momentul declaratiei.

-94-

In continuare,biblioteca se apeleaza la fel ca orice biblioteca DLL.

Astfel in cadrul unui program oarecare,se declara functia in mod identic

cu cel in care a fost declarata in biblioteca DLL,iar in locul definitiei

se utilizeaza cuvantul cheie EXTERNAL urmat de numele filei care contine

biblioteca DLL.

EXEMPLU: program assmb108;

{$N+}

uses WinCRT;

var x:double;

function sfera(raza1:double):double;external 'asmDLL1.dll';

begin

writeln('Introduceti raza sferei:');

Read(x);

writeln('Volumul sferei este:',sfera(x):15:6);

end.

Sunt posibile toate cele trei tipuri de apel:prin nume,prin index sau

prin denumirea alias (prin numele alternativ al functiei declarate).

Pentru detalii despre modul de editare si apelare al bibliotecilor DLL

din Pascal,consultati bibliografia acestui limbaj.

Observati ca fila assmb108.pas ocupa 224 de bytes,in timp ce fila

asmDLL1.dll ocupa 3214 bytes iar fila executabila assmb108.exe ocupa

57171 bytes de memorie.

Bibliotecile de functii DLL (biblioteci alocate dinamic) sunt foarte

utile atunci cand se lucreaza cu un numar foarte mare de functii,care

daca ar fi incarcate simultan ar depasi spatiul de memorie de operare.

Cu ajutorul bibliotecilor DLL,functiile se incarca in memorie secvential,

doar in momentul in care sunt necesare in program,dupa care memoria este

eliberata pentru a permite executia unei alte functii.In plus,mai multe

programe sau chiar mai multi utilizatori pot partaja simultan aceasi

biblioteca de functii DLL.Pentru detalii,consultati literatura de spe-

cialitate,si limbajele Pascal,C++,Delphi etc.
Cu aceste notiuni elementare,se incheie acest abecedar.Notiunile

prezentate sunt departe de a fi exhaustive,dar sunt suficiente pentru

a va simplifica munca de editare a unor programe si aplicatii simple.

Doritorii vor explora pe cont propriu seturile de instructiuni implementa-

te in procesoarele moderne (80386,80486 si urmatoarele),precum si modul

in care pot fi utilizate pentru a realiza cooperarea dintre doua sau

mai multe procesoare,procesarea paralela a datelor etc.Dar nu uitati:

de cele mai multe ori,solutia cea mai buna este si cea mai simpla.Nu

cautati solutii savante atunci cand exista o solutie elementara la

indemana.Nu are rost sa scrieti in assembler functii care au fost deja

implementate in Pascal.Cautati intotdeauna solutia cea mai simpla.Nu va

complicati cu sisteme de protectie prea sofisticate (o analiza statistica

a demonstrat ca proprietarul casei este cel care sare cel mai des peste

gardul de la gradina).Daca puteti,aveti in vedere dictonul latinesc:

NON MULTA,SED MULTUM

*** S F A R S I T ***
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