Práce se zásobníkem v Assembleru - 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

Práce se zásobníkem v Assembleru

asm

7. prosince 2001, 00.00 | Zásobník je jedna z nejdůležitějších struktur, kterou v assembleru využíváme. Slouží k ukládání a obnově hodnot registrů. To využíváme při volání procedur, přerušení, předávání parametrů procedurám či k prostému uchování hodnot registrů..

1.0 Zásobník - úvod
Zásobník je jedna z nejdůležitějších struktur, kterou v assembleru využíváme. Je založen na principu LIFO (Last In, First Out), tedy co je vloženo jako poslední je k dispozici jako první. Zásobník slouží k ukládání a obnově hodnot registrů. To využíváme při volání procedur, přerušení, předávání parametrů procedurám či k prostému uchování hodnot registrů. Bázová adresa segmentu zásobníku je uložena v registru SS, v registru SP je uložen offset-posun oproti bázové adrese. Těchto registrů potom využíváme k přístupu k datům uloženým v zásobníku. Data jsou v něm ukládána od nejvyšší adresy směrem „dolů“. Zásobník může být deklarován v samostatném segmentu nebo v rámci jednoho segmentu s daty a kódem (COM soubor).

1.1 Instrukce PUSH a POP
Ke vkládání dat do zásobníku slouží instrukce PUSH. Tato instrukce sníží obsah registru SP (SP ukazuje na vrchol zásobníku) o dvě a pokud ukládáme šestnáctibitovou hodnotu tak na adresu SS:SP uloží tuto hodnotu. Pro výběr dat ze zásobníku slouží instrukce POP, ta nejprve naplní 16-bitový operand obsahem paměťové buňky na adrese SS:SP a potom zvýší obsah registru SP o dvě. Registr SP potom ukazuje na další hodnotu v zásobníku.

1.2 COM soubor
Už víme, že v tomto typu souborů je zásobník součástí jednoho segmentu, ve kterém je uložen celý program. Tedy SS=CS. Počáteční obsah registru SP je FFFEh.




1.3 EXE soubor
V EXE souboru se zásobníku vyhradí libovolně veliký prostor ohraničený velikostí 64kB. Umístění segmentu v paměti neřídí programátor, paměť je mu přidělena OS. V příkladu jsme si delkarovali zásobník o velikosti 32h*2 bajtů = 64h (100dec) bajtů. Instrukce PUSH sníží obsah SP na 0062h, příčemž na adresu SP:0063h uloží obsah horní poloviny (AH) registru AX, tj. hodnotu FFh a na adresu SP:0062h uloží číslo EEh.




exSTACK SEGMENT STACK ;segment zasobniku exSTACK
ASSUME SS:exSTACK
db 32h dup(0cdh,21h) ;velikost zasobniku
exSTACK ENDS
exCODE SEGMENT ;zacatek segmentu exCODE
ASSUME CS:exCODE,DS:exCODE
start:
MOV ax, 0FFEEh
PUSH ax
MOV ax, 0000h
POP ax
MOV ah, 4ch
MOV al, 00h
INT 21h
exCODE ENDS
END start

1.4 Další instrukce
PUSHF,POPF - uložení ,resp.vyjmutí příznakového registru ze zásobníku (push flags)
PUSHA,POPA - uložení, reps. vyjmutí osmi šestnáctibitových registrů ze zásobníku. Registry jsou uloženy v pořadí (AX,BX,DX,BX,BP,SP,DI). SP se sníží o 8*2=16. Výběr je prováděn pochopitelně v opačném pořadí tj. od DI k AX. Instrukce je obsažena až v instrukčním repertoáru procesoru 286.

2. Podprogram (subrutine)
Podprogram (budeme používat slovo procedura) je skupina instrukcí, které se často využívají a proto by bylo zbytečné je do programu neustále vpisovat. Jsou volány jako samostatná část programu. Taková prodcedure je uzavřena mezi dvojici direktiv PROC a ENDP:
Název procedury PROC
;Tělo procedury
RET
Název procedury ENDP
Procedura je protom z programu volána instrukcí CALL. Tako instrukce zajisí uložení návratové adresy (adresa instrukce, která následuje za CALL) na zásobník a skok na adresu příslušné procedury, tím je řízení programu předáno proceduře. Na konci těla procedury musí být umístěna instrukce RET, která zajisí vyjmutí návratové adresy ze zásobníku a uložení její hodnoty do registru IP, tj. předá řízení programu, který proceduru volal. Podívejme se na následující příklad:
prSTACK SEGMENT STACK
ASSUME SS:prSTACK
db 32h dup(0cdh,21h)
prSTACK ENDS
prCODE SEGMENT
ASSUME CS:prCODE,DS:prCODE
start:
CALL NicNedelam
MOV ah, 4Ch
MOV al, 00h
INT 21h
NicNedelam PROC
MOV ax,0
RET
NicNedelam ENDP
prCODE ENDS
END start
Nejdříve je zavolána instrukcí CALL procedura NicNedelam, tzn. že do zásobníku je uložena adresa následující instrukce (návratová adresa), protože program začíná na adrese CS:00, je tam umístěna hodnota 0003h, což je adresa instrukce MOV ah, 4ch. Protože zásobník má velikost 64h bajtů je návratová adresa uložena na adrese SS:0062h. Do registru IP se přiřadí adresa první instrukce procedury, vykoná se tělo procedury a na konci instrukce RET, vyjme ze zásobníku návratovou adresu 0003h a umístí ji do registru IP, čímž předá řízení opět hlavnímu programu. Procedura je v segmentu umístěna až za volání služby 4Ch instrukce INT 21h, která ukončí program. Modifikujme proceduru následujícím způsobem:
NicNedelam PROC
MOV ax,4h
push ax
RET;
NicNedelam ENDP
V takovém případě dojde k chybě programu, protože instrukce RET předpokládá, že na vrcholu zásobníku je připravena návratová adresa, místo ní ale vyjme ze zásobníku číslo 4h, což je adresa jiné instrukce, tím pádem dojde ke zhroucení nebo špatné činnosti programu.

2.1 Vzdálené volání
Proceduru lze také definovat v jiném segmentu, potom je nutné za direktivu PROC uvést ještě slovo FAR a pro návrat z procedury je nutné požít instrukci RETF. Pro návrat do programu, který volal proceduru z jiného segmentu je nutné do zásobníku uložit nejen obsah registru IP, ale také obsah segmentového registru CS v pořadí PUSH CS, PUSH IP.
prSUBR SEGMENT
NicNedelam PROC FAR
RETF;
NicNedelam ENDP
prSUBR ENDS


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: