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