|
ca operanzi si registrii sau variabilele de memorie.Instructiunile
|
səhifə | 8/10 | tarix | 16.12.2017 | ölçüsü | 1,03 Mb. | | #35021 |
| ca operanzi si registrii sau variabilele de memorie.Instructiunile
AND,OR si XOR actualizeaza flag-urile SF,ZF si PF din registrul
FLAGS.In rest regulile sunt la fel ca si pentru ADD.
EXEMPLU: program assmb57;
uses WinCRT;
var A,B,C:word
begin
asm
mov A,5
mov BX,7
AND A,BX
mov AX,A
OR AX,BX
mov B,AX
XOR AX,BX
mov C,AX
end;
writeln(' 5 AND 7 este: ',A);
writeln(' 5 OR 7 este: ',B);
writeln(' 7 XOR 7 este: ',C);
end.
Dupa cum se observa,operatiile se pot efectua intre registri si variabile
in orice combinatie posibila (inclusiv valorile imediate).
-55-
SHL d,c si
SHR r,c - sunt identice cu operatiile logice cu acelasi nume,dar accepta
si registrii sau variabilele de memorie pentru operandul de destinatie
respectiv o valoare imediata sau un registru CL pentru operandul sur-
sa.Pentru a executa saltul spre stanga,procesorul adauga zerouri la
capatul din dreapta,pe masura ce bitii sunt eliminati la capatul din
stanga al expresiei binare.Pentru a executa saltul spre dreapta,pro-
cesorul adauga zerouri la capatul din stanga,pe masura ce bitii sunt
eliminati la capatul din dreapta.Ceilalti biti,avanseaza spre stanga,
sau respectiv spre dreapta (in functie de sensul operatiei).
EXEMPLU: numarul initial 195 este 1100 0011
dupa un salt la stanga devine 1000 0110 (134)
iar dupa un salt la dreapta devine 0110 0001 (97)
Ultimul bit care iese este salvat in flagul CF.
EXEMPLU: program assmb58;
uses WinCRT;
var nr1,nr2:byte;
begin
asm
mov AL,195
SHL AL,1
mov nr1,AL
mov BL,195
mov nr2,BL
SHR nr2,1
end;
writeln(' 195 SHL 1 este: ',nr1);
writeln(' 195 SHR 1 este: ',nr2);
end.
Daca se executa un salt dublu spre stanga 1100 0011 devine 0000 1100 (12).
Daca se opereaza cu date de tip word,practic se obtine un salt binar ex-
ponential al puterilor lui doi(creste sau scade exponentul lui 2).
Executati operatia pentru acealsi numar si cu un salt prograsiv si obser-
vati deplasarea bitilor in reprezentarea binara a numarului obtinut.
Atentie:-rezultatul returnat depinde de tipul de data.
ROL d,c si
ROR d,c -sunt operatiile de rotatie a bitilor (ROL=Rotate Left iar ROR=
Rotate Right).La fel ca si pentru SHL si SHR,operandul de destinatie
poate fi un registru sau o variabila de memorie iar operandul sursa
trebuie sa fie o valoare imediata sau un registru CL.Rotatia se face
la fel ca pentru SHL si SHR,dar cu diferenta ca bitii care ies la
unul dintre capete sunt adaugati la celalat capat (in loc sa fie
inlocuiti cu zerouri).Astfel,de exemplu pentru o operatie de salt
dublu la stanga,primii doi biti de la capatul din stanga vor fi
eliminati si vor fi adaugati la capatul din dreapta,dupa ce toti
ceilalti biti au avansat cu doua locuri.
EXEMPLU : valoarea initiala 92 este: 0101 1100
dupa salt devine 113 adica: 0111 0001
Practic primii doi biti ( 01 ) au fost eliminati la capatul din
stanga si adaugati la capatul din dreapta (dupa 00 )
Daca se face un salt de patru biti,ambele operatii returneaza acelasi nr.
-56-
EXEMPLU: program assmb59;
uses WinCRT;
var nr1,nr2:byte;
begin
asm
mov AL,92
ROL AL,4
mov nr1,AL
mov AL,92
ROR AL,4
mov nr2,AL
end;
writeln('92 ROL 4 este: ',nr1);
writeln('92 ROR 4 este: ',nr2);
end.
Ambele instructiuni returneaza acelasi rezultat,adica 197 deoarece:
cele doua rotatii sunt simetrice:
92 este 0101 1100 iar dupa salt 4 stanga devine 1100 0101 adica 197
92 este 0101 1100 iar dupa salt 4 dreapta devine 1100 0101 adica 197
Practic,pentru valorile de tip byte saltul de patru biti este simetric.
Pentru valorile de tip word,simetria se obtine la saltul de 8 biti,etc.
Pentru a exemplifica un salt nesimetric,efectuati exercitiul urmator:
EXEMPLU: program assmb60;
uses WinCRT;
var nr1,nr2:byte;
begin
asm
mov AL,92
ROL AL,2
mov nr1,AL
mov AL,92
ROR AL,2
mov nr2,AL
end;
writeln(' 92 ROL 2 este: ',nr1);
writeln(' 92 ROR 2 este: ',nr2);
end.
In acest exemplu,in urma rotatiilor:
92 adica 0101 1100 ROL 2 devine 0111 0001 adica 113 iar
92 adica 0101 1100 ROR 2 devine 0001 0111 adica 23
Observati ca bitii preluati de la unul dintre capete se regasesc la
capatul opus.Rezultatul returnat este determinat de tipul de data.Astfel
daca utilizati tot valoarea 92 dar pentru o data de tip word se vor
obtine valorile 368 pentru ROL si 23 pentru ROR.
Daca utilizati aceste instructiuni este bine sa aveti permanent in
vedere reprezentarea binara a numerelor si sa verificati cu atentie
rezultatul returnat.Orice greseala de format sau de salt,poate determina
vicieri semnificative ale rezultatului.Operatiile de acest gen se pot
utiliza si pentru a parcurge si analiza datele reprezentate in format
binar.Se pot scrie rutine de analiza automata a valorilor numerice,sau
a caracterelor ASCII in functie de reperezentarea lor binara.
-57-
RCL d,c si RCR d,c sunt identice cu ROL si ROR dar modifica si flagul CF
prin setarea acestuia la valoarea ultimului bit care a iesit de la
capatul de iesire.In rest toate regulile si rezultatul returnat
corespund celor de la ROL si ROR.
TEST d,s -efectueaza aceeasi operatie ca si instructiunea AND,dar fara
sa modifice operandul de destinatie.Practic,instructiunea compara
cei doi operanzi si modifica doar registrul FLAGS fara sa afecteze
cu nimic cei doi operanzi.Regulile sunt identice cu cele de la
instructiunea ADD.
EXEMPLU: program assmb61;
uses WinCRT,WinProcs;
var nr1:word;
begin
asm
mov AX,-155
mov BX,-77
TEST AX,BX
PUSHF
pop nr1
end;
writeln('registrul FLAGS este: ',HIBYTE(nr1),'-',LOBYTE(nr1));
end.
Exemplul de mai sus returneaza : 2 - 134 adica in reprezentare binara
registrul FLAGS contine valoarea :000000010 10000110 adica flag-urile
2 (PF-parity flag),7 (SF-sign flag) si 9 (IF-interrupt flag) sunt setate
cu valoare 1 (bitul 3 nu are nici o semnificatie).
INSTRUCTIUNI PENTRU TRANSFER DE CONTROL
-transferta controlul executiei la o anumita locatie (adresa)
CALL a - transfera controlul (executia) la procedura situata la adresa
specificata (prin a) si salveaza adresa de la care se pleaca,in
memoria stiva,pentru a putea fi utilizata ulterior de instructiunea
RET,care reutrneaza controlul la adresa de pornire (citeste adresa
stocata in stiva).Se utilizeaza pentru a efectua salturi neconditio-
nate in program.Este una dintre cele mai vechi instructiuni din
istoria limbajelor de programare.Actual este depasita,dar s-a pastrat
in uz,mai ales pentru compatibilitatea cu programele mai vechi.
EXEMPLU: program assmb62;
uses WinCRT;
var nr1:word;
begin
asm
mov AX,33
CALL @@Nume1
mov AX,77
@@Nume1:
INC AX
mov nr1,AX
end;
writeln('registrul AX este: ',nr1);
end.
-58-
Adresa de pornire se poate prelua cu POP si poate fi utilizata pentru un
nou salt,sau poate fi preluata direct din stiva cu instructiunea RET,
care returneaza controlul la adresa de la care s-a apelat instructiunea
CALL.Daca o anumita adresa este apelata in mod repetat,de la diferite
locatii din program,se poate scrie o procedura care sa returneze adresa
de pornire:
EXEMPLU: program assmb63;
uses WinCTR;
var nr1:word;
procedure Test;
begin
asm
CALL @@Adresa1
RET
@@Adresa1:
mov AX,55
mov nr1,AX
CALL @@Adresa2
JMP @@Adresa1
@@Adresa2:
pop nr1
end;
end;
begin
Test;
writeln('Adresa stocata este: ',nr1);
end.
Pentru specificarea adresei,cea mai simpla modalitate este sa utilizati
o eticheta (Label).Atentie,salturile apelate prin CALL se executa necon-
ditionat.Daca la adresa specificata nu exista o iesire valida din pro-
gram,acesta se va executa in continuare in background.Daca doua adrese
se apeleaza reciproc prin CALL se formeaza o bucla cu executie infinita
din care nu se poate iesi decat prin oprirea calculatorului.
JMP a - este instructiunea de salt neconditionat la adresa specificata
Este similara cu CALL,dar permite specificarea adresei atat direct
(Exemplu: JMP 100 h sau JMP 0FFFFh:0 ) cat si indirect:
EXEMPLU: program assmb64
uses WinCRT;
var nr1:word;
begin
asm
JMP @@ETICHETA1
mov AX.55
mov BX,77
@@ETICHETA1:
mov AX,'W'
mov nr1,AX
end;
writeln('registrul AX contine valoarea: ',nr1);
end.
Saltul se efectueaza la adresa specificata prin eticheta.
-59-
Instructiunea JMP este mai moderna si a inlocuit instructiunea CALL in
majoritatea programelor recente.Adresa poate fi specificata si indirect,
adica prin intermediul unui pointer spre adresa respectiva,sau cu ajuto-
rul unui registru in care este stocata adresa de referinta.
In plus,instructiunea JMP are si o serie intreaga de variante de salt
conditionat.Aceste variante executa transferul controlului doar daca este
indeplinita o anumita conditie.Conditiile pentru salt sunt determinate
de starea registrului FLAGS.In functie de conditia evaluata din registrul
FLAGS,varsiunile instructiunii JMP au o terminate mnemotehnica formata
dupa cum urmeaza:
SUFIX MNEMOTEHNIC CONDITIA EVALUATA DESCRIERE
========================================================================
o OF = 1 overflow
no OF = 0 not overflow
c CF = 1 carry
b CF = 1 below
nae CF = 1 not above nor equal
nc CF = 0 not carry
ae CF = 0 above or equal
nb CF = 0 not below
e ZF = 1 equal
z ZF = 1 zero
ne ZF = 0 not equal
nz ZF = 0 not zero
be CF OR ZF = 1 below or equal
na CF OR ZF = 1 not above
a CF OR ZF = 0 above
nbe CF OR ZF = 0 not below nor equal
s SF = 1 sign
ns SF = 0 not sign
p PF = 1 parity
pe PF = 1 parity even
np PF = 0 not parity
po PF = 0 parity odd
l SF XOR OF = 1 less
nge SF XOR OF = 1 not greater nor equal
ge SF XOR OF = 0 greater or equal
nl SF XOR OF = 0 not less
le (SF XOR OF) OR ZF = 1 less or equal
ng (SF XOR OF) OR ZF = 1 not greater
g (SF XOR OF) OR ZF = 0 greater
nle (SF XOR OF) OR ZF = 0 not less nor equal
==========================================================================
Versiunile instructiunii JMP se vor forma adaugand la litera J(de la JUMP)
combinatia de simboluri mnemotehnice care descrie cel mai bine conditia
care trebuie evaluata. EXEMPLE:
JB/JNAE -Jump on BELOW/Jump on NOT ABOVE OR EQUAL
JBE/JNA -Jump on BELOW OR EQUAL/Jump on NOT ABOVE
JE/JZ -Jump on EQUAL/Jump on ZERO
JL/JNGE -Jump on LESS/Jump on NOT GREATER OR EQUAL
JLE/JNG -Jump on LESS OR EQUAL/Jump on MOT GREATER
-60-
JNB/JAE - Jump on NOT BELOW/Jump on ABOVE OR EQUAL
JNBE/JA - Jump on NOT BELOW OR EQUAL/Jump on ABOVE
JNE/JNZ - Jump on NOT EQUAL/Jump on NOT ZERO
JNL/JGE - Jump on NOT LESS/Jump on GREATER OR EQUAL
JNLE/JG - Jump on NOT LESS OR EQUAL/Jump on GREATER
JNO - Jump on NOT OVERFLOW
JNP/JPO - Jump on NOT PARITY/Jump on PARITY ODD
JNS - Jump on NOT SIGN
JO - Jump on OVERFLOW
JP/JPE - Jump on PARITY/Jump on PARITY EVEN
JS - Jump on SIGN
Toate operatiile de salt lasa registrul FLAGS nemodificat.Ca rezultat,
se pot utiliza siruri succesive de instructiuni conditionale care tes-
teaza si evalueaza registrul FLAGS pana cand una dintre conditii este
satisfacuta se se efectueaza saltul.
Exista si o instructiune conditionala care evalueaza registrul CX.Astfel
JCXZ (Jump on CX ZERO) efecteaza saltul doar daca registrul CX este zero.
Pentru a utiliza corect aceste instructiuni conditionale,trebuie sa stiti
exact ce operatii afecteaza registrul FLAGS si cum.Daca nu stiti exact,
executati o operatie in care stiti exact ce rezultat obtineti asupra re-
gistrului FLAGS:
EXEMPLU: program assmb65;
uses WinCRT;
var nr1:word;
procedure Test;
begin
asm
mov AX,nr1
PUSH AX
POPF
JNO @@Adresa1
mov AX,1
@@Adresa1:
INC AX
ADD AX,5
mov nr1,AX
end;
end;
begin
writeln('introduceti o valoare oarecare(0-255): ');
read(nr1);
Test;
writeln('Valoarea corectata este: '.nr1);
end.
Pentru orice valoare care nu seteaza flagul OF,procedura va executa saltul
la adresa @@Adresa1,respectiv va corecta valoarea adaugand unu si apoi
inca cinci unitati.Pentru valorile negative si pentru orice alta valoare
care seteaza flagul OF nu se va executa saltul,iar ca rezultat AX va
fi unu si in urma corectiei se va returna 7 si un mesaj de eroare.
Pentru a avea certitudinea ca registrul FLAGS este modificat,am salvat
valoarea in stiva si apoi am transferat-o in registrul FLAGS.
-61-
Pentru situatiile in care dorim un salt conditionat,independent de regis-
trul FLAGS,cea mai simpla instructiune este JCXZ:
EXEMPLU: program assmb66;
uses WinCTR;
var nr1,nr2:word;
text:string;
procedure Test;
begin
asm
mov AX,nr1
mov CX,nr2
JCXZ @@Adresa1
SUB AX,77
@@Adresa1:
mov nr1,AX
end;
end;
begin
writeln('Introduceti o valoare (0-65535): ');
readln(nr1);
writeln('Scadeti o taxa fixa de 77 unitati ? da/nu :');
readln(text);
if text = 'da' then
nr2:=1
else
nr2:=0;
Test;
writeln('Valoarea recalculata este: ',nr1);
end.
In acest caz,conditia pentru salt este stabilita de valaoarea registrului
general CX.Daca CX este zero,se executa saltul iar in caz contrar saltul
nu are loc.Pentru a selecta una dintre cele doua variante,se seteaza
registrul CX la valaorea zero,sau la orice valoare pozitiva.
Pentru toate celelalte tipuri de conditii,se va evalua starea actuala
a registrului FLAGS.Pentru aceste cazuri,sunt posibile trei variante:
-prima varianta este sa utilizati o anumita valoare pentru setarea regis-
trului FLAGS in functie de reprezentarea binara(aceasta situatie a fost
deja exemplificata in exemplul assmb65).
-a doua varianta este sa utilizati modificarile registrului FLAGS generate
de instructiunile care modifica acest registru (AAA,AAD,AAM,AAS,ADC,ADD,
AND,CMP,CMPS,DAA,DAS,DEC,NEG,OR,POPF,RCL,RCR,ROL,ROR,SAR,SBB,SCAS,SHL,SHR,
SEB,TEST,XCHG sau XOR).Pentru a determina exact in ce mod vor fi modifi-
cate falg-urile in urma operatiilor efectuate de aceste instructiuni,con-
sultati cu atentie lista de instructiuni 8086 de la pagina 13-14.
-a treia varianta este sa evaluati valorile din registrii generali sau
din variabilele de memorie cu ajutorul unor functii care modifica regis-
trul FLAGS corespunsator cu situatia evaluata,dar nu modifica si nu alte-
reaza valorile analizate.Pentru acest scop se pot utiliza instructiunile
CMP sau TEST care analizeaza operanzii fara sa-i modifice.Aceasta varianta
este cea mai simpla si cel mai frecvent utilizata,deoarece nu poate induce
erori de programare sau de evaluare a valorilor.
-62-
EXEMPLU: program assmb67;
uses WinCRT;
var nr1,nr2:word;
procedure Test;
begin
asm
mov AX,nr1
mov BX,nr2
CMP AX,BX
JBE @@Adresa1
mov AX,0
@@Adresa1:
mov BX,0
mov nr1,AX
mov nr2,BX
end;
end;
begin
writeln('Introduceti primul numar: ');
readln(nr1);
writeln('Introduceti al doilea numar: ');
readln(nr2);
Test;
if nr1=nr2 then
writeln('Primul numar este mai mare decat al doilea !)
else
writeln('Primul numar este mai mic sau egal cu al doilea');
end.
In mod similar se poate utiliza oricare dintre instructiunile de salt
conditional.Compararea valorilor prin CMP sau TEST nu numai ca este mai
simplu de implementat,dar este si mult mai usor de verificat in cursul
etapei de depanare a unui program.Instructiunile si operatiile care
modifica definitiv operanzii,in acelasi timp cu modificarea registrului
FLAGS sunt ceva mai greu de depanat si implica o serie de operatii supli-
mentare de verificare secventiala a valorilor calculate.Atentie insa,
operatia de comparare nu evalueaza si valoarea zero.Daca ambii operanzi
au valoarea zero,rezultatul evaluarii poate fi incorect.
INT - este instructiunea de transfer a controlului catre sistemul de ope-
rare DOS.Este o instructiune clasica,la fel ca si CALL,si a facut
"cariera" in epoca de pionierat a limbajelor de programare.Reprezinta
si in prezent una dintre cele mai valoaroase modalitati de progra-
mare din assembler deoarece permite apelarea directa a functilor din
sistemul de operare DOS.Practic permite comunicarea dintre sistemul
Windows si sistemul DOS.Instructiunea permite apelul unui nivel de
intrerupere DOS,care trebuie sa aiba o valoare cuprinsa intre zero
si 255.Deoarece fiecare nivel de intrerupere are si un anumit numar
de subfunctii,apelul se face in doua etape.In prima etapa se va
introduce in registrul AH,valoarea subfunctiei iar apoi se va apela
prin INT nivelul de intrerupere corespunzator.Se obtin astfel cateva
sute de functii si subfunctii ale sistemului de operare DOS.
-63-
EXEMPLU: program assmb68;
uses WinCRT;
var nr1,nr2,nr3,nr4:word;
procedure Memorie;
begin
asm
mov AH,36
mov DL,2
int 21h
mov nr1,AX
mov nr2,BX
mov nr3,CX
mov nr4,DX
end;
end;
begin
Memorie;
writeln('Memoria libera de pe discul C este: ');
writeln(nr1,' sectoare/cluster ');
writeln(nr2,' clustere libere ');
writeln(nr3,' nr bytes/sector ');
writeln(nr4,' nr clustere/unitate ');
end.
Exercitiul de mai sus exploateaza intreruperea INT 21,36 adica intrerupe-
rea DOS 21 prin subfunctia sa cu numarul 36.Subfunctia se plaseaza in
AH iar in DL se specifica numarul unitatii (0 pentru A,1 pentru B etc.).
Pentru evaluarea dispozitivului mouse,se utilizeaza intreruperea INT 33.
EXEMPLU: program assmb69;
uses WinCRT;
var nr1,nr2,nr3,nr4:byte;
begin
asm
mov AH,5
mov BH,1
int 33h
mov nr1,AH
mov nr2,BH
mov nr3,CH
mov nr4,DH
end;
writeln('Dispozitivul mouse are urmatoarele valori: ');
writeln('Status= ',nr1);
writeln('Numar apasari butonul stang= ',nr2);
writeln('Pozitia Ox la ultima apasare=',nr3);
writeln('Pozitia Oy la ultima apasare=',nr4);
end.
In mod similar se pot apela cele 34 de subfunctii ale INT 33.
Daca intreruperea nu are subfunctii,se va apela direct nivelul de intre-
rupere dorit: EXEMPLU: int 11h
mov nr1,AX
va prelua in registrul AX echipamentul BIOS instalat.
-64-
Intreruperile DOS pot fi apelate cu ajutorul limbajului assembler si din
interiorul obiectelor Windows: EXEMPLU:
program assmb71;
uses WinTypes,WinProcs,OWindows,ODialogs,WinCRT,Strings;
type PTW = ^TW;
TW = object(TWindow)
CB1,CB2,CB3:PComboBox;BT1:PButton;PS1,PS2,PS3:PStatic;
constructor Init(AParent: PWindowsObject; ATitle: PChar);
procedure Buton(var Msg: TMessage);virtual id_First + 101;
end;
TDlgApp = object(TApplication)
procedure InitMainWindow;virtual;end;
constructor TW.Init(AParent: PWindowsObject; ATitle: PChar);
begin
inherited Init(AParent,ATitle);
PS1:=New(PStatic,Init(@Self,201,'ORA',200,180,50,20,0));
PS2:=New(PStatic,Init(@Self,202,'MIN',300,180,50,20,0));
PS3:=New(PStatic,Init(@Self,203,'SEC',400,180,50,20,0));
CB1:=New(PComboBox,Init(@Self,302,200,200,50,60,cbs_Simple,0));
CB2:=New(PComboBox,Init(@Self,303,300,200,50,60,cbs_Simple,0));
CB3:=New(PComboBox,Init(@Self,304,400,200,50,60,cbs_Simple,0));
BT1:=New(PButton,Init(@Self,101,'ORA EXACTA',30,200,120,20,True));
end;
procedure TW.Buton(var Msg:TMessage);
var t1,t2,t3:PChar;s1,s2,s3:string;nr1,nr2,nr3:byte;
begin
t1:=' ';t2:=' ';t3:=' ';
asm
mov AH,2Ch
int 21h
mov nr1,CH
mov nr2,CL
mov nr3,DH
end;
Str(nr1,s1);Str(nr2,s2);Str(nr3,s3);
CB1^.ClearList;CB2^.ClearList;CB3^.ClearList;
StrPCopy(t1,s1);CB1^.AddString(t1);
StrPCopy(t2,s2);CB2^.AddString(t2);
StrPCopy(t3,s3);CB3^.AddString(t3);
end;
procedure TDlgApp.InitMainWindow;
begin
MainWindow:= New(PTW,Init(nil,'Apasati butonul !'));
end;
var App: TDlgApp;
begin
App.Init('Arhivare');App.Run;App.Done;
end.
Acest exemplu ilustreaza modul in care sistemul Windows poate apela la
resursele sistemului DOS,pentru un obiect API Windows.Pentru a utiliza
corect instructiunea INT trebuie sa aveti un tabel cu intreruperile DOS.
-65-
LOOP a -este o instructiune de transfer conditinat a controlului la adresa
specificata prin a.Operatia este repetitiva si este determinata de
valoarea stocata in registrul contor CX.La fiecare executie,valoarea
din CX este decrementata cu o unitate,pana cand CX ajunge la valoa-
rea zero.Practic,bucla se va repeta de atatea ori,cat este valoarea
din CX in momentul apelarii.
EXEMPLU: program assmb72;
uses WinCRT;
var nr1,nr2,nr3:word;
begin
asm
MOV AX,1
MOV CX,35
MOV nr2,CX
@@Adresa1:
INC AX
LOOP @@Adresa1
MOV nr1,AX
MOV nr3,CX
end;
writeln('numarul rezultat este: ',nr1);
writeln('numarul de bucle executate: ',nr2);
writeln('valoarea finala a contorului este: ',nr3);
end.
LOOPNZ a -este o varianta a instructiunii LOOP.Se executa bucla atat timp
cat valoarea registrului CX este nonzero.
EXEMPLU: program assmb73;
uses WinCRT;
var nr1,nr2,nr3:word;
begin
asm
mov AX,17
mov BX,3
mov CX,15
mov nr3,CX
@@Adresa1:
INC BX
ADD BX,5
DEC AX
ADD AX,3
LOOPNZ @@Adresa1
mov nr1,AX
mov nr2,BX
end;
writeln('valorile initiale sunt: AX=17 si BX=3 ');
writeln('numarul de bucle este: ',nr3);
writeln('valoarea finala pentru AX este: ',nr1);
writeln('valoarea finala pentru BX este: '.nr2);
end.
LOOPZ a - este o versiune a LOOOP in care bucla este repetata atat timp
cat CX este zero.LOOPNE si LOOPE respecta conditia Not equal/Equal.
-66-
INTO - este o varianta de intrerupere DOS.Apeleaza INT 4 in caz ca flagul
OF este setat 1 (in caz de overflow).Ca rezultat,se intrerupe exe-
cutia programului si se afiseaza un mesaj de eroare.Este utila in
etapa de depanare a programelor(determina erorile de reprezentare).
INSTRUCTIUNI I/O (de intrare/iesire)
-se utilizeaza pentru transferul datelor intre procesoare,sau intre cal-
culatoare diferite.Datele vor fi eliberate in portul de comunicatie,sau
vor fi receptionate de la portul de comunicatie.Fiecare port de comuni-
catie are un tampon,cu o capacitate mai mica sau mai mare de stocare a
datelor transferate (in functie de tipul placii I/O ).
OUT p,s -transfera in portul de comunicatie specificat prin p datele
continute in sursa specificata prin s,care poate fi registrul AL,AX
sau EAX.Datele transferate pot fi de tip byte,word sau dword.Portul
de comunicatie poate fi specificat printr-o valoare cuprinsa intre
0 si 255 sau prin valoarea stocata in registrul DX(obisnuit,placile
I/O au 16-25 de porturi paralele).
EXEMPLU: program assmb74;
uses WinCRT;
var nr1:word;
begin
asm
mov AX,99
OUT 1,AX
mov nr1,AX
end;
writeln('Numarul transmis este: ',nr1);
end.
IN d,p -transfera datele din portul de comunicatie specificat prin p in
registrul de destinatie specificat prin d.Portul de comunicatie poate
fi specificat prin orice valoare cuprinsa intre 0 si 255 sau prin
valoarea stocata in registrul DX,iar registrul de destinatie poate fi
registrul AL,AX sau EAX.Datele trensferate pot fi de tip byte,word sau
respectiv dword.
EXEMPLU: program assmb75;
uses WinCRT;
var nr1:word;
begin
asm
IN AX,1
mov nr1,AX
end;
writeln('Valoarea receptionata este: ',nr1);
end.
Datele transmise sau receptionate sunt pastrate in portul de comunicatie
pana cand intervine operatia urmatoare.Astfel,daca executati succesiv
cele doua exemple anterioare,cel de al doilea exemplu va receptiona
valoarea plasata in portul de comunicatie de catre primul exemplu.
Protocoalele de comunicatie,lucreaza cu pachete intregi de date,care
sunt formate in tamponul portului si apoi sunt transferate in bloc.In
acest mod se pot transmite si comenzi simple cate efectori.
-67-
INSTRUCTIUNI PENTRU OPERATII ASUPRA SIRURILOR
-se utilizeaza pentru a efectua operatii asupra unui element dintr-un sir
de elemente.Elementele unui sir pot fi de tip byte,word sau dword.Astfel
sirurile pot contine numere sau litere,pentru a forma siruri numerice sau
text.Practic,instructiunile opereaza doar asupra adreselor de memorie ale
fiecarui element.Elementele sirului pot fi adresate cu ajutorul registri-
lor DI si SI.Dupa fiecare operatie efectuata,registrii SI si DI sunt
actualizati automat,astfel incat sa pointeze urmatorul element din sir.
Directia de deplasare in interiorul sirului este determinata de valoarea
flag-ului DF (Direction Flag) din registrul FLAGS.Daca DF este setat zero,
deplasarea va fi crescatoare,respectiv DI si SI vor fi incrementati.Daca
DF este setat 1,deplasarea va fi descrescatoare,respectiv DI si SI vor
fi decrementati.Incrementarea sau decrementarea se face in functie de
tipul de data.Pentru datele de tip byte,pointerul se deplaseaza cu o uni-
tate,pentru cele de tip word cu doua unitati,iar pentru cele de tip dword
cu patru unitati.Astfel,dimensiunea unui element,inmultita cu numarul de
elemente,trebuie sa fie egala cu dimensiunea sirului.Numarul total de
salturi posibile este egal cu numarul de elemente din sir.Pentru fiecare
instructiune de acest tip,se adauga sufixul "b","w" sau "d" pentru a
desemna tipul de data(dimensiunea saltului).Pentru datele reprezentate pe
32 de biti se vor utiliza registrii ESI si EDI(de la 80386 in sus).
Procesorul 8086 nu are suficienta memorie interna,pentru a opera cu
siruri intregi de date.Sirurile sunt preluate din memorie in tampoane
de memorie formate in memoria de RAM si sunt gestionate de catre sistemul
de operare.Assembler poate opera asupra acestor date,doar actionand asupra
adreselor de memorie.Cea mai simpla modalitate este cea prin care se uti-
lizeaza pointeri spre adresa de memorie a sirului.
LDS r,s - este instructiunea de incarcare a unui pointer in registrul DS
(Load Pointer to DS).Ca rezultat,valoarea pointerului specificat
prin sursa (s) va fi transferata in registrul general specificat
prin r si in registrul DS,dupa cum urmeaza: offset-ul adresei se
va transfera in registrul r iar segmentul adresei in registrul DS.
EXEMPLU: program assmb76;
uses WinCRT;
var text:string;
t1:^String;
adr,sg1:word;
pt1:PChar;
begin
text:='Textul care trebuie prelucrat !';
t1:=@text;
asm
LDS AX,t1
mov adr,AX
mov sg1,DX
end;
pt1:=ptr(sg1,adr);
writeln(pt1);
end.
In exercitiu,am transferat cu LDS,pointerul t1 in AX si DS.Apoi am preluat
offset-ul si segmentul si am format un alt pointer (Pt1).
-68-
LES r,s -este similara cu LDS,cu diferenta ca valoarea pointerului este
transferata in registrul specificat + registrul ES (Load pointer
to ES).Registrul "r" va contine offset-ul iar registrul ES va
contine segmentul de adresa al pointerului din sursa "s".
(vezi exemplul de mai sus.In mod similar,procesoarele cu registri
auxiliari (de la 386 in sus) accepta si instructiunile LFS,LGS si
LSS care sunt similare dar transfera segmentul adresei in registrul
ES,respectiv GS sau SS. (vezi exemplul de la LDS)
LEA r,s -este asemanatoare cu LDS,dar in loc sa transfere valoarea ope-
randului,transfera direct adresa afectiva a variabilei=Load effective
address to DX.Ca rezultat,nu mai este necesar un pointer spre variabila
dorita.Rezultatul operatiei consta in transferarea offset-ului adresei
de memorie in registrul specificat prin "r" si a segemntului adresei
in registrul DS.
EXEMPLU: program assmb77;
uses WinCRT;
var text:string;
adr,sg1:word;
pt1:PChar;
begin
text:='Textul care trebuie prelucrat !';
asm
LEA DX,text
mov adr,DX
mov sg1,DS
end;
pt1:=ptr(sg1,adr);
writeln(pt1);
end.
In exemplul de mai sus,adresa sirului "text" este transferata direct in
registrii DX si DS.Este mai simpla si mai directa decat LDS,dar nu se
poate utiliza decat pentru registrul DX.
Toate operatiile asupra adreselor actualizeaza si valoarea flag-urilor
din registrul FLAGS.Daca programati mai multe astfel de operatii succesiv,
este bine sa aveti o hartie cu patratele,pe care sa notati valoarea
binara a registrului FLAGS,in urma fiecarei operatii.Eventual,este bine
sa adaugati si un comentariu cat mai sugestiv,care sa simplifice ulterior
munca de depanare.Pentru fiecare operatie,este important mai ales cum
este setata valoarea flag-ului DF,care va determina directia de deplasare
in interiorul sirului.Operatiile trebuiesc verificate cu atentie,pentru
tot spectrul de valori admisibile,deoarece se preteaza extrem de usor la
confuzii de interpretare.Principalele instructiuni de acest gen sunt:
MOVS,CMPS,SCAS,STOS,LODS,INS si OUTS:
SCAS (SCASB,SCASW,SCASD) -compara valoarea de la adresa ES:DS cu cea din
registrul acumulator (AX) si seteaza flag-urile similar cu o scadere.
Actualizeaza falg-urile AF,SF,ZF,PF,CF si OF.Daca valorile sunt egale
flagul ZF este setat pozitiv (1),iar in caz contrar este eliberat
(este seatat 0).Registrul DI este incrementat sau decrementat in
functie de valoarea flagului DF si in functie de tipul de data utili-
zat (1=byte,2=word,4=dword).
-69-
EXEMPLU: program assmb78;
uses WinCRT,WinProcs;
var text1,text2:string;
t1,t2:^string;
rezultat:word;
d1,d2,c1,c2:word;
begin
text1:='Textul 1';
text2:='123456789';
t1:=@text1;
t2:=@text2;
asm
mov d1,DI
LDS AX,t1
LES AX,t2
mov c1,AX
mov c2,DI
SCASW
PUSHF
pop rezultat
mov d2,DI
end;
writeln('Rezultatul comparatiei este: ');
writeln(HIBYTE(rezultat),'-',LOBYTE(rezultat));
writeln('Valoarea DI initiala este: ',d1);
writeln('Valoarea DI finala este: ',d2);
writeln('Valorile comparate sunt: ',c1,' si ',c2);
end.
Cele doua valori comparate nu sunt egale,astfel incat flagul ZF este
setat zero.Valoarea finala a registrului FLAGS este 2-2,care in repre-
zentare binara este: 0000 0010 - 0000 0010 adica,singurul flag setat
pozitiv este falgul 9,adica IF(intreruperile sunt permise).Deoarece flagul
DF este setat zero,deplasarea se face cu incrementare si pentru ca fiecare
element din sir este de tip word,deplasarea se face cu doua unitati
(creste cu 2 bytes).
Daca se repeta operatia SCASW,valoarea din DI va fi incrementata cu
inca doua unitati,iar diferenta dintre valoarea initiala si cea finala
va fi de 4 bytes(doua elemente).Utilizand acest mecanism,se pot scrie
algoritmi care parcurg un sir de date,de la un capat la celalalt si
efectueaza diverse operatii de comparare.Puteti edita functii care
opereaza asupra sirurile de date asemanator cu functiile din uniatea
Strings din mediul Pascal.
CMPS (CMPSB,CMPSW,CMPSD) -efectueaza o operatie de comparare prin sca-
derea elementului sir de destinatie ES:DI din elementul sir sursa
adresat prin DS:SI.In urma operatiei de comparare sunt actualizate
flag-urile AF,SF,PF,CF si OF.Daca cele doua elemente sunt egale,ZF
este setat pozitiv(1),iar in caz contrar,ZF este setat zero.
Primul operand trebuie sa fie un element al unui sir,adresat prin
SI si orice adresa de segment,iar cel de al doilea operand trebuie
sa fie adresat prin DI.
-70-
EXEMPLU: program assmb79;
uses WinCRT,WinProcs;
var text:string;
t1:^string;
rezultat:word;
d1,d2,d3,d4:word;
pt1:PChar;
begin
text:='Textul care trebuie prelucrat !';
t1:=@text;
asm
mov d1,DI
LDS AX,t1
LES BX,t1
mov d3,AX
mov d4,BX
STD
CMPSW
PUSHF
pop rezultat
mov d2,DI
end;
writeln('Rezultatul comparatiei este: ');
writeln(HIBYTE(rezultat),'-',LOBYTE(rezultat));
writeln('valoarea initiala DI este: ',d1);
writeln('valoarea finala DI este: ',d2);
writeln('valorile comparate sunt: ',d3,' si ',d4);
end.
Rezultatul comparatiei este: 6-70 adica,in reprezentare binara,valoarea
registrului FLAGS este: 0000 0110 - 0100 0110
deci flag-urile 2 (PF-parity flag) 6 (ZF-zero flag) si 9 (IF-interupt
flag) sunt setate pozitiv(in ambii registrii am incarcat offset-ul de
la acelasi pointer spre sirul text).
In acest caz,flagul DF este setat pozitiv in urma instructiunii STD si
ca rezultat,deplasarea se face descrescator,iar registrul DI este
decrementat cu doua unitati (elementele sunt de tip word).
STOS (STOSB,STOSW,STOSD) -salveaza AX in memorie la adresa DI.Practic
instructiunea salveaza valoarea din registrul acumulator la adresa ES:DI.
DI este incrementat sau decrementat in functie da valoarea flagului
DF (direction flag) si in functie de dimensiunea operandului (tipul de
data transferat).Daca DF este zero,DI este incrementat iar daca DF este
1,DI este decrementat.Pentru adrese de tip Word,incrementarea si/sau
decrementarea se face din 2 in 2 (cate 2 bytes).Functia poate fi repetata
succesiv cu ajutorul instructiunii REP (in functie de valoarea registru-
lui counter CX).Pentru a recupera sirul initial,se va tine cont de
deplasarea pointerului in cursul operatiei efectuate.Astfel,daca a fost
citit(si comparat) intregul sir,pentru a putea recupera adresa initiala
va trebui scazuta din adresa finala,dimensiunea sirului (dimensiunea
cu care a fost deplasat pointerul de sir (respeciv registrul de indexare
SI). (vezi exercitiul)
-71-
EXEMPLU: assmb80;
uses WinCRT,WinProcs;
var text:string;
t1:^string;
d1,d2,d3,d4,rezultat:word;
pt1:pChar;
begin
text:='Sirul de caractere procesat !';
t1:=@text;
asm
mov d1,DI
LDS AX,t1
STOSB
mov d2,DI
mov d3,ES
mov d4,DI
sub d4,SI
pushf
pop rezultat;
end;
writeln('valoarea initiala a registrului DI este: ',d1);
writeln('Valoarea din AX a fost stocata in DI');
writeln('valoarea finala a registrului DI este: ',d2);
writeln('Registrul FLAGS are valoarea: ');
writeln(HIBYTE(rezultat),'-',LOBYTE(rezultat));
writeln('Sirul potae fi recuperat din ES:DI ');
pt1:=ptr(d3,d4);
writeln(pt1);
end.
Observati ca in cazul instructiunii STOSB,tipul de data este BYTE iar
DI este incrementat cu 1.Daca se utilizeaza instructiunea STOSW,tipul
de data este WORD iar DI va fi incrementat cu 2.Pointerul de indexare
SI este egal cu dimensiunea sirului.Pentru a selecta adresa de inceput
al sirului,derbuie ca din valoarea offset-ului sa fie scazuta dimensiunea
sirului (valoarea SI).In caz contrar,pointerul va fi orientat spre byte-ul
imediat urmator ultimului caracter diun sir.
MOVS -(MOVSB,MOVSW,MOVSD) -transfera memoria din SI in DI.
Practic instructiunea copiaza datele de la adresa DS:SI la locatia
ES:DI si actualizeaza valoarea registrilor SI si DI.Asftel,daca
flagul DF este setat zero,DI si SI vor fi incrementati iar daca
flagul DF este setat 1,cei doi registri vor fi decrementati.Valoarea
cu care se efectueaza incrementarea sau decrementarea este determina-
ta de tipul de data ( 1 pentru byte,2 pentru word si 4 pentru dword).
Instructiunea poate fi repetata cu ajutorul instructiunii REP.
Datele transferate pot fi recuperate de la adresa de destinatie
(ES:DI) cu conditia sa se deplaseze pointerul cu o valoarea egala
cu dimensiunea sirului (practic se scade valoarea registrului de
indexare SI care este egal cu dimensiunea sirului).Pentru toate
operatiile care utilizeaza stiva se aplica principiul LIFO (LAST
IN FIRST OUT).
-72-
EXEMPLU: program assmb81;
uses WinCRT,WinProcs;
var text:string;
t1:^string;
d1,d2,d3,d4,rezultat:word;
pt1:PChar;
begin
text:='Text oarecare';
t1:=@text;
asm
mov d1,SI
mov d2,DI
LDS AX,t1
STD
MOVSW
mov d3,ES
mov d4,DI
SUB d4,SI
end;
writeln('SI initial = ',d1);
writeln('DI initial = ',d2);
writeln('ES = ',d3);
writeln('DI final= ',d4);
writeln('Sirul poate fi recuperat din ES:DI ');
pt1:=ptr(d3,d4);
writeln(pt1);
end;
REP/REPNE/REPNZ/REPE/REPZ -sunt instructiuni de repetare a unei operatii
asupra sirurilor.Se utilizeaza sub forma de prefix al instructiunii care
urmeaza sa fie repetata (Exemplu: REP MOVSW).Atunci cand o instructiune
are un prefix de repetitie,operatia respectiva va fi repetata dar la
fiecare repetitie se va utiliza elementul urmator din sir.Repetitia se
termina in momentul in care este satisfacuta conditia specificata prin
prefix.Toate prefixele utilizeaza registrul counter (CX),care este
decrementat dupa fiecare operatie efectuata,pana cand ajunga la valoarea
zero.REP este dependenta exclusiv de valoarea registrului CX.REPE,REPZ si
respectiv REPNE si REPNZ sunt dependente si de valoarea flagului ZF (zero
flag).REPE si REPZ termina executia daca flagul ZF este zero,iar REPNE
si REPNZ termina executia daca flagul ZF este non zero (adica este 1).
Aceste instructiuni se utilizeaza impreuna cu celelalte instructiuni
de manipulare a sirurilor (scas,cmps,movs,stos etc.) pentru a forma
bucle de repetitie in care este evaluat fiecare element din sir.In functie
de directia de deplasare determinata de flagul DF si in functie da valoa-
rea flagului ZF,se pot forma diferiti algoritmi de parcurgere si comparare
a fiecarui element din sir.Se poate compara fiecare element cu un sablon
fix sau se poate compara fiecare element din sir cu fiecare element din
alt sir.Acest gen de rutine sunt ceva mai greu de implementat dar sunt
extrem de rapide si pot completa functiile de manipulare a sirurilor
existente in Pascal (Exemplu: elementele din sir pot fi comparate dupa
un model fix oarecare: din 2 in 2,sau in grupuri de cate trei etc.).
-73-
EXEMPLU: program assmb82;
uses WinCRT,WinProcs;
var text: string;t1:^string;
d1,d2:word;pt1:PChar;
begin
text:='Text oatecare';
t1:=@text;
asm
LDS AX,t1
SDT
MOV CX,7
REP MOVSW
mov d1,ES
mov d2,DI
end;
writeln('Sirul care poate fi recuperat din ES:DI este:');
pt1:=ptr(d1,d2);
writeln(pt1);
end.
Operatia a fost repetata de 7 ori,deci DI a fost decrementat cu 14.
LODS (LODSB,LODSW,LODSD) incarca memoria din SI in AX.Practic instruc-
tiunea transfera sirul adresat prin DS:SI in registrul acumulator.
SI este incrementat sau decrementat in functie de flagul DF.Se poate
utiliza impreuna cu REP.
EXEMPLU: assmb83;
uses WinCRT,WinProcs;
var text:string; t1:^string;
d1,d2,d3,d4,d5:word;
pt1:PChar;
begin
text:='Textul analizat';
d1:=Seg(text);
d2:=Ofs(text);
asm
mov DS,d1
mov SI,d2
mov CX,2
REP LODSW
mov d3,SI
mov d4,ES
mov d5,AX
end;
writeln('Sirul poate fi recuperat din ES:SI ');
pt1:=ptr(d4,d3);
writeln(pt1);
writeln('pointerul de sir a avansat cu 4 pozitii');
writeln('registrul AX primeste valoarea:',d5);
end.
Instructiunile pentru manipularea sirurilor de date,sunt utile pentru a
realiza functii noi,diferite de cele standard din unitatea Strings).
-74-
PROCESORUL 8087 SI SETUL DE INSTRUCTIUNI 8087
In paginile precedente,au fost exemplificate sumar instructiunile
procesorului 8086.Arhitectura extrem de simpla a acestui chip,nu permite
decat prelucrarea datelor cu un format relativ restrans.Din acest motiv,
pentru efectuarea de calcule matematice stiintifice,a fost proiectat si
realizat un procesor dedicat acestui scop,denumit procesor numeric,sau
coprocesor matematic.In versiunea Intel,acest procesor a fost denumit
8087.Initial,procesorul 8087 era un chip independent,cu un slot de
montare independent de 8086,dar incepand cu seria de procesoare 80486,
a fost incorporat impreuna cu 80486 in CPU.
Procesorul 8087 a fost conceput special pentru a putea efectua opera-
tii cu numerele in virgula mobila (floating point).Numerele in virgula
mobila sunt echivalentul software al notatiei matematice cunoscuta sub
numele de notatie stiintifica.Initial au existat un numar destul de mare
de implementari hardware,dar,in timp,s-a precizat un format unic concre-
tizat prin standardul IEEE 754-1985 si mai apoi IEC 60559-1989 (IEEE
Standard for Binary Floating-Point Arithmetic for microprocesor systems).
Conform acestui standard,reprezentarea binara a unui numar in virgula
mobila se face pe 80 de biti,astfel:
bitul de semn exponent mantisa
| | |
0 00000000 00000000000000000000000000000000000000000....
unde bitul 80 este bitul de semn (bitul cel mai semnificativ)
Ca rezultat,toate instructiunile procesorului 8087 au o denumire
mnomotehnica in care prima litera este F (de la floating-point numbers),
iar registrii procesorului 8087 sunt dezvoltati pe cate 80 de biti,adica
8 bytes.
Procesorul 8087 este format din 8 registri pentru numere,denumiti ST,
de la ST(0) la ST(7) si un registru pentru controlul informatiei,un regis-
tru de status,un registru TAG si cate un registru pentru pointerul de data
si pointerul de instructiune.
Registrii pentru numere sunt organizati sub forma de stiva,si functio-
neaza la fel ca o stiva.Astfel,primul registru este denumit ST sau ST(0),
urmatorul registru din stiva este ST(1) etc.Spre deosebire de registrii
generali ai procesorului 8086,registrii ST nu au o pozitie fixa.Astfel,
dupa in registrul ST au fost introduse date noi,datele anterioare avan-
seaza in stiva si vor putea fi referite ulterior prin ST(1).Altfel spus,
dupa o operatie PUSH,datele din ST(0) vor fi referite prin ST(1).Acest
mecanism (LIFO ),este specific pentru operatiile cu stive de date si
trebuie respectat atunci cand se programeaza operatii succesive.
Registrul de control,determina modul de solutionare al unor situatii
critice,cum ar fi: modul de rotunjire al numerelor nereprezentabile,
modul de rezolvare pentru calculele incorecte,controlul preciziei de
calcul,etc.Pentru procesoarele de tip Intel,registrul de control contine
16 biti.Pentru trunchiere si rotunjire se utilizeaza perechea de biti
10 si 11,iar pentru determinarea preciziei se utilizeaza perechea de biti
8 si 9.Bitul 1 mascheaza o intrerupere denormalizata,bitul 2 mascheaza o
impartire prin zero,bitul 3 mascheaza o exceptie overflow(>decat domeniul)
-75-
bitul 4 mascheaza o exceptie underflow(< decat domeniul de reprezentare),
iar bitul 5 controleaza daca poate interveni o exceptie de precizie.
Bitii 6 si 13-15 sunt rezervati pentru implementari ulterioare.
Pentru controlul trunchierii/rotunjirii se utilizeaza urmatoarele setari:
bitii 10 si 11 TIPUL DE SOLUTIONARE
0 0 -rotunjire spre valoarea cea mai apropiata
0 1 -rotunjire in jos
1 0 -rotunjire in sus
1 1 -trunchiere
Pentru controlul preciziei de reprezentare,se utilizeaza setari:
bitii 8 si 9 VALOAREA PRECIZIEI
0 0 -24 de biti
0 1 -rezervat
1 0 -53 de biti
1 1 -64 de biti
Registrul pentru status este format tot din 16 biti.Primii 5 biti sunt
flaguri pentru exceptii.Bitul 6 indica supraincarcarea stivei.Bitul 7
este setat atunci cand intervine una dintre exceptiile controlate de
flagurile 0-5 (atesta existenta unei exceptii),iar bitii 8-14 contin
flagurile pentru conditiile procesorului si se mai numesc si biti pentru
coduri conditionale (Condition Code Bits C3 C2 C1 si C0 ).
INSTRUCTIUNE C3 C2 C1 C0 CONDITIE
fcom,fcomp, 0 0 x 0 ST > sursa
fcompp,ficom 0 0 x 1 ST < sursa
si ficomp 1 0 x 0 ST = sursa
__________________ 1 1 x 1 ST sau sursa nedefinita
0 0 x 0 ST este pozitiv
ftst 0 0 x 1 ST este negativ
1 0 x 0 ST este zero
_________________ 1 1 x 1 ST nu poate fi comparat
0 0 0 0 + Nenormalizat
0 0 1 0 - Nenormalizat
0 1 0 0 + Normalizat
0 1 1 0 - Normalizat
fxam 1 0 0 0 + 0
1 0 1 0 - 0
1 1 0 0 + Denormalizat
1 1 1 0 - Denormalizat
0 0 0 1 + NaN
0 0 1 1 - NaN
0 1 0 1 + Infinit
0 1 1 1 - Infinit
1 x x 1 Registru gol
____________________
fucom,fucomp si 0 0 x 0 ST > sursa
fucompp 0 0 x 1 ST < sursa
1 0 x 0 ST = sursa
1 1 x 1 unorder (neordonat)
(x poate lua orice valoare 0 sau 1)
-76-
Dupa cum se poate observa,registrul de status este asemantor cu registrul
FLAGS 8086.
Registrul TAG,contine grupuri de biti care determina statusul unei
valori in fiecare dintre cei 8 registri pentru numere.
Registrii pentru pointerul de data si respectiv pointerul de instruc-
tiune contin informatii despre ultima instructiune executata.
Operatiile cu numere in virgula mobila prezinta o serie intreaga de
Dostları ilə paylaş: |
|
|