Ľudmila Jánošíková | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Programovanie v jazyku symbolických adries | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pre 32-bitové procesory Intel | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Štandardné segmentové direktívy
Definovanie segmentov pomocou štandardných segmentových direktív je zložitejšie ako so zjednodušenými segmentovými direktívami. Avšak na druhej strane štandardné segmentové direktívy dovoľujú nastaviť rôzne parametre segmentov, napr. určiť, na akej adrese má segment začínať. Skôr, ako pristúpime k popisu jednotlivých direktív, ukážeme rámec programu pri použití štandardných segmentových direktív:
Zasobnik SEGMENT para stack ’stack’ Data SEGMENT word public ’data’ Program SEGMENT word public ’code’ END Zac
Začiatok segmentu definuje direktíva meno_segmentu SEGMENT [align] [combine] [use] [class] Význam nepovinných parametrov je nasledujúci: Parameter align (zarovnanie) určuje, na akej adrese bude segment začínať. Môže nadobúdať hodnoty:
Segmenty definované pomocou zjednodušených direktív majú zarovnanie para. Parameter combine (typ spojenia) určuje, či a akým spôsobom bude spojovací program (linker) spájať daný segment so segmentami rovnakého mena z iných modulov. Parameter combine môže nadobúdať hodnoty:
Obr. 20 ilustruje rôzne spôsoby spojenia pre segmenty rovnakého mena s parametrom combine z dvoch rôznych modulov A a B.
Obr. 20. Spôsoby spojenia segmentov Zjednodušené segmentové direktívy definujú pre dátový a kódový segment typ spojenia public, pre zásobníkový segment typ stack. Parameter use nastavuje dĺžku offsetu:
Pri použití zjednodušených segmentových direktív závisí dĺžka offsetu od poradia direktívy .MODEL a direktív, ktoré sprístupňujú inštrukčný súbor daného procesora (sú to direktívy .386, .486, .586). Ak najprv uvedieme .MODEL a potom napr. .386, budú mať všetky segmenty 16-bitový offset. Ak použijeme opačné poradie (najprv .386, potom .MODEL), budú mať všetky segmenty 32-bitový offset. Parameter class (trieda) je reťazec v apostrofoch; určuje, v akom poradí budú segmenty zoradené v .EXE súbore. Spojovací program umiestni všetky segmenty jednej triedy za sebou. Poradie tried sa určuje podľa poradia tried v prvom .OBJ súbore, poradie segmentov v rámci jednej triedy potom podľa poradia .OBJ súborov pri spájaní. Napr. ak spájame súbory ZACIATOK.OBJ, POKRAC.OBJ, KONIEC.OBJ do súboru CELY.EXE a poradie segmentov podľa tried v jednotlivých súboroch je:ZACIATOK.OBJ: ‘data’, ‘code’, ‘stack’ POKRAC.OBJ:
‘stack’, ‘data’, ‘code’ KONIEC.OBJ:
‘data’, ‘code’ tak výsledné poradie segmentov
v CELY.EXE bude: ‘data’,
‘code’, ‘stack’. Poradie segmentov v .OBJ súbore možno ovplyvniť direktívami .SEQ (implicitne) – segmenty v .OBJ súbore budú v takom poradí, ako sú uvedené v zdrojovom texte; .ALPHA – segmenty sa zoradia v abecednom poradí podľa mien (nie podľa tried!). Ak spájate assemblerovský program s programom vo vyššom jazyku, rozhoduje o poradí segmentov prekladač vyššieho jazyka. V čistých assemblerovských programoch môžete použiť direktívu DOSSEG, ktorá zoradí segmenty podľa pravidiel Microsoftu: ‘code’, ‘data’, ‘stack’. Toto poradie sa použije tiež pri zjednodušených direktívach. Nasledujúca tabuľka ukazuje implicitné segmentové atribúty, ktoré sa priradia segmentom, ak sme použili zjednodušené segmentové direktívy a pamäťový model small.
Keď deklarujeme segmenty pomocou štandardných segmentových direktív, prekladač nemôže vedieť, ktorý segment obsahuje inštrukcie, ktorý dáta a ktorý zásobník. Preto pomocou direktívy ASSUME alebo pomocou operátora prepisu segmentu musíme prekladaču oznámiť, pomocou ktorých segmentových registrov sú segmenty adresované. Direktíva ASSUME spája segmentové registre s menami segmentov, ale neukladá do segmentových registrov bázové adresy segmentov, to je rovnako ako pri zjednodušených direktívach záležitosť operačného systému (pre segmentové registre CS a SS), resp. programátora (pre ostatné segmentové registre). Direktíva ASSUME so segmentovým registrom CS sa musí objaviť pred prvou inštrukciou programu, aby prekladač vedel, ktorý segment sa má použiť v štartovacej adrese programu, pri skokoch a volaniach procedúr. ASSUME s ostatnými segmentovými registrami sa môže vyskytovať kdekoľvek v programe, ale pred prvým prístupom do daného segmentu. V direktíve ASSUME sa môžu vyskytovať predpokladané priradenia pre jeden alebo viac segmentových registrov. Priradenie segmentov segmentovému registru môžeme v priebehu programu meniť (ak pritom samozrejme zmeníme aj obsah segmentového registra). Pozrime si nasledujúci program:
Data1 SEGMENT
Prem DW ? Data2 SEGMENT
Cislo DW 0 Program SEGMENT Na poslednom príkaze prekladač vyhlási chybu, lebo premenná Cislo je definovaná v segmente Data2, avšak tento segment nie je spojený so žiadnym segmentovým registrom. Chybu hneď napravíme: ASSUME es:Data2mov ax,Data2 mov es,ax mov ax,[Cislo] Teraz je všetko v poriadku. V direktíve ASSUME es:Data2 sme prekladaču oznámili, že segment Data2 je adresovaný pomocou segmentového registra ES a prekladač automaticky doplní prepis segmentu: mov ax,es:[Cislo]Ak budeme pokračovať v príklade, môžeme zmeniť priradenie pre segmentový register DS a naplniť ho bázovou adresou segmentu Data2: ASSUME ds:Data2push es pop ds mov ax,[Cislo] V tomto prípade v poslednej inštrukcii nepotrebujeme prepis segmentu, lebo segmentový register DS sa implicitne používa pri odkazoch na dáta. Pokračujme v príklade a zmeňme obsah registra DS: mov ax,Data1mov ds,ax mov ax,[Cislo] Pretože sme nezmenili priradenie
segmentu segmentovému registru DS, prekladač sa domnieva, že priradenie
ds:Data2 stále platí a pri prístupe k premennej
Cislo použije segmentový register DS, ktorý však
už neobsahuje adresu Data2.
Táto chyba sa prejaví pri vykonávaní programu.
Direktíva zruší priradenie vytvorené poslednou direktívou ASSUME. Direktíva ASSUME segmentový_register:nothingzruší posledné priradenie danému segmentovému registru. Direktíva ASSUME nie je povinná, ale ak ju neuvedieme, musíme pri každom odkaze na pamäť použiť prepis segmentu. |
Načo je vám jazyk symbolických adries?
Architektúra moderných procesorov Segmentové direktívy
Služby operačného systému MS-DOS Služby operačného systému Windows 95/98/NT/XP |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Vydala Žilinská univerzita v Žiline, 2000. ISBN 80-7100-723-4. Otázky a pripomienky môžete poslať autorke. Naposledy upravené 29.10.2007. |