Segmentace paměti v ASM - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Assembler

Segmentace paměti v ASM

asm

1. listopadu 2001, 00.00 | Lehký úvod do programování v asembleru. Dobrým základem pro práci v asembleru je pochopení správy paměti. Proto se v prvním díle budeme zabývat právě segmentací paměti, správou registrů ap.

1. Předpoklady
Nezbytným předpokladem pochopení a porozumění této úvodní kapitole a celému assembleru vůbec je dobrá orientace v šestnáctkové a dvojkové soustavě a znalost převodů mezi nimi. Ostatně v assembleru desítkovou soustavu využijete zřídka a proto je nutné mít "zažité" počítání v těchto pro nás poněkud nepřirozených soustavách. Pokud si budete zkoušet některé malé příklady tohoto dílu doporučuji zatím využít možnost vkládat instrukce přímo do zdrojového kódu některého z vyšších jazyků (tzv. vkládaný assembler). V Pascalu vkládáme instrukce mezi klíčová slova:
asm
...
end;

2. 8086
Procesor 8086 má 16-ti bitovou datovou a 20-ti bitovou adresovou sběrnici. To znamená, že je schopen adresovat paměť o velikosti 1MB (220=1048576 možných adres). Obsahuje ale jen 16-ti bitové registry, což nutně vede k "problémům" s prací s adresami a k tzv. segmentaci paměti.

3. Segmentace paměti
Paměť "z nutnosti" logicky dělíme na homogenní části, tzv. segmenty paměti, jejichž maximální velikost je 64kB (216=65536 možných adres - obsah registru). Jediná podmínka, kterou musí segment splňovat je, aby jeho počáteční adresa byla násobkem šestnácti, odtud plyne, že teoreticky se paměť dá rozdělit na 1048576 / 16 =65536 segmentů. Posun v rámci segmentu vzhledem k jeho bázové (počáteční adrese) určuje tzv. offset. Adresa se tedy skládá ze dvou šestnáctibitových částí. V praxi to vypadá nějak takhle:
adresa :            segment:offset
napr.16:	 	     A0CF:CB54
napr. 2:   1100110011001110:1100101010101010	
Protože ale k adresaci 1MB paměti je nutné použít 20-ti bitů, musíme tuto logickou adresu upravit do 20-bitového tvaru na fyzickou adresu:
adresa:
                  segment:A0CF0
                 + offset:0CB54	
                          -----
                          AD844
Všimněte si, že rozšíření na 20-bitů jsme dosáhli tím, že jsme k původní 16-bitové adrese přidali 4 bity, pro segment zprava (nyní už je jasné, proč je adresa počátku segmentu vždy násobkem 16) a pro offset zleva. V 16-ti bitovém tvaru jsou 4 bity jedna pozice pro znak z hexadecimální abecedy. To ale mimo jiné znamená, že změníme-li vhodně adresu počátku (báze) segmentu a offset (posun od báze), můžeme dosáhnou stejné fyzické adresy:
adresa:
                  segment:9FD00
                 + offset:0DB44	
                          -----
                          AD844
Přičteme-li k segmentové adrese 1, je to stejné, jako bychom zvýšili offset o 16, naopak, zvýšíme-li např. offset o 32, je to totéž, jako kdybychom zvedli bázovou adresu segmentu o 2. Tak můžeme jedno fyzické místo v paměti určit mnoha kombinacemi různě velikých segmentů a offsetů.

4. Registry
Registry jsou rychlé "vnitřní paměti procesoru", do kterých ukládáme hodnoty na nichž potom procesor vykonává operace. Podle typu procesoru je dělíme na 16-ti bitové (8086, 286) a 32-bitové (386, 486, Pentia).

4.1 Univerzální registry
Univerzální registry jsou EAX, EBX, ECX, EDX a jejich využití závisí více méně na programátorově fantazii. Struktura registrů má své historické opodstatnění a je následující:

EAX - využívá se při aritmetických operacích a práci s porty př:
mov eax, 401h ; do eax premisti 401h
mov ebx, 50h ; do ebx premisti 50h
sub eax, bx ; od eax odecti ebx, výsledek->eax

Všimněte si na výpisu z obsahu registrů že skutečně dochází ke komentovaným změnám.


EBX - bázový registr používaný k adresování paměti
mov al, ds:[dx] ; do al uloz obsah pameti z adresy segment ds, offset dx
ECX - počitadlo využívané cykly a řetězcovými operacemi
mov ax, 000001h ; do ax uloz 1
mov cx, 5h ; do cx uloz pocet posunu
shl ax, cl ; posun o 5 vlevo => ax shl cl = 2*2*2*2*2=32
EDX - operace s porty, adresace
mov dx, 0378h ; do reg. dx umistime cislo portu
mov al, 08h ; co chceme poslat na port
out dx, al ; odesli na port dx hodnotu al

4.2 Segmentové registry
CS - code segment, ukazatel na segment kódu (programu)
SS - stack segment, ukazatel na segment zásobníku
DS - data segment, ukazatelů na segment dat
ES - extra segment, volně využitelný

4.3 Indexové registry a ukazatele
BP - base pointer, bázový registr
SP - stack pointer, ukazatel zásobníku
DI - destination, adresa cíle
SI - source, adresa zdroje

4.3.1 Registr IP
IP - instruction pointer, ukazatel na právě prováděnou instrukci, obsah tohoto registru nelze přímo zjistit, ale můžeme použít následující techniku:
call Get_IP ; volani procedury, v zasobniku se uchova navratova adresa, tj. aktualni IP pro navrat
Get_IP:
pop si ; preneseni slova z vrcholu zasobniku
pozn.: To je i jeden z možných důvodů zobrazení chyby Error 202: Stack overflow error . Došlo k přeplnění zásobníku neustálým ukládáním IP adresy, např. procedura:
procedure Stack_overflow;
begin
Stack_overflow
end;

4.4 Registr příznaků (FLAGS)

CF - carry flag : odráží výsledek operace, je v něm uložen přenos z nejvyššího bitu:
mov al, $FE ; $FE -> al
add al, $05 ; reg. AL je 8-bitovy a $FE + $05 = $103 > $FF, v al bude $03 a v CF bude nastaveno 1
PF - parity flag : příznak lze použít pro kontrolu správnosti dat, při sudé paritě je nastaven na 1 a při liché je tato vlajka shozena, tzn. že v předchozím příkladu, kdy je výsledek v al=$03=00000011 bude PF=1, pokud bychom ale např. přičítali $04, potom bude výsledek v al=$02=00000010 a PF=0
AF - auxiliary flag : podobný jako CF,ale AF=1 pokud vzniká přenesení z nižší slabiky do vyšší , či z nižší poloviny slabiky do vyšší (tj, ze 4 do 5 bitu), využití v BCD:
mov al, $0F ; $FE -> al $F=00001111
add al, $01 ; pridanim $01 vznika preneseni ze 4 do 5 bitu => AF=1
ZF - zero flag : ZF=1 pokud je výsledek operace roven 0
SF - sign flag : SF=1 pokud je výsledek operace záporný, tj. SF je rovno nejvyššímu bitu výsledku operace
TF- trap flag : příznak krokování (ladění), TF=1 pokud provádíme program po instrukcích
IF - interrupt flag : příznak přerušení IF=1, pokud jsou dovoleny vnější maskovaná přerušení
DF- direction flag : příznak směru
OF - overflow flag : příznak přetečení,OF=1, potom výsledek operace přetekl do znaménkového bitu:
mov ax, -$8000 ; -$8000=2^15, tzn. ze vsechny bity vcetne znamenkoveho jsou rovny 1
sub ax, $1 ; preteceni do znamenkoveho bitu=> OF=1

Příště:
- šablony COM a EXE souborů
- proměnné, konstanty
- logické operace
- atd.

Tématické zařazení:

 » Rubriky  » Assembler  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: