Obsah    Kapitoly: 12345678,  |  X.1X.2X.3X.4,  |  Y1 Y2 

7) Práce se zásobníkem

Co je to vlastně zásobník? Je to vlastně segment v paměti, do kterého si můžete odkládat data. Na tento segment ukazuje segmentový registr SS (Stack Segment - viz kapitola 2) a na aktuální pozici tohoto zásobníku ukazuje registr SP (Stack Pointer). Kompletní adresa je tedy SS:SP. Známe dva druhy zásobníků LIFO (Last In First Out - "Poslední dovnitř a první ven) a FIFO (First In First Out - První dovnitř a První ven). Tento trochu nesrozumitelný popis zásobníku je ve své podstatě velmi jednoduchý.

Představme si, že data, která vkládáme do zásobníku jsou lidé. Typickým zásobníkem LIFO by tedy byl plný autobus. Lidé, kteří do autobusu vejdou jako poslední z něj mohou vystoupit jako první, zato ti, co nastoupili první, musí počkat, až všichni před nimi vystoupí, aby mohli odejít.

Na druhou stranu zásobníku FIFO by mohla být obyčejná fronta u přepážky na poště. Lidé, co dříve přišli, budou dříve odbaveni, a tedy i dříve odejdou. Stejné je to i s daty v zásobníku. Máme-li zásobník typu LIFO, data uložená poslední, budou první, která ze zásobníku přečteme.

Zásobník, který používáme v assembleru je typu LIFO. Je to velmi jednoduchý, ale také velmi užitečný systém. Tak například mám proceduru, která volá svoji podproceduru. Takže si nejdříve uložím data procedury do zásobníku, poté v podproceduře různě pracuji s daty, a když se vrátím do původní procedury, mám data procedury hezky "po ruce" na vrcholu zásobníku.

Do tohoto zásobníku se ukládají data "odshora", to znamená, že prázdný zásobník má SP nejvyšší. Při každém uložení čísla se SP zmenšuje o příslušný počet bitů, aby vždy ukazoval na poslední uložené číslo. (Při uložení hodnoty Word se sníží o dva.) Jako byste na jakýsi provaz visící ze stropu dolů zavěšovali balíčky(data). Poslední balíček je nejníže a zároveň jej musíte první vybrat.

Instrukce, které na zásobník ukládají a vybírají data jsou PUSH a POP.

  • Instrukce PUSH

    Volně přeloženo "narvi data do zásobníku". Můžete tam uložit 16 nebo 32bitové číslo. Několik instrukcí PUSH za sebou lze psát v jedné řádce.
    Syntaxe:
    PUSH < Co >
    Příklady:
    PUSH AX - ulož AX
    PUSH AX BX CX - ulož AX, BX a CX


    Ve skutečnosti tato instrukce provede následující operace:

    SUB SP, velikost < co >	; odečti od SP velikost argumentu < co >
    MOV SS:[SP], < co >
    

  • Instrukce POP

    Tato instrukce naopak vybere 16 nebo 32bitová data ze zásobníku a uloží je do svého argumentu. Stejně jako u PUSH lze psát více argumentů do řádky.
    Syntaxe:
    POP < kam >
    Příklady:
    POP AX -> načti do AX
    POP AX BX CX -> načti do AX, BX a CX


    Ve skutečnosti provádí:

    MOV < kam >, SS:[SP]
    ADD SP, velikost < kam >	; přičti SP velikost argumentu < kam >

    pozn.: S instrukcemi PUSH a POP jste se už setkali v kapitole
    05 - Vzhůru k dalšímu programu .

  • Instrukce PUSHA (PUSH all)

    Tato instrukce provede současné uložení registrů AX, BX, CX, DX, SI, DI, BP, SP. Není to samé co PUSH AX BX CX DX SI DI BP SP, ale jedná se o plnohodnotnou instrukci procesoru.
    Syntaxe:
            PUSHA        
  • Instrukce POPA (POP All)

    Opak PUSHA.
    Syntaxe:
            POPA        
  • Instrukce PUSHF

    Instrukce uloží obsah registru FLAGS (bity 0..15) jako Word na zásobník.
    Syntaxe:
            PUSHF        
  • Instrukce POPF

    Instrukce přečte obsah Wordu na vrcholu zásobníku a uloží jej do registru FLAGS (bity 0..15). Syntaxe je obdobná.
    Syntaxe:
            POPF        


    Předchozí kapitola Nahoru Následující kapitola