Scrigroup - Documente si articole

Username / Parola inexistente      

Home Documente Upload Resurse Alte limbi doc  
AccessAdobe photoshopAlgoritmiAutocadBaze de dateC
C sharpCalculatoareCorel drawDot netExcelFox pro
FrontpageHardwareHtmlInternetJavaLinux
MatlabMs dosPascalPhpPower pointRetele calculatoare
SqlTutorialsWebdesignWindowsWordXml

Instructiuni de transfer

calculatoare



+ Font mai mare | - Font mai mic



Instructiuni de transfer

Instructiunile de transfer presupun o copiere a unui octet sau a unui cuvant de la o sursa la o destinatie. Aceasta copiere (atribuire) va fi desemnata uneori printr-o sageata, de la sursa catre destinatie. Destinatia poate fi un registru, o locatie de memorie sau un port de iesire, iar sursa poate fi un registru, o locatie de memorie, date imediate (constante) sau un port de intrare. Cu exceptia cazului important al instructiunilor PUSH si POP (1), sursa si destinatia nu pot fi simultan locatii de memorie.



Instructiunile de transfer se clasifica in instructiuni generale, specifice acumulatorului, specifice adreselor si specifice flagurilor.

In specificarea destinatiei si a sursei, se vor folosi notatiile segment : offset pentru adrese si notatia (x), pentru a desemna "continutul lui x'. Notatia cu paranteze se poate extinde pe mai multe nivele. De exemplu, (BX) inseamna continutul registrului BX, iar ((BX)) inseamna continutul locatiei de memorie adresate de BX (implicit prin DS). Similar ES:((BX)) va insemna continutul locatiei de memorie adresate de registrele ES si BX.

Cu exceptia instructiunilor SAHF si POPF (4), nici o instructiune de transfer nu modifica vreun bistabil de conditie.

1 Instructiuni de transfer generale - MOV, PUSH, POP, XCHG

Instructiunea MOV (Move Data - Transfera date)

Formatul general este:

MOV  destinatie, sursa ;(destinatie) <- sursa

in care sursa si destinatie (operanzii) sunt octeti sau cuvinte respectand regulile descrise mai sus.

Urmatoarele operatii sunt ilegale:

sursa si destinatia nu pot fi ambele operanzi in memorie;

nu pot fi folosite registrele FLAGS si IP;

operanzii nu pot avea dimensiuni diferite;

registrul CS nu poate aparea ca destinatie. Procesorul original 8086 are restrictiile suplimentare:

nu pot ti transferate date imediate intr-un registru de segment;

operanzii nu pot fi simultan registre de segment. Aceste ultime doua restrictii au fost relaxate la variantele ulterioare (80286 si peste). Exemple de instructiuni corecte:

MOV AX, BX

MOV AL, CH

MOV VAL[BX][SI], AL

MOV byte ptr [BX+100], 5

Ultima instructiune de mai sus ar fi fost ambigua fara utilizarea operatorului ptr: MOV [BX+100], 5 se poate interpreta ca "pune valoarea 5 in octetul de la adresa DS:BX+100' sau, la fel de bine, "pune valoarea 5 la cuvantul de la adresa DS:BX+100'. Forma "byte ptr' precizeaza ca este vorba de un transfer pe octet.

Exemple de instructiuni incorecte:

MOV AL, BX ; operanzi de lungime diferita

MOV [BX], [SI] ; ambii operanzi in memorie

MOV CS, AX ; registrul cs apare ca destinatie

De retinut ca o instructiune de forma:

.data

ALFA DB 1

.code

MOV AL, ALFA

incarca in AL continutul locatiei de memorie ALFA. Daca se doreste incarcarea adresei efective a variabilei ALFA, se poate folosi operatorul OFFSET:

MOV BX, OFFSET ALFA

sau instructiunea LEA (3).

Instructiunea PUSH (Push Data - Salveaza date in stiva)

Forma generala este:

PUSH sursa

in care sursa este un operand pe 16 biti (registru general de 16 biti, registru de segment sau locatie de memorie), iar semnificatia este "copiaza sursa in varful stivei'. Concret, executia instructiunii se face dupa secventa:

(SP) <- (SP) - 2

SS : ((SP)+1 : (SP)) <- sursa

ceea ce inseamna ca se decrementeaza SP cu 2 si in octetii de la adresele (SP)+1 si (SP) din segmentul de stiva se copiaza operandul sursa. Copierea respecta regula de memorare a cantitatilor pe mai multi octeti si anume, partea mai putin semnificativa (partea low) se memoreaza la adrese mici. O exprimare detaliata a instructiunii ar putea fi:

(SP) <- (SP) - 2

SS : ((SP)+1) <- high (sursa)

SS : ((SP)) <- low (sursa)

Exemple de instructiuni corecte:

PUSH BX

PUSH ES

PUSH [BX]

PUSH [BP+5]

PUSH ES:[BX][SI+4]

Exemplu de instructiuni incorecte:

PUSH AL  ; Operand pe 1 octet

Instructiunea POP (Pop Data - Refa date din stiva)

Forma generala este:

POP  destinatie

in care destinatie este un operand pe 16 biti (registru general de 16 biti, registru de segment sau locatie de memorie), iar semnificatia este "copiaza continutul varfului stivei in destinatie'. Registrul CS nu poate aparea ca destinatie. Concret, executia instructiunii se face dupa secventa:

destinatie <- SS : ((SP)+1 : (SP))

(SP)  <- (SP) + 2

ceea ce inseamna ca se transfera octetii de la adresele (SP)+1 si (SP) din segmentul de stiva in operand (destinatie) si apoi se incrementeaza SP cu 2. O exprimare detaliata a instructiunii ar putea fi:

high (destinatie) <- SS : ((SP)+1)

low (destinatie) <- SS : ((SP))

(SP)  <- (SP) + 2

Exemple de instructiuni corecte:

POP BX

POP ES

POP ES:[DI]

POP [BP+5]

POP SS:[BX+4]

Exemple de instructiuni incorecte:

POP  AL ; Operand pe 1 octet

POP  CS ; Registrul cs

Din analiza instructiunilor PUSH si POP, reiese ca o secventa de refaceri ale unor cantitati salvate in stiva (de exemplu, continutul unor registre) trebuie scrisa in ordine inversa. Daca secventa de salvare a fost:

PUSH AX

PUSH BX

PUSH CX



atunci secventa de refacere trebuie sa fie:

POP CX

POP BX

POP AX

Daca registrele de mai sus contin valorile AX = 1234H, BX = 5678H si CX = 9ABCH, iar registrul SP contine (inainte de salvari) valoarea 1288H, atunci imaginea stivei va fi cea din Figura

Figura 2.1 Imaginea stivei dupa o secventa de instructiuni PUSH si POP

La operatiile cu stiva, trebuie avut grija ca o secventa de refacere sa aduca indicatorul SP la valoarea de dinainte de secventa de salvare. Acest lucru inseamna ca, de regula, numarul operatiilor POP trebuie sa coincida cu cel al operatiilor PUSH.

Tot ca regula generala, nu este indicat sa se modifice explicit locatiile aflate "in josul stivei', adica la valori mai mari sau egale cu valoarea curenta a registrului SP. In acele locatii se pot afla informatii a caror alterare ar putea compromite definitiv executia programului. Trebuie, deci, folosite cu atentie secventele de genul:

MOV BX, SP

MOV SS:[BX], AX

MOV byte ptr SS:[BX+2], 1

Instructiunile PUSH si POP se mai pot folosi la transferul indirect al unor registre. Secventa:

PUSH DS

POP ES

copiaza continutul registrului DS in ES, lasand indicatorul SP neschimbat.

Instructiunile PUSH si POP realizeaza de fapt un transfer din memorie in memorie. Daca operandul din cele doua instructiuni este o locatie de memorie, ceea ce transfera la PUSH este continutul acelei zone. Secventa:

.data

X  dw 100

.code

PUSH X

va pune in varful stivei valoarea 100 (continutul lui X). Daca se doreste punerea in stiva a adresei efective sau complete a variabilei X, se va folosi instructiunea MOV si operatorul OFFSET sau instructiunea LEA (vezi 3), respectiv registrul de segment care adreseaza curent segmentul respectiv. Daca segmentul in care e definita variabila nu este adresat in mod curent de nici un registru de segment, se poate folosi operatorul SEG, care furnizeaza segmentul in care este definit operandul:

.code

LEA AX, X

PUSH AX ; Offset-ul la adrese mici

PUSH DS ; Apoi segmentul

Sau .

MOV AX, OFFSET X

PUSH AX ; Offset-ul lui X

MOV AX, SEG X

PUSH AX ; Adresa de segment a lui X

Instructiunea XCHG (Exchange Data - Interschimba date)

Forma generala este:

XCHG destinatie, sursa

iar semnificatia este cea de interschimbare a sursei cu destinatia. Registrele de segment nu pot aparea ca operanzi si, bineinteles, cel putin un operand trebuie sa fie registru.

Exemple de instructiuni corecte:

XCHG AL, AH

XCHG BX, SI

XCHG ES:[BX], AX

Exemple de instructiuni incorecte:

XCHG AL, BX ; Operanzi de lungime diferita

XCHG ES, AX ; Registru de segment

Instructiunea XCHG este utila la interschimbarea a doua cantitati aflate in memorie. Daca op1 si op2 sunt doi operanzi aflati in memorie, care trebuie interschimbati, secventa standard de interschimbare (folosind un registru general reg) este:

MOV reg, opl

XCHG reg, op2

MOV opl, reg

2 Instructiuni de transfer specifice acumulatorului - IN, OUT, XLAT

Instructiunea IN (Input Data - Citeste date de la port de intrare)

Forma generala este:

IN destinatie, port

in care destinatie este registrul AL sau AX, iar port este fie o constanta cuprinsa intre 0 si 255, fie registrul DX. Variantele noi de procesoare accepta orice registru in locul lui AL sau AX. Semnificatia este ca se executa o citire de la portul de intrare specificat, pe 8 sau 16 biti, dupa cum s-a specificat registrul AL sau AX. La variantele noi de procesoare (80286 si peste), registrele AL sau AX pot fi substituite cu orice registre generale.

Instructiunea OUT (Output Data - Scrie date la port de iesire)

Forma generala este:

OUT destinatie, port

in care destinatie este registrul AL sau AX, iar portul de iesire este specificat la fel ca la instructiunea IN.

Instructiunile IN si OUT sunt singurele instructiuni propriu-zise care pot realiza interactiunea procesorului cu alte dispozitive. Unele arhitecturi de calculatoare au organizata memoria in asa fel incat zone din spatiul adresabil sunt dedicate unor echipamente periferice, si nu unor zone propriu-zise de memorie. Accesul la zonele respective de memorie va insemna de fapt un acces la echipamentul periferic. Asemenea sisteme de intrari / iesiri se numesc de tip "memory-mapped' (intrari-iesiri organizate ca spatiu de memorie).

Sa consideram ca un echipament periferic necesita un port de stare si un port de date, ambele pe 8 biti. Intr-un sistem de intrari-iesiri obisnuit, vor exista doua porturi de intrare, de exemplu, 0F8H si 0F9H, dedicate perifericului respectiv. Intr-un sistem de tip "memory-mapped', vor exista doua adrese, de obicei adiacente, de exemplu c800:0000 si c800:0001, corespunzatoare porturilor de stare si de date. Secventele de citire stare, respectiv date, in cele doua tipuri de intrari / iesiri vor fi:

IN AL, 0F8H ; Citire stare

IN AL, 0F9H ; Citire date

MOV ES, 0C800H

MOV AL, ES:[0] ; Citire stare

MOV AL, ES:[1] ; Citire date

Instructiunea XLAT (Translate - Translateaza)

Instructiunea nu are operanzi, iar semnificatia este;

(AL) <- DS : ((BX) + (AL))

adica se aduce in AL continutul octetului de la adresa (BX) + (AL). Aceasta instructiune este folosita impreuna cu tabele de translatare (de unde si numele), utile in conversia unor tipuri de date. De exemplu, daca dorim sa convertim o valoare numerica intre 0 si 15 la cifra hexa corespunzatoare, putem folosi secventa:

.data

TABELA DB '0123456789ABCDEF'

.code



MOV BX, OFFSET TABELA

XLAT

prin care se incarca in BX offsetul tabelei de octeti si se face apoi translatarea.

3 Instructiuni de transfer specifice adreselor - LEA, LDS, LES

Aceste instructiuni transfera o adresa efectiva intr-un registru general sau o adresa completa pe 32 de biti intr-o pereche de registre.

Instructiunea LEA (Load Effective Address - Incarca adresa efectiva)

Forma generala este:

LEA registru, sursa

in care sursa este un operand aflat in memorie, specificat printr-un mod oarecare de adresare. Efectul este copierea adresei efective a operandului offset-ul in cadrul segmentului) in registrul general specificat. Exemple:

LEA BX, ALFA

LEA DI, ALFA [BX] [SI]

Un calcul similar al adresei efective se obtine si cu operatorul OFFSET si instructiunea MOV, calcul care se face insa la asamblare. Astfel, instructiunea LEA permite si moduri de adresare bazata si / sau indexata.

Instructiunea LEA se foloseste pentru incarcarea registrelor de baza sau de segment cu adresele efective ale unor operanzi din memorie, in vederea unor adresari ulterioare. Secventa:

.data

VECTOR  DW 10, 20, 30, 40, 50

.code

LEA BX, VECTOR

MOV SI, 4

MOV AX, [BX][SI]

va incarca in AX al treilea element al tabloului VECTOR.

Instructiunile LDS (Load Data Segment - Incarca DS) si LES (Load Extra Segment - Incarca ES)

Forma generala este:

LDS reg, sursa

LES reg, sursa

in care reg este un registru general de 16 biti, iar sursa este un operand de tip double-word aflat in memorie, care contine o adresa completa de 32 de biti. Efectul instructiunii este:

(reg)  <- ((sursa))

(DS) / (ES) <- ((sursa)+2)

adica se incarca perechea DS:reg, respectiv ES:reg, cu o adresa completa de 32 de biti. De obicei, instructiunea LDS se foloseste impreuna cu directiva Define DoubleWord, ca in exemplul urmator:

.data

x  db 10

y  db 15

adr_x dd x

adr_y dd y

.code

LDS SI, adr_x

LES DI, adr_y

MOV byte ptr [SI], 20

MOV byte ptr ES:[DI], 30

Variabilele adr_x si adr_y, care contin adresele far ale variabilelor x si y, sunt incarcate in DS:SI si ES:DI. Se acceseaza apoi variabilele x si y, folosind adresarea indexata.

Urmatorul exemplu utilizeaza o tabela de adrese. Sa presupunem ca avem 8 variabile word diferite, numite V_0, , V_7 si dorim sa incarcam in AX variabila a carui indice este dat de registrul CX. Cu alte cuvinte, daca CX=0, incarcam V_0, daca CX=1, incarcam V_1 etc. Definim in acest scop tabela de adrese TAB_ADR si folosim adresarea indexata.

.data

TAB_ADR  dd V_0, V_1, V_2, V_3, V_4, V_5, V_6, V_7

.code

MOV BX, CX

ADD BX, BX

ADD BX, BX

LES DI, TAB_ADR[BX]

MOV AX, ES:[DI]

Deoarece o pozitie din tabela ocupa 4 octeti, valoarea indicelui din CX trebuie inmultita cu 4. Acest lucru se obtine prin doua instructiuni ADD BX, BX, care aduna BX la el insusi.

4 Instructiuni de transfer specifice flagurilor (LAHF, SAHF, POSHF, POPF)

Instructiunea LAHF (Load AH with FLAGS - Incarca AH cu FLAGS)

Instructiunea nu are operanzi, iar semnificatia este data de denumire: se incarca registrul AH cu partea mai putin semnificativa a registrului de flaguri:

AH <- FLAGS0:7

Instructiunea SAHF (Store AH into FLAGS - Depune AH in FLAGS)

Este perechea instructiunii LAHF, semnificatia fiind:

FLAGS0:7 <- AH

Instructiunea PUSHF (Push Flags - Salveaza FLAGS in stiva)

Nu are operanzi, iar efectul este plasarea registrului FLAGS in varful stivei ("salvarea' flagurilor in stiva):

(SP)  <- (SP) - 2

SS:((SP) + 1 : (SP)) <- FLAGS

Instructiunea POPF (Pop Flags - Reface FLAGS din stiva)

Este perechea instructiunii PUSHF:

FLAGS <- SS:((SP) + 1 : (SP))

(SP) <- (SP) + 2

Instructiunile LAHF si SAHF citesc si scriu explicit partea mai putin semnificativa a registrului de flaguri. Partea mai semnificativa poate fi citita si modificata prin mici artificii cu instructiunile PUSHF si POPF. Secventa:

PUSHF

POP AX

va incarca in AX registrul de flaguri, deci in AH vom avea partea mai semnificativa, iar secventa:

PUSH AX

POPF

va incarca AX in registrul de flaguri.

Cu exceptia instructiunilor explicite SAHF si POPF, nici o instructiune de transfer nu modifica bistabilii de conditie.





Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 2495
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved