Aktív témák

  • kisfurko

    senior tag

    válasz OddMan #34 üzenetére

    ''Létezik egyáltalán olyan debugger, amit lehetne használni?''
    A probléma ott van, hogy védett módba csak valós módból lehet átkapcsolni, így csak olyan debuggert használhatsz, ami valós módú. De mivel átkapcsolsz, a szegmens regiszterek új értelmet nyernek, azokhoz kellene a megfelelő GDT stb. Ráadásul az interruptokat is engedélyezi (hiába volt cli, az csak virtuálisan, a programod szempontjából érvényes). A turbo debugger meg amúgy is elég béna (kicsi, valós módú programokhoz jó).
    Én úgy csináltam, hogy stack-re mentettem az engem érdeklő regiszetereket, majd vissza valós módba, ott pedig szépen, kényelmesen kibányásztam a védett módú stack helyéről a számokat.
    Az IDT az egy nagy tömb, felépítését tekintve olyan, mint a GDT. Ugyanúgy kell beállítani, mint a GDT-t (lidt). A bejegyzések szintén 8 byte-osak. Egy bejegyzés így néz ki:

    dw offszet also 16 bitje
    dw szelektor
    db 0 ; ez igazabol csak 5 bites, ez azt mondja meg, hogy call gate eseten hany dwordot (wordot) kell a ket kulonbozo szint verme kozott masolni (mert minden szintnek sajat verme van)
    db 0 ; a tipust es a priv. szintet adja meg, ugyanugy mint egy deszkriptornal. A tipus ertekei a kovetkezok lehetnek:
    ; 4 286 call gate
    ; 5 386 task gate
    ; 6 286 interrupt gate
    ; 7 286 trap gate
    ; 12 386 call gate
    ; 14 386 int gate
    ; 15 386 trap gate
    dw 0 ; offszet felso 16 bitje

    Szóval, baromira hasonló, de itt nem bázis és határ van, hanem szelektor és offszet. Ez a címe a kiszolgáló rutinnak, ide ugrik, a valós módban csak szelektor és offszet van pl. A típust állítsd interrupt gate-re (14)!

    A kivételek listája:

    0 osztás hiba
    1 debug trap
    2 NMI
    3 int3 utasítás
    4 into utasítás
    5 bound hiba
    6 érvénytelen utasítás
    7 device not available (taszkváltásnál kell, vagy koprocesszor emulációnál)
    8 double fault (hiba amikor éppen hibát szolgálsz ki)
    10 érvénytelen TSS
    11 szegmens nem aktív (a P bitje 0)
    12 stack hiba
    13 általános hiba (ez kell nagyon :DD)
    14 lapozási hiba
    16 FPU hiba
    Meg még van egy pár, de ezek a legfontosabbak. A 9-es és 15-ös nem maradt ki, az nincs. A legegyszerűbb, ha csinálsz egy 32 elemű IDT-t, az lefedi az összes (akár jövőbeni) kivételt. Ahogy ajánlottam feljebb, az összes rutin csak annyi, hogy beteszed a számát a kivételnek a verembe, majd ugrasz a közös rutinra. Érdemes a verembe piszmogni, mert amikor a kiszolgálóra jut a vezérlés, akkor csak az ''áll készen'', hiszen a szegmens regiszterek ismeretlen értéket tartalmaznak (és a CS nem írható). Vagy benyomatod a verembe a DS-t, majd szabad a pálya. Mindenképpen 0-ás priv. szint kell a kiszolgáláshoz (természetesen a cél CS-nek is 0-ás szintűnek kell lennie)! Persze az int3, into lehet alacsonyabb szinten, ott azt jelenti, hogy melyik a legalacsonyabb szint, ahol végrehajtható az utasítás.

    Van még egy lényeges dolog. Lehet, hogy tudsz róla, lehet, hogy nem. Amikor átváltasz másik módba, akkor a szegmensek megőrzik a régi tartalmukat. De itt ne csak a számra gondolj, amit betöltöttél, hanem azokra az értékekre, amit a deszkriptorban állítani tudsz (valós módban is ugyanúgy működik a határ ellenőrzés pl.). Hogy ez ne okozzon gondot, átváltás után szükség van egy szegmensközi ugrásra (far jmp pl.). Ha vissza is akarsz váltani, akkor szükséged lesz egy olyan deszkriptorra, ami egy valós módú szegmenst ír le. 64k-s határral, 16 bites móddal, 0-ás priv. szinttel. Lehet, hogy a fajtáját is be kell állítani, már nem emlékszem, hogy én hogyan csináltam.
    Kiváncsian várom a fejleményeket!

Aktív témák