CATEGORII DOCUMENTE |
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 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 |
Vizualizari: 2674
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved