CATEGORII DOCUMENTE |
Transferuri de date si operatii aritmetice cu memoria
1 Componentele unei adrese logice
Pentru a modulariza blocurile de memorie folosite de diverse task-uri si pentru a nu trebui specificata pe tot parcursul unui program o adresa logica de 32 de biti, arhitectura procesoarelor Intel x86 foloseste procedeul segmentarii. Astfel, spatiul de memorie este impartit in blocuri de maxim 64 KB in Modul Real (respectiv 1 MB sau 4 GB in Modul Protejat), blocuri numite segmente.
Aceasta permite ca in Modul Real specificarea unei adrese de memorie sa se faca prin numai 16 biti, considerati ca fiind pozitia locatiei respective de memorie fata de baza segmentului in care se afla. Acesti 16 biti formeaza adresa efectiva sau deplasamentul (offset). Ne vom referi in continuare, daca nu se va specifica altfel, numai la Modul Real de functionare.
Segment n
. .
. .
. .
. .
. . Locatia vizata
Segment 2
Adresa efectiva (AE)
Adresa logica (AL)
Segment 1 Adresa baza segment (ABS)
Figura 1 - Adresarea in cadrul unui segment
Blocul de management al memoriei din interiorul procesorului va forma automat o adresa logica de memorie ca in figura 1, dupa urmatoarea formula generala:
AL = AS*16 +AE
unde:
AL este adresa logica (coincide cu adresa fizica, transmisa pe magistrala de adrese, daca nu se foloseste paginarea).
AS este adresa de segment, continuta in unul din urmatoarele registre:
-CS pentru segmente de coduri de instructiuni
-DS pentru segmente de date
-SS pentru segmente de stiva
-ES pentru extrasegmente
Ea nu coincide cu adresa bazei segmentului , acesta fiind obtinuta prin deplasarea cu 4 biti spre stanga a adresei de segment (inmultire cu 16):
ABS=16*AS
Prin acest procedeu de scriere a dreselor de segment, ele vor avea numai 16 biti, iar adresa bazei segmentului va avea 20 si se obtine automat in unitatea de management a memoriei din interiorul microprocesorului.
AE este adresa efectiva , indicand pozitia in interiorul unui segment, adica deplasamentul fata de baza segmentului. Ea are 16 biti,ceea ce inseamna ca un segment are o lungime de maxim 64k (216 locatii).
Conventii :
Orice operand pus intre paranteze drepte reprezinta o adresa de memorie . De exemplu [3A21] reprezinta continutul locatiei de memorie cu adresa efectiva 3A21, iar [BX+DI] reprezinta continutul locatiei de memorie a carei adresa efectiva este data de suma intre registrele BX si DI.
Este permisa si scrierea RG[const] cau const[RG] unde RG este un registru general iar const este un deplasament (numar sau eticheta ) care se aduna la continutul acestui registru. Acesta forma este echivalenta cu [RG+const], deci scrierea de termeni alaturati are semnificatie de sumare si nu de inmultire.
Exemplu 1:
MOV CL,BX[10h] ; Incarca in CL continutul ;locatiei de memorie a carei adresa efectiva este suma ;intre continutul lui BX si constanta 10h, iar adresa de ;segment este continuta in DS.
In mod normal, programatorul va specifica numai adresa efectiva, dar in cazuri speciale se poate folosi totusi si adresa fizica, prin specificarea si a adresei de segment, cu sintaxa:
AF=AS:AE
Exemplul 2:
MOV AH,DS:[20h] ;Transfera in AH continutul ;locatiei 20h din segmentul a carui ;adresa este continuta in registrul DS
MOV SS:[BX+10h], CL ;Transfera continutul lui CL ;in locatia a carei adresa efectiva este ;data de continutul lui BX adunat cu 10h, ;din segmentul a carui adresa este ;continuta in SS.
Modul de lucru:
P 1 Se va scrie si se va testa un program care efectueaza urmatoarele:
Incarca constanta 22h in registrul AL
Trimite aceasta constanta in memorie la adresa BX[20] si la adresa DS:30
Indicatii:
Ambele locatii sunt plasate in segmentul de date si se pot vizualiza in zona Dump din fereastra inferioara a Turbo Debugger.
2 Componentele unei adrese efective
Este comod sa se lucreze in mod normal cu adrese efective, adresa de segment fiind incarcata de procesor in mod automat din registrul de segment implicit pentru operatia respectiva. Aceasta conduce insa la necesitatea cunoasterii registrelor implicite pentru diversele adresari, registre care vor fi specificate in continuare.
AE se alcatuieste dupa formula generala:
AE = (BX/BP)* + (SI/DI)* + (D8/D16)*
unde:
* indica un termen optional (nu se admite o AE formata numai din ultimul termen)
/ separa variantele unui termen
BX si BP sunt registrele de tip baza
SI si DI sunt registrele index ( sursa si respectiv destinatie)
D8 si D16 reprezinta un deplasament exprimat pe 8, respectiv 16 biti
Deci, adresa efectiva se exprima si sub forma:
Adresa = Baza + Index + Deplasament,
unii dintre acesti termeni fiind optionali.
In functie de registrele generale folosite in formarea unei adrese, registrele de segment implicite sunt cele din tabelul 1.
Registru general |
Registru de segment implicit |
SP |
SS |
BP |
SS |
BX |
DS |
SI |
DS |
DI |
ES |
BP+SI sau BP+DI |
SS |
BX+SI sau BX+DI |
DS |
IP |
CS |
Tabelul 1- Registrele de segment implicite la formarea unei adrese
Trebuie sa se tina seama in permanenta de regulile registrelor de segment implicite deoarece asamblorul nu poate semnala erori in cazul utilizarii lor incorecte. De exemplu, daca se doreste citirea unei valori din segmentul de date si se foloseste registrul general BP in instructiunea:
MOV CH,[BP+10]
asamblorul considera ca aceasta instructiune este corecta si ca intentia programatorului a fost sa citeasca din segmentul de stiva (vezi tabelul). Programatorul ar fi trebuit sa foloseasca unul din registrele BX sau SI daca dorea citirea din segmentul de date.
Observatie: Asamblorul nu accepta AE specificata numai ca o constanta numerica, deoarece nu poate sti registrul de segment implicit. De aceea, se vor folosi forme de sumare cu un registru (eventual adus la 0 in prealabil), sau adrese logice . Exemplu: in loc de MOV AL, [3000] se va folosi MOV AL,[BX+3000], daca BX a fost facut 0 in prealabil. Unele asambloare dau insa doar o avertizare si folosesc segmentul de date, indiferent daca aceasta a fost intentia programatorului sau nu.
Modul de lucru:
In programele care urmeaza se va incerca, de cate ori este posibil, sa se foloseasca adrese efective, lasand procesorul sa incarce automat adresa de segment din registrul implicit specificat in tabelul 1.
P 2. Se va scrie si se va testa un program care efectueaza urmatoarele:
Incarca constanta 22 in registrul AL;
Trimite aceasta constanta in memorie in segmentul de date la adresa 10 si la adresa 30;
Trimite aceasta constanta in memorie in segmentul de stiva la adresa 120.
Indicatii:
Primele doua locatii se pot vedea in fereastra Dump, iar ultima in fereastra Stack din dreapta jos a Turbo Debugger.
Pentru a se specifica segmentul de stiva, se va folosi adresarea prin registrul BP.
3 Transferuri pe 1 octet si pe 2 octeti
O locatie de memorie are prin conventie un octet, astfel ca ea poate fi operand numai pentru un registru de 8 biti. In cazul in care se fac transferuri cu registre de 2 octeti se utilizeaza urmatoarea conventie ('little-endian'): la adresa specificata se afla octetul inferior al registrului dublu, iar la adresa imediat urmatoare octetul superior.
Specificarea lungimii operandului (1 octet sau 2 octeti) este sau implicita sau declarata cu prefixele BYTE PTR repectiv WORD PTR .
Exemplul 3:
MOV AL, [BX+3000] transfera numai in AL octetul de la adresa 3000 din segmentul de date. Nu este nevoie de prefix deoarece operandul AL este de 8 biti si rezulta implicit un transfer de un octet.
MOV AX, [SI+3000] transfera in AL octetul de la adresa 3000 din segmentul de date si in AH octetul de la adresa 3001 din segmentul de date (intotdeauna in octetul superior continutul locatiei de memorie cu adresa mai mare). Nu este nevoie de prefix deoarece operandul AX este de 16 biti si rezulta implicit un transfer de doi octeti.
ADD word ptr [BX+3000],59 aduna la cuvantul (numar de 16 biti) continut in locatiile 3001 si 3000 din segmentul de date, numarul 59. Daca nu s-ar specifica lungimea 'word ptr', s-ar face adunarea pe un singur octet intre continutul locatiei 3000 si constanta 59.
ADD byte ptr [BP+3000],59 aduna la octetul continut in locatia 3000 din segmentul de stiva, numarul 59, fara vreo influenta asupra locatiei 3001. Daca nu s-ar specifica lungimea, operatia s-ar efectua tot pe un octet, dar asamblorul ar afisa totusi o avertizare legata de lungimea operanzilor.
Modul de lucru :
Se vor scrie si testa urmatoarele programe, folosindu-se pe cat posibil numai adrese efective:
P Program care incarca in AX constanta 3344 si o trimite in memorie la adresa 20h. Se va observa in ce fel apar octetii acestei constante in memorie.
P 4.Trimite in memorie la adresa 20 constanta 1122 si la 30 constanta 44
P 5. Program care:
incarca constanta 33EE in AX
o trimite in memorie la adresa 30
incarca constanta 22 in AL
aduna aceasta constanta la numarul din locatiile incarcate anterior cu constanta 33EE.
Indicatii:
Pentru a avea rezultatul adunarii pe 16 biti, va trebui folosit registrul AX, dupa ce se incarca AH cu 00.
In memorie, la adresa DS:30 vor apare octetii 10.34, adica numarul 3410, rezultatul adunarii lui 33EE cu 22.
P 6. Program care trimite in memorie la adresa 10 din segmentul de date suma constantelor 44 si 122, fara sa se specifice explicit registrul de segment.
Indicatii:
Rezultatul, la adresa 10 trebuie sa apara sub forma 66.01.
P 7. Acelasi program ca la punctul 6 dar se vor folosi adrese logice, fara a implica alte registre generale (se presupune ca nu trebuie modificat continutul acestora).
Indicatii:
Va fi necesar sa se specifice explicit registrul de segment.
4 Moduri de adresare
In functie de termenii folositi in formula generala a adresei efective, se definesc urmatoarele moduri de adresare:
1. Adresare imediata la memorie:
Se specifica in adresa efectiva numai deplasamentul, care constituie chiar adresa efectiva. Conform observatiei de la paragraful 2, este necesar sa se specifice si registrul de segment, deci se va scrie de fapt o adresa logica.
Exemplul 4:
MOV AX,DS:[54] ;Incarca in AL continutul locatiei cu adresa efectiva 54 din segmentul de date, iar in AH continutul locatiei urmatoare
MOV ES:[3AC2],DL ;Incarca in locatia cu adresa efectiva 3AC2 din extrasegment continutul registrului de 8 biti DL
Adresa efectiva poate fi specificata si printr-o eticheta (in paranteze drepte si cu specificarea unui segment sau a unui registru general) care a fost declarata anterior. Declararea unei etichete se face cu una din variantele:
eticheta EQU numar
eticheta EQU sir
eticheta = numar
Daca se foloseste forma cu EQU, se admite pentru asignare si un sir de caractere, in schimb nu se mai poate face alta asignare ulterioara in program. Forma cu = admite reasignari, dar nu permite asignarea cu siruri.
Exemplul 5:
adresa1 equ 20h
adresa2 equ adresa1+2
adresa3=30h
.
.
.
mov AL,DS:[adresa1]; Incarca in AL continutul ;locatiei de memorie de la adresa 20h ;din cadrul segmentului de date
mov SI[adresa2],ch ;Incarca CH in adresa 22h ;din cadrul segmentului de date
mov AH,[BP+adresa3];Incarca in AH de la ;adresa 30h din cadrul segmentului de ;stiva
.
.
.
2. Adresarea directa
In caz ca se utilizeaza numele unei locatii declarate in cadrul segmentului de date, nu mai sunt necesare parantezele drepte si un alt registru. Adresa de segment este continuta implicit in DS, daca nu se specifica altfel.
Aceasta forma este posibila pentru segmentul de date, care poate fi declarat in partea initiala a programului, fara ca programatorul sa se preocupe de plasarea sa exacta in memorie. Se utilizeaza directive de rezervare a unor locatii de memorie, DB, DW, etc. care vor fi prezentate pe larg mai tarziu. Adresa va fi calculata automat de asamblor si inlocuita in instructiune cu valoarea numerica corespunzatoare.
Exemplul 6:
.model small
.stack 100h
.DATA
locatie db 33,44,55,66 ;Stabileste adresa ;'locatie' la inceputul ;segmentului de date
.code
MOV AX, data ;Incarca adresa segmentului de date
MOV DS,AX ;in registrul DS
MOV AL,locatie+2 ;Incarca in AL octetul de la a ;locatia 02 din DS
MOV locatie+1, byte ptr AL;Incarca in locatia 01 ;continutul lui AL
.
.
.
Se observa ca nu este necesara punerea operandului de adresa in paranteze, prin eticheta declarata dupa directiva .DATA intelegandu-se implicit continutul unei locatii de memorie.
Observatie: Instructiunile care urmeaza imediat dupa directiva .code din exemplul de mai sus ( cele cu caractere bold) 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. Cum acest registru nu admite o incarcare directa cu o constanta, aceasta adresa, cunoscuta de asamblor prin simbolul @data se incarca intai intr-un registru general si apoi se transfera in registrul DS. Se poate folosi si forma de referire la o variabila sau constanta din segmentul de date (forma nerecomandata totusi in astfel de cazuri):
MOV AX, seg locatie
Programul Turbo Debugger, daca are implicit afisata o fereastra Dump, dupa rularea instructiunii MOV DS,AX va afisa automat zona respectiva cu registrul de segment ES. Pentru a afisa chiar segmentul de date, trebuie data o noua comanda Dump din submeniul View, 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.
Adresare indirecta la memorie prin registru.
Se specifica in instructiune registrul din care se va lua adresa efectiva. Dupa cum rezulta din formula, registrul este unul din urmatoarele: BX,BP,SI,DI.
Exemplul 7:
MOV AL, [BX] ;Incarca in AL continutul ;locatiei de memorie a carei adresa efectiva este ;continuta in BX si adresa de segment continuta in ;registrul implicit DS.
MOV [BP],CX ;Incarca continutul lui CL in ;locatia de memorie a carei adresa efectiva este ;continuta in BP si adresa de segment continuta in ;registrul implicit SS, iar continutul lui CH in locatia ;de memorie urmatoare.
Daca nu se specifica in adresa si un registru de segment, acesta va fi cel implicit, specificat de tabelul 1
4.Adresare indirecta la memorie prin registru cu deplasare.
Adresa efectiva este data de suma registrului si deplasamentului specificate de instructiune. Adresa de segment va fi data de DS, cu exceptia cazului in care se utilizeaza registrul BP, caz in care adresa de segment este data de SS.
Exemplul 8:
MOV AL,[DI+31] ; Transfera in AL continutul locatiei a carei adresa este data de continutul lui DI la care se aduna 31, iar adresa de segment este data de DS.
MOV [BP+1226],CX; Transfera pe CL in locatia a carei adresa este data de continutul lui BP la care se aduna 1226, iar adresa de segment este data de SS, iar CH in locatia urmatoare.
Aceste instructiuni se mai pot scrie si :
MOV AL,31[DI] respectiv
MOV 1226[BP],CX
Modul de adresare prin registru cu deplasare se recomanda pentru adresarea elementelor sirurilor si tabelelor. De exemplu, daca s-a definit anterior constanta numerica TAB ( de exemplu TAB EQU 2100) se poate adresa elementul de tabel cu numarul continut in registrul SI printr-o instructiune de genul ADD BX, TAB[SI].
5.Adresare indirecta la memorie prin 2 registre.
Adresa efectiva este data de suma a doua registre specificate de instructiune (una din cele 4 variante posibile conform expresiei generale).
Registrul de segment implicit este DS cu exceptia cazului cand este mentionat BP, in care caz segmentul este cel de stiva, cu adresa continuta in SS.
Modul de adresare prin registru cu deplasare se recomanda pentru adresarea elementelor sirurilor si tabelelor. De exemplu, daca s-a incarcat anterior constanta numerica TAB intr-un registru de baza ( de exemplu MOV BX,2100) se poate adresa elementul de tabel cu numarul continut in registrul SI printr-o instructiune de genul MOV CX,[BX+SI].
Exemplul 9:
MOV CL,[BP+SI] sau MOV CL,[BP][SI]
SBB DX,[BX+DI] sau SBB DX,[BX][DI]
6.Adresare indirecta la memorie prin 2 registre cu deplasare.
Adresa efectiva este data de suma a doua registre si un deplasament, toate elementele fiind specificate de instructiune.
Registrul de segment implicit este DS cu exceptia cazului cand este mentionat BP, in care caz segmentul este cel de stiva, cu adresa continuta in SS.
Exemplul 10:
MOV CX,[BX+SI+2C]
SUB DX,[BP+SI+2455]
Modul de adresare prin 2 registre cu deplasare se recomanda pentru adresarea elementelor matricilor. De exemplu, daca s-a definit anterior constanta numerica MAT ( de exemplu 2100) iar BP contine numarul unei linii inmultit cu numarul total de coloane se poate adresa elementul din linia respectiva avand indicele (numarul de coloana) continut in registrul SI, printr-o instructiune de genul:
ADD BX,MAT[BP][SI];echivalenta cu ADD BX,[BP+SI+2100]
De exemplu, pentru o matrice cu 5 linii si 6 coloane, care incepe la adresa 20h, daca se doreste accesarea elememtului al treilea din linia a patra, vom scrie:
MAT=20h
MOV BX, 18
MOV SI,3
MOV CL, MAT[BX+SI]
Modul de lucru
P 8. Se va realiza un program care sa execute prin adresari imediate urmatoarele operatii:
In CH se va citi (transfera) de la adresa 10 din memoria de date
In DX se va citi de la adresa 11
Se va scrie la adresa 20 constanta 22
Se va scrie la adresa 21 constanta 8877
Se va scrie la adresa 30 continutul lui CH
Se va scrie la adresa 31 continutul lui DX
P 9. Se va realiza un program care are urmatoarele date initiale: constantele de un octet A=11 si B=22 si constantele de doi octeti C=3344 si D=5566.Se va calcula in BX expresia (C+D)-(A+B).
P 10. Se vor incarca registrele in felul urmator: AX=2233, CX= 99AA, DL=10 BX=20. Suma dintre AX si CX se va trimite in memorie la adresa formata din suma intre BX si DL iar diferenta lor la adresa imediat urmatoare.
Indicatii:
- AX trebuie salvat inainte de sumare;
-DL nu poate fi adunat direct cu BX si nici nu poate fi folosit la formarea AE.
-In memorie, la adresa DS:0030 va apare sirul: DD.BB.89.88
P 11. 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 pentru stocarea temporara in memorie a unui registru modul imediat, modul direct si modul indirect.
P 12. Folosind instrunctiunea de adunare a unui registru cu o constanta, se vor incarca 4 locatii succesive de memorie incepand de la 10, cu numere crescatoare de un octet, incepand cu 1.
P 1 Acelasi program ca la punctul 12, dar cu numere pe doi octeti incepand cu 1000.
P 14. Acelasi program ca la punctul 12, dar cu numere pe un octet multipli de 5.
P 15. Acelasi program ca la punctul 13, dar cu numere pe doi octeti, multipli de 201.
P 16. Se va completa ultima varianta de program pentru a se transfera continutul zonei de memorie de la 10 la 15 incepand de la adresa 30 .
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 1849
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved