Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateC
C sharpCalculatoareCorel drawDot netExcelFox pro
FrontpageHardwareHtmlInternetJavaLinux
MatlabMs dosPascalPhpPower pointRetele calculatoare
SqlTutorialsWebdesignWindowsWordXml

Procedee de transfer cu memoria

calculatoare



+ Font mai mare | - Font mai mic



Procedee de transfer cu memoria

Deoarece numarul registrelor de uz general este mic, de multe ori este necesar ca anumite rezultate intermediare sau alte variabile sa fie stocate in memorie. Pentru efectuarea de trensferuri cu memoria sunt utilizabile mai multe solutii.



1 Transferuri prin adresare la memorie.

In acest caz, adresa efectiva este specificata de program, folosind unul din modurile de adresare prezentate anterior. Metoda va fi folosita atunci cand se doreste cunoasterea adresei de memorie respective, ea fiind impusa de algoritm. De exemplu, daca se doreste scrierea in memoria ecran care incepe la adresa A000h, adresa efectiva unde se va scrie poate fi specificata explicit de program.

2 Transferuri prin stiva

Pentru salvarea in memorie si readucerea din memorie a unor registre se pot folosi instructiunile complementare PUSH rs si POP rd.

Instructiunea PUSH rs:

Mnemonic: PUSH rs:

Efect:

Mai intai, registrul SP este decrementat cu 2. Apoi, continutul registrului sursa dublu rs este trimis in memorie (in stiva) la adresa specificata de registrul SP (stack pointer).

SP SP-2.

[SP] rsL

[SP+1] rsH

POP rd:

Efect:

Mai intai, continutul registrului destinatie dublu rd este incarcat din memorie (din stiva) de la adresa specificata acum de registrul SP (stack pointer). Apoi, registrul SP este incrementat cu 2.

rdL [SP]

rdH [SP+1]

SP SP+2.

Lucrul cu stiva prin instructiunile PUSH si POP este comod deoarece nu necesita calculul sau specificarea adresei de memorie. Trebuie sa se tina cont insa de ordinea in care au fost salvate registrele in stiva, astfel ca daca dorim refacerea lor, incarcarea trebuie facuta in ordine inversa.

Exemplul 1:

.

.

PUSH AX ;Acum SP=SPinitial-2.

;Salveaza AX la [SPinitial -2].

PUSH BX ;Salveaza BX la [SPinitial-4]

. ;Alte instructiuni

. ;pe parcursul carora SP=SPinitial- 4

.

POP BX ;Readuce BX de la[SPinitial-4].

;Acum SP=SPinitial-2.

POP AX ;Readuce AX de la [SPinitial-2].

;Acum SP=SPinitial.

.

.

.

Uneori poate fi alterata in mod voit ordinea inversa, pentru a se folosi alt registru destinatie decat cel care a fost initial sursa:

Exemplul 2:

.

.

.

PUSH AX ;Salveaza AX la [SP].Acum SP=SPinitial-2

. ;Alte instructiuni

. ;pe parcursul carora SP=SPinitial- 2

.

POP BX ;Acum SP=SPinitial. Readuce in BX de la ;[SPinitial], ceea ce a fost inainte in ;AX

.

.

.

Modul de lucru

P 1. Se vor incarca registrele in felul urmator: AX=1122, BX= 3344, CX=5566 si DX=7788. Sa se faca permutarea ciculara a acestor registre (AX ia valoarea lui BX, BX a lui CX, CX a lui DX iar DX a lui AX). Se vor folosi numai instructiuni PUSH si POP (se va observa evolutia stivei si a SP in partea din dreapta mijoc a TD) .

Indicatie:

Se va folosi un registru suplimentar pentru a memora temporar continutul unuia dintre registrele specificate.

3 Transferul prin initializarea/rezervarea de locatii de catre asamblor

In cazul in care nu este necesara o adresa anume de memorie, variabila putand fi stocata acolo unde exista loc liber, nu mai este necesara specificarea explicita a adresi efective. Se va folosi o directiva de asamblare de tip DB pentru rezervarea unei locatii de 1 octet sau DW pentru rezervarea unei locatii de 2 octeti (vezi anexa 1 - Directive de asamblare).

De regula, se va defini mai intai un segment de date, cu directiva:

.DATA

si aici se pot plasa directive de tip DB sau DW.

Exemplul 3:

.Radix 16

.Model small

.Stack 100h

.DATA

variabila1 DB ?

variabila2 DB 3F

variabila3 DW ?

sir1 DB 10 DUP(1A)

.Code

start:

mov ax, data  ;Incarca adresa ;segmentului

mov ds,ax ;de date in DS

mov al,variabila2 ;Incarca in AL constanta ;3Fh

add al, 55h ;Aduna cu 55h

mov varibila1,al ;Depune octetul din AL in ;memorie la adresa ;variabila1

mov ah,variabila2 ;Aduce si in AH constanta ;3Fh

mov variabila3,ax ;Depune cuvantul din AX ;in memorie la adresa ;variabila3

term: jmp temp

end start

Referirea in program a locatiei se face prin numele asignat in stanga directivei. Se observa ca daca se doreste initializarea locatiei, se va specifica constanta care trebuie sa fie initial acolo, iar daca nu, se va folosi simbolul '?'.

Se pot initializa mai multe locatii cu directiva DB sau DW, valorile respective fiind separate prin virgule.

Exemplul 4:

numere1 DW 23A4h,0BC56h,96h ;Declara 4 numere ;de 2 octeti

caractere DB 'F','2','7' ;Declara 3 ;caractere de un octet

const1 DB 21,0A2h,'L' ;Declara 3 valori ;diverse

De asemenea, se pot initializa sau rezerva un numar de n locatii cu formularea n DUP(const) sau respectiv n DUP(?) ca in exemplul de mai sus pentru constanta SIR.

Observatie: Cum s-a aratat si in lucrarea precedenta, instructiunile care urmeaza imediat dupa directiva .code (cele cu caractere bold in exemplul 3), sunt necesare intotdeauna atunci cand se declara un segment de date. Asamblorul si linkeditorul plaseaza acest segment acolo unde au memorie libera si adresa acestui segment trebuie incarcata explicit in registrul de segment de date, DS.

Dupa rularea instructiunii MOV DS,AX programul Turbo Debugger, daca are implicit afisata o fereastra Dump, va afisa automat zona respectiva cu registrul de segment ES, aceasta zona nefiind cea de date. Pentru a afisa chiar segmentul de date, trebuie data o noua comanda Dump din submeniul View dupa rularea acestei instructiuni atunci cand fereastra CPU este activata (daca nu este, se da un click pe aceasta fereastra). In noua fereastra dump se vor observa datele declarate.

Modul de lucru

P 2. Se va rula programul din exemplul precedent si se va observa evolutia registrelor si a zonei de memorie de date.

P 3. Se vor declara in segmentul de date sirul de cuvintele 1122, 3344 si 5566 si se vor transfera in alte trei locatii rezervate (in locatii consecutive variabilelor declarate initial).

Observatii:

Se vor folosi directive DW, deci adresa locatiei 3344 este sursa+2, etc. Pentru locatiile de destinatie se poate folosi o directiva de tipul:

dest DW 3 DUP(?)

P Se va declara in segmentul de date un sir de 10 numere crescatoare de un octet, incepand cu 1, si se va inversa continutul primei locatii cu ultima si a celei de a doua cu penultima.

4 Instructiunea de translatare a unei adrese, XLAT

Daca in memorie este definit un sir sau o tabela a carei adresa este specificata de BX , se poate face incarcarea in AL a valorii continute in locatia de memorie [BX+AL], adica a locatiei cu indexul dat chiar de AL in acea tabela.

Atentie: Indexarea incepe de la 0.

Formatul instructiunii este:

XLAT

Actiune:

AL [BX+AL]

Exemplul 5:

.

.

.

mov bx, 1200h

mov al,5

xlat ; In AL va apare continutul locatiei de memorie ;1205h adica al locatiei cu numarul 5 din tabela, TABELA5

.

.

.

Modul de lucru

P 5. Se va scrie un program care sa aduca in DL continutul locatiei cu indexul 5 dintr-o tabela care incepe la adresa 10 din segmentul de date si in DH continutul locatiei cu indexul 8 din acea tabela. Se va folosi instructiunea XLAT.

5 Instructiuni de transfer pentru registrul de flaguri

Verificarea/modificarea individuala sau in bloc a flagurilor se poate face prin transferul intre registrul AH si registrul de flaguri folosind urmatoarele instructiuni:

LAHF

Actiune: Incarca flagurile din registrul de flaguri in AH.

AH7=SF (flagul de semn, 1 daca este minus, 0 daca este plus);

AH6=ZF (flagul de zero, 1 daca este 0, 0 daca nu este 0);

AH5=0;

AH4=AF (flagul de transport auxiliar de la cei 4 biti inferiori ai unui rezultat);

AH3=0 ;

AH2=PF (flagul de paritate, 1 daca este par, 0 daca este impar);

AH1=IF (flagul de intreruperi, 1 daca daca intreruperile sunt activate, 0 daca nu);

AH0=CF (flagul de transport 1 daca exista transport de la rezultat);

SAHF

Actiune: Salveaza flagurile AH in registrul de flaguri.

SF=AH7 (flagul de semn, 1 daca este minus, 0 daca este plus);

ZF=AH6 (flagul de zero, 1 daca este rezultatu 0, 0 daca nu este 0);

AF= AH4 (flagul de transport auxiliar de la cei 4 biti inferiori ai unui rezultat);

PF=AH2 (flagul de paritate, 1 daca este par, 0 daca este impar);

IF= AH1 (flagul de intreruperi, 1 daca daca intreruperile sunt activate, 0 daca nu);

CF=AH0 (flagul de transport 1 daca exista transport de la rezultat);

Bitii AH5 si AH3 trebuie sa fie 0.

6 Incarcarea unei adrese logice din memorie

Daca in memorie la adresa nn se afla un pointer (ca o adresa logica de 32 de biti), ea poate fi adusa intr-o pereche formata dintr-un registru de segment si un registru de 16 biti, folosind instructiunile LGS/LSS/LDS/LES/LFS.

Sintaxa: LDS r16,RS:nn

LSS r16,RS:nn

etc.

Actiune:

LDS r16,nn: R16L[RS:nn], R16H[RS:nn+1], DSL[RS:nn+2], DSH[RS:nn+3]

LSS r16,nn: R16L[RS:nn], R16H[RS:nn+1], SSL[RS:nn+2], SSH [RS:nn+3]

LES r16,nn: R16L[RS:nn], R16H[RS:nn+1], ESL[RS:nn+2], DEH[RS:nn+3]

LFS r16,nn: R16L[RS:nn], R16H[RS:nn+1], FSL[RS:nn+2], FSH[RS:nn+3]

LGS r16,nn: R16L[RS:nn], R16H[RS:nn+1], GSL[RS:nn+2], GSH[RS:nn+3]

unde r16 este un registru de 16 biti de uz general, RS este un registru de segment (DS,SS,ES,FS sau GS) iar nn este un numar de 16 biti.

Observatii:

  • Instructiunile LSS, LGS, LFS nu apar la procesoare anterioare lui 80386 (nici nu existau registrele de segment FS si GS), de aceea, in cazul folosirii lor, in partea initiala a programului trebuie introdusa directiva .386.
  • Cu specificarea directivei .386, se poate folosi in al doilea operand si un numar nnnn (de 32 de biti).

Modul de lucru

P 6. Sa se scrie un program care sa aduca in perechea ES:AX continutul a patru locatii de memorie a caror adresa de inceput este data de DS+10h. Se va folosi instructiunea LES.

7 Incarcarea unei adrese efective

Atunci cand trebuie specificata o adresa care a fost calculata de asamblor si nu este cunoscuta numeric, se poate folosi instructiunea LEA (Load Effective Adress):

Sintaxa: LEA r16, m16

Actiune: r16 m16

Exemplul 6:

.radix 16

.model small

.stack 100h

.DATA

sir1 db 13,14,15,1,2,3

sir2 db 16,17,18,19

.code

start: mov ax,@data ;Adresa segmentului de date

mov ds,ax ;se incarca in DS

lea di,sir2 ;In DI se va afla offset-ul ;sirului notat 'sir2'(in acest caz 06),

;in memoria de date

mov al,[di+2] ;Transfera din a treia locatie ;a acestui sir in AL

Observatii:

  • Pentru transferurile care implica segmentul de date vor fi folosite ca registre destinatie la instructiunea LEA numai registrele BX, SI si DI si nu va fi folosit BP.
  • Instructiunea LEA rd, adresa_efectiva poate fi inlocuita in majoritatea cazurilor cu instructiunea MOV rd,OFFSET adresa_efectiva, lasand astfel asamblorul sa calculeze si sa incarce valoarea corecta a adresei efective in registrul dorit. Sunt situatii insa cand instructiunea LEA este mai eficienta (de exemplu la lucrul cu directive de grupare).

P 7. Sa se scrie un program care sa inverseze al treilea element al primului sir declarat ca in exemplul 6 cu elementul al patrulea al celui de-al doilea sir. Se va folosi instructiunea LEA.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1283
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