Limbajul Assembler abc-doar



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

mov ax,33

stc

sbb ax,32

mov nr1,ax

end;

writeln('rezultatul este: ',nr1);

end.

Comparati rezultatul cu cel obtinut in exercitiul precedent.

Instructiunea se utilizeaza mai ales in bucle care contin o secventa de

genul : stc

sbb ax,0

sbb ax,0 ...etc.

In functie de numarul de instructiuni sbb,daca flagul CF este 1,se va

obtine un rezultat diferit.Astfel,se pot genera rezultate diferite,in

functie de valoarea flagului CF.Se utilizeaza la depanare si setari.


-46-

DEC d - decrementeaza destinatia d cu o unitate.Este inversa instructiunii

INC.Nu afecteaza flagul CF.Se utilizeaza pentru a scadea o unitate

dintr-o valoare sau dintr-un registru.Cel mai frecvent se utilizeaza

pentru functii si bucle de repetitie,pentru a asigura repetarea sec-

ventiala a unei operatii:

EXEMPLU: program assmb42;

uses WinCRT;

var nr1,nr2:word;

function D2(nr1:word):word;assembler;

asm

mov ax,nr1

dec ax

end;

begin

for nr1:=2 to 15 do

begin

nr2:=D2(nr1);

writeln('nr1= ',nr1,' nr2= ',nr2);

end;

end.

CMP d,s -compara sursa cu destinatia prin efectuarea unei operatii de

scadere a sursei din destinatie,dar fara sa modifice valoarea

celor doi operanzi (sursa si destinatia raman cu valorile ini-

tiale).Dupa comparare,actualizeaza registrul FLAGS in functie de

rezultatul obtinut (semn,paritate etc.).Pentru valorificarea

rezultatului trebuie preluat registrul FLAGS si interpretate

noile setari:

EXEMPLU: program assmb43;

uses WinCRT,WinProcs;

var nr1:word;

begin

asm

mov ax,55

mov bx,55

cmp ax,bx

pushf

pop nr1

end;

writeln('numarul rezultat este: ',LOBYTE(nr1));

end.

In exemplul de mai sus,puteti alterna valorile celor doi operanzi.In

cazul in care rezultatul comparatiei va fi negativ (sursa are valoare

mai mare decat destinatia),byte-ul inferior din registrul FLAGS va returna

o valoare mai mare decat 131 (deoarece bitul de semn va fi setat 1).Daca

cele doua valori sunt egale,byte-ul inferior din FLAGS va fi 70,iar daca

sursa va fi mai mica decat destinatia,byte-ul inferior va avea o valoare

mai mica decat 70 (2 sau 6 etc.).Revedeti reprezentarea binara a numerelor

zecimale,pentru a descifra semnificatia registrului FLAGS,biti cu bit.

Pentru a utiliza propriu zis instructiunea de comparare,se poate edita

un program sau o functie care evalueaza valoarea registrului FLAGS in

urma executiei unei instructiuni cmp:


-47-

EXEMPLU: program assmb44;

uses WinCRT,WinProcs;

var x1,y1,z1,r:word;

function Compara(x1,y1:word):word;assembler;

asm

mov ax,x1

mov bx,y1

cmp ax,bx

pushf

pop z1

end;

begin

x1:=9;

for y1:=1 to 15 do

begin

r:=Compara(x1,y1);

if LOBYTE(z1)=70 then

writeln(' numerele sunt egale cu : ',x1)

else

writeln('numerele nu sunt egale !');

end;

end.

In mod similar se pot selecta situatiile in care sursa este mai mare,sau

sursa este mai mica decat destinatia( LOBYTE(z1) > 70 sau <70 ).

NEG d - scade din zero un intreg.Rezultatul acestei operatii este schim-

barea bitului de semn din registrul FLAGS.Implicit operandul speci-

ficat ca destinatie isi schimba semnul (din pozitiv devine negativ

iar din negativ devine pozitiv cu valoarea complementara "in oglinda")

EXEMPLU: program assmb45;

uses WinCRT;

var nr1,nr2:word;

begin

asm

mov ax,-77

neg ax

mov nr1,ax

mov bx,3

neg bx

mov nr2,bx

end;

writeln('numarul nr1 este: ',nr1);

writeln('numarul nr2 este: ',nr2);

end.

Observati ca pentru 3 se returneaza 65533,adica complementul fata de

valoarea maxima de 65535.Doua instructiuni NEG succesive se anuleaza

reciproc.

Toate instructiunile aritmetice binare de mai sus,actualizeaza valoarea

bitilor de stare din byte-ul inferior al registrului FLAGS(adica SF,ZF,PF

si OF.Unele dintre ele actualizeaza si flag-ul CF.Valorile actuale ale

fiecarui bit de stare se utilizeaza pentru programarea unor rutine auto-

mate de verificare si depanare a programelor de calcul.


-48-

MUL s -efectueaza multiplicarea valorii din registrul AX cu cea din

sursa (s).Daca operandul este un byte,atunci se va multiplica prim

s valoarea continuta in registrul AL iar rezultatul se va salva

in registrii AH si AL.Daca operandul este un word,atunci se va

multiplica prin s valoarea din registrul AX iar rezultatul se va

salva in registrii AX si DX.Pentru operandul de un byte,rezultatul

returnat va fi de 1 word (pe 16 biti) iar daca operandul este de

tip word,rezultatul returnat va fi de tip dword(32 de biti).

MUL reseteaza registrul FLAGS la fel ca si INC.

Valoarea din s trebuie sa fie din tipul unsigned (pozitiva).

EXEMPLU: program assmb46;

uses WinCRT;

var nr1,nr2:byte;

rez1:word;

begin

asm

mov ax,13

mov bx,7

mul bx

mov nr1,ah

mov nr2,al

mov rez1,ax

end;

writeln('numarul nr1 rezultat este(AH): ',nr1);

writeln('numarul nr2 rezultat este(AL): ',nr2);

writeln('rez1 este(AX): ',rez1);

end.

Daca valoarea din AX este negativa,rezultatul va fi complementul fata de

65535 al rezultatului.Pentru a obtine rezultatul corect se poate utiliza

instructiunea NEG:

EXEMPLU: program assmb47;

uses WinCRT;

var nr1,nr2:word;

begin

asm

mov ax,-15

mov bx,77

mul bx

neg ax

mov nr1,ax

mov nr2,dx

end;

writeln(' nr1 este (AX): ',nr1);

writeln(' nr2 este (DX): ',nr2);

end.

Instructiunea MUL nu este performanta in cazul numerelor mari.Se poate

utiliza cu succes mai ales pentru programarea unor bucle de repetitie

cu numere mici,sau pentru calculul unor adrese (Offset-ul nu poate fi

mai mare decat valorile reprezentabile ale rezultatului).

Pentru procesoarele din generatiile actuale,MUL accepta si operand de

32 de biti si returneaza rezultatul pe 64 de biti(accepta valori f.mari).


-49-

IMUL s -este identica cu MUL,dar accepta ca opernad(sursa s),un mumar de

tip signed (cu semn)(Exemplu: imul s ...unde s este -7 ).
DIV s -este instructiunea prin care valoarea din registrul acumulator(AX)

este impartita prin valoarea din sursa (s).In ecuatie,deimpartitul

stocat in AX trebuie sa fie cu tip dublu fata de divizorul specificat

iar rezultatul si restul var fi din acelasi tip cu divizorul.Astfel,

daca divizorul este de tip byte,deimpartitul va fi de tip word si va

fi preluat din AX.Rezultatul este returnat in AL,iar restul in AH:

EXEMPLU: program assmb48;

uses WinCRT;

var nr1:byte;

rez,rest:byte;

begin

asm

mov ax,19

mov nr1,3

div nr1

mov rez,AL

mov rest,AH

end;

writeln('19 impartit la 3 rezulta: ');

writeln(rez,' rest ',rest);

end.

Daca divizorul este de tip word,deimpartitul va fi de tip dword si va

fi preluat din registrii AX si DX,respectiv word-ul superior va fi

preluat din DX iar cel inferior va fi preluat din AX.Rezultatul va fi

returnat in AX iar restul va fi returnat in DX.

EXEMPLU: program assmb49;

uses WinCRT;

var nr1:word;

rez,rest:word;

begin

asm

mov AX,29

mov DX,0

mov nr1,5

div nr1

mov rez,AX

mov rest,DX

end;

writeln('rezultatul impartirii este: ');

writeln('rez,' rest ',rest);

end.

Asadar,impartirea se face cu rest,iar rezultatul si restul suprascriu

valoarea initiala.In caz ca doriti sa repetati operatia puteti salva

valorile initiale cu PUSH inainte de a efectua impartirea.

IDIV s - este identica cu DIV,dar accepta pentru divizor (valoarea din

sursa s) o valoare de tip signed (cu semn).In rest toate regulile sunt

identice cu cele de la instructiunea DIV(deimpartitul este preluat din

AX daca divizorul este de tip byte,sau din DX si AX daca este tip word)


-50-

INSTRUCTIUNI ARITMETICE DECIMALE

-sunt instructiuni care se utilizeaza in combinatie cu instructiunile

aritmetice binare (cele prezentate mai sus).Se utilizeaza pentru a

ajusta rezultatul unei operatii binare la un numar de tip unpacked deci-

mal,sau packed decimal sau pentru a modifica operanzii unei operatii

aritmetice binare astfel incat se fie de tip packed sau unpacked decimal.

Cu alte cuvinte,numerele zecimale sunt scrise in format hexazecimal,

din care se exclud numerele care incep cu o litera.Astfel,de exemplu,

numarul 10 decimal,transformat in hexazecimal,in loc sa fie 0A va fi tot

10.Diferenta este ca numarul 10 decimal,in reprezentare binara este:

0000 1010 iar numarul 10 hexazecimal in reprezentare binara este:

0001 0000.Instructiunile AAA si AAS,dupa ce au realizat ajustarea ASCII,

inlocuiesc prin zerouri primii patru biti din bytes.Astfel,in cazul

exemplului de mai sus,10 decimal devine 10 unpacked,adica 10 hexazecimal,

adica 0001 0000,care,dupa inlocuirea primilor patru biti devine 0000 0000

adica 0.

Dupa inlocuirea primilor patru biti cu zerouri,valorile posibile vor

fi cuprinse intre 0000 0000 si 0000 1111 adica intre 0 si 15.
AAA - este operatia de ajustare dupa adunare in AX (ASCII Adjust for Add

in AX).Modifica valoarea din registrul AL astfel incat sa fie de tip

unpacked decimal,dupa care inlocuieste prin zero primii patru biti.

Instructiunea AAA se poate apela doar dupa o operatie de adunare a

doi operanzi de tip unpacked decimals in AL.Daca este cazul,este

setat si flagul CF,iar AH este incrementat daca "carry" este necesar.

EXEMPLU: program assmb50;

uses WinCRT;

var nr1,nr2,nr3:byte;

begin

asm

mov AL,1+9

AAA

mov nr1,AL

mov AL,1+10

AAA

mov nr2,AL

mov AL,1+24

AAA

mov nr3,AL

end;

writeln('nr1 este: ',nr1);

writeln('nr2 este: ',nr2);

writeln('nr3 este: ',nr3);

end.

In exemplul de mai sus,1+9 rezulta 10 (vezi mai sus).1+10 rezulta 11,care

scris unpacked devine 11 hexazecimal,adica 0001 0001.Dupa inlocuirea prin

zero a primilor patru biti,devine 0000 0001,adica 1.1+24 rezulta 25,care

scris hexazecimal este 1F,adica 0001 1111.Dupa inlocuirea primilor patru

biti prin zerouri,numarul devine 0000 1111,adica 15.

Cu ajutorul acestei instructiuni,orice numar de tip byte va fi transformat

intr-o valoare cuprinsa intre 0 si 15 (respectiv 0000 0000 la 0000 1111).


-51-

Pentru a clarifica orice nelamurire,sau pentru a programa aceste instruc-

tiuni,trebuie sa aveti un tabel de conversie a numerelor decimale in

hexazecimale si in numare binare (perferabil tabelul complet care include

si numerele octale,respectiv ASCII).

Acest gen de operatii,sunt utile atunci cand se doreste selectia unei

anumite optiuni dintre maxim 16 posibile.De exemplu,daca doriti sa se-

lectati automat o linie de adresa a unui procesor cu 16 linii de adresa,

se va utiliza instructiunea AAA,pentru a selecta una dintre liniile de

date in functie de valoarea din registrul AL.

AAS -este operatia de ajustare dupa scadere (ASCII Adjust for substract

in AX).Este similara cu AAA,dar poate fi apelata doar dupa ce s-a

efectuat in AL o operatie de scadere cu doi operanzi unpacked decimali

Instructiunea schimba valoarea din AL la o valoare unpacked (despache-

tata) si apoi inlocuieste prin zero primii patru biti.

EXEMPLU: program assmb51;

uses WinCRT;

var nr1:byte;

begin

asm

mov AL,29-13

AAS

mov nr1,AL

end;

writeln('numarul rezultat este: ',nr1);

end.

In exemplul de mai sus,29-13 rezulta 16 in AL.Ajustat la o valoare de tip

unpacked,16 devine 10 hexazecimal adica 0001 0000.Dupa inlocuirea celor

patru biti prin zerouri,numarul devine 0000 0000,adica 0.

AAM -este operatia de ajustare dupa inmultire(ASCII Adjust for Multiply

in AX).Este operatia prin care rezultatul unei inmultiri va fi adjustat

la doua numere unpacked distincte,returnate in registrii AH si AL.In

registrul AH se va returna digitul cu ordinul superior,iar in registrul

AL se va returna digitul cu ordinul inferior.

EXEMPLU: program assmb52;

uses WinCRT;

var nr1:byte;

r1,r2:byte;

begin

asm

mov AX,255

mov nr1,1

mul nr1

AAM

mov r1,AL

mov r2,AH

end;

writeln('registrul AL este: ',r1);

writeln('registrul AH este: ',r2);

end.

Pentru a intelege operatia,repetati exercitiul cu numarul 256,apoi 257,

apoi executati diferite inmultiri si observati cei doi digiti.


-52-

AAD - este oparatia de ajustare pentru impartire (ASCII adjust for

divide in AX) care modifica valorile din AH si AL astfel incat

rezultatul impartirii dintre doua numere zecimale sa fie tot un

numar zecimal.AH va contine digitul superior iar AL va contine

digitul inferior.Instructiunea efectueaza ajustarea la un numar

decimal despachetat si plaseaza rezultatul in AL in timp ce AH va

contine valoarea zero.Regulile sunt la fel ca pentru AAM.

EXEMPLU: program assmb53;

uses WinCRT;

var nr1:byte;

rez1,rest1:byte;

rez2,rest2:byte;

rez3,rest3:byte;

begin

asm

mov AX,34

mov nr1,5

div nr1

mov rez1,AL

mov rest1,AH

AAD

mov rez2,AL

mov rest2,AH

div nr1

mov rez3,AL

mov rest3,AH

end;

writeln('rez1= ',rez1,' rest1= ',rest1);

writeln('rez2= ',rez2,' rest2= ',rest2);

writeln('rez3= ',rez3,' rest3= ',rest3);

end.

Pentru a intelege mai bine operatia efectuata,executati exercitiul cu o

serie de numere consecutive in AX (33,34,35,36,37...etc).Observati cum

valoarea din AH este transferata in AL in urma operatiei AAD.

DAA -este operatia de ajustare decimala pentru adunare (Decimal Adjust for

Add in AX).Daca este cazul,seteaza si flagul CF.Nu are operanzi.

EXEMPLU: program assmb54;

uses WinCRT;

var nr1,nr2:byte;

begin

asm

mov AL,0+0

DAA

mov nr1,AL

mov AL,1+1

DAA

mov nr2,AL

end;

writeln('nr1 este: ',nr1);

writeln('nr2 este: ',nr2);

end.


-53-

Instructiunea trebuie sa urmeze dupa o operatie de adunare in AL.Ajustarea

consta practic in adunarea numarului 96 la valoarea din AL.Pentru a

intelege mai bine operatia,consultati tabelul ASCII.Valoarea 96 decimala

corespunde cu litera "a" ASCII.Instructiunea este foarte untila mai ales

pentru operatii asupra codurilor numerice ale caracterelor ASCII.

EXEMPLU: program assmb54b;

uses WinCRT;

var x,y:byte;

function Scrie(y:byte):word;assembler;

asm

mov AL,x+0

DAA

mov y,AL

end;

begin

for x:=96 to 119 do

begin

y:=Scrie(x);

write(CHR(y));

end;

end.

DAS - este operatia de ajustare decimala pentru scadere (Decimal Adjust

for Substract in AX).Trebuie sa urmeze dupa o operatie de scadere

in AL.Daca este necesar,se seteaza si flagul CF.

EXEMPLU: program assmb55;

uses WinCRT;

var nr1,nr2:byte;

begin

asm

mov AL,198-1

DAS

mov nr1,AL

mov AL,199-3

DAS

mov nr2,AL

end;

writeln('caracterul cu numarul: ',nr1,' este: ',CHR(nr1));

writeln('caracterul cu numarul: ',nr2,' este: ',CHR(nr2));

end.

Practic,ajustarea consta din scadrea valorii 96 din valoarea stocata in

AL.Astfel,instructiunea se poate utiliza pentru operatii cu caractere,sau

pentru a afla numerul de ordine al unui carcater,etc.Atentie insa la

faptul ca numerele despachetate exclud valorile hexazecimale 0A,0B,0C,0D,

0E si 0F.Astfel in loc de 256 de valori rezulta doar 250.Functiile liniare

in care se utilizeaza doar valoarea 96 vor returna valori eronate atunci

cand operatia se face "cu imprumut (with borrow) ",adica atunci cand se

depaseste valoarea domeniul de reprezentare pentru un byte (0-256).

Efectuati cateva exercitii cu serii de numere consecutive si evaluati

rezultatul.Atunci cand programati functii automate,cu aceste instructiuni,

verificati cu atentie fiecare valoare posibila,inainte de a utiliza

functia respectiva.


-54-

INSTRUCTIUNI LOGICE

-sunt asemanatoare cu operatiile logice,dar spre deosebire de operatiile

simple in care operanzii trebuie sa fie obligatoriu valori imediate,in

instructiunile logice se pot utiliza ca operanzi atat registrii cat si

variabilele de memorie.

NOT d -este operatia de negare a operandului de destinatie (d).Negarea se

face prin returnarea valorii complementare ("in oglinda").Nu are

nici un efect asupra registrului FLAGS.Valoarea rezultata inlocuieste

valoarea preexistenta.

EXEMPLU: program assmb56;

uses WinCRT;

var nr1:word;

nr2:byte;

begin

asm

mov nr1,15

NOT nr1

mov AL,15

NOT AL

mov nr2,AL

end;

writeln('Complementul "WORD" al lui 15 este: ',nr1);

writeln('Complementul "BYTE" al lui 15 este: ',nr2);

end.
AND d,s

OR d,s

XOR d,s - sunt similare cu operatiile logice cu acelasi nume,dar accepta

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