ASM - DOS/COM - 64K lokális változó
2012-08-14T21:32:57+02:00
2012-08-15T19:15:51+02:00
2022-08-16T18:55:34+02:00
dzsungelharcos
Sziasztok!

Kérnék egy kicsi oldalba billentést:
Én egy kezdő ASM nebuló vagyok, szóval ha magyarázat is jön azt külön köszönöm!

Szóval szeretnék a stack-en lefoglalni 64Kb memoriát (de ha nagyon tudod legyen inkább 2x64Kb) azt bejárni, módosítani.

Itt találtam egy példát ami működik is, rendszerhívásokkal:
A memória kezelése - Cikkek - Prog.Hu

De én egyszerűen rendszer hívás nélkül szeretném megoldani, valahogy így:

push ebp move ebp, esp sub esp, 0FFFFh lea edi, [ebp - 0FFFFh] mov ecx, 3FFF mov eax, 0CDCDh rep stosd
(Ezt egy C program assembly változata alapján próbáltam meg, de ez most így ebben a formában nem működ)

Én arra tudok gondolni, hogy valamelyik szegmens regisztert kellene beállítanom, de fogalmam nincs sajnos az milyen utasítással kell vagy egyáltalán, hogy álljak neki.

Nasm -ot használok, ha ez számít.
(Esetleg valaki megtudná mondani, hogy a .bss szekció hogy működik COM fájloknál, ha oda vennék fel 2 64Kb-os inicializálatlan adat területet, akkor hogy tudnám őket elérni?)



Köszi!
Mutasd a teljes hozzászólást!
A com fájlnak elméletben stackel együtt bele kell férnie egy szegmensbe. Természetesen megpróbálhatod átírni a stack segmenst, de akkor meg egy teljesen ismeretlen memóriaterületet fogsz használni, valamit felülírsz, védett módú oprendszer meg egyből kilő, mert nem a saját helyedre írtál.
A .bss az inicializálatlan adatterület. Ennek is bele kell férnia a 64k-ba.
Azaz a stacked mérete = 64k-futtatható kód - adat; ez sose lesz nagyobb, mint 64k.
Mutasd a teljes hozzászólást!

  • Ezt így most azt hiszem sikerült működésre bírnom:

    org 100h section .text start: push es push edi les edi, [buffer] cld mov ecx, 4000h mov eax, 10101010h rep stosd pop edi pop es mov ax,4c00h int 21h section .data section .bss buffer: resb 65536
    Mutasd a teljes hozzászólást!
  • A com fájlnak elméletben stackel együtt bele kell férnie egy szegmensbe. Természetesen megpróbálhatod átírni a stack segmenst, de akkor meg egy teljesen ismeretlen memóriaterületet fogsz használni, valamit felülírsz, védett módú oprendszer meg egyből kilő, mert nem a saját helyedre írtál.
    A .bss az inicializálatlan adatterület. Ennek is bele kell férnia a 64k-ba.
    Azaz a stacked mérete = 64k-futtatható kód - adat; ez sose lesz nagyobb, mint 64k.
    Mutasd a teljes hozzászólást!
  • DOS-ban nem foglalhatsz 64KB-t a vermen, mert az egész verem max akkora. Fejlessz win32/command prompt-hoz, az is olyan, mint a DOS, csak más.
    Mutasd a teljes hozzászólást!
  • Ohh, akkor "rosszul" olvastam eddig, minden oldalon valahogy úgy írták, hogy a com fájl mérete nem lehet nagyobb 64K-nál, de akkor így már világos, hogy ezt úgy kell érteni, hogy betöltés után sem lehet nagyobb.
    Mutasd a teljes hozzászólást!
  • Erről szó sincs, a COM is használhatja a DOS memóriafoglaló műveleteit: alloc, free, realloc

    Szerk: Sőt, az allocnál írt komment szerint a COM-nak a DOS eleve lefoglalja a lehető legnagyobb szabad blokkot. Jó kérdés, hogy ennek méretéről hogyan lehet tájékozódni.

    Szerk: A PSP 02-03-as byte-jait kellene megnézni.
    Mutasd a teljes hozzászólást!
  • Igen, erről írt ez a prog.hu-s cikk is:
    A memória kezelése - Cikkek - Prog.Hu

    (Itt mondjuk nem a PSP-t vizsgálja, hanem csak újra allokálja a memóriát)

    De az szerinted is helyes, hogy a stack-en is csak egy szegmensnyi helyem lehet maximum? Ha további memóriára van szükségem akkor kell a DOS memória kezelését igénybe vennem?
    Mutasd a teljes hozzászólást!
  • De az szerinted is helyes, hogy a stack-en is csak egy szegmensnyi helyem lehet maximum?


    Egyértelműen. A stack az a memóriaterület, aminek a "teteje" (a legkisebb használt cím) az SS:SP címen van, az "alja" (a legnagyobb használt cím) pedig valahol az SS által megadott szegmensben. (A CPU-t nem érdekli, hol a verem alja. Ha alulcsordítod a vermet, így jártál, nincs rá külön ellenőrzés.) Ebből következik, hogy maximum egy szegmensnyi méretű lehet a stack-ed.

    Az viszont nem tilos, hogy "stacket válts", vagyis más értékeket tölts az SS és SP regiszterekbe. Az egyetlen cseles rész a dologban, hogy ha később vissza szeretnél váltani az előző stackre, akkor el kell menteni az SS és SP régi értékeit. Mondjuk az új verem legaljára lemented a régi verem adatait abban a függvényben, ami stacket vált, és amikor ugyanez a függvény visszatérésre készül, az új verem legaljáról kiveszi az SS-be és SP-be a régi értékeket. Tehát ezzel a trükkel egy stack-igényes függvény csinálhat magának egy átmeneti saját stacket, amit az általa meghívott függvények is használni fognak.

    Én a helyedben, mielőtt ilyennek nekiállok, átgondolnám, hogy nem lehet-e egyszerűbben megoldani a feladatot. Nem lehet esetleg átírni a kódot, hogy a heap-ről foglaljon memóriát a stack helyett? Vagy nem lehet átállni valami védett módú megoldásra, ahol nem kell szerencsétlenkedni 64KB-os szegmensekkel és 16 bites regiszterekkel?
    Mutasd a teljes hozzászólást!
  • Ezt nagyon köszönöm, teljesen helyre tetted a "memóriám".

    Amúgy a feladat csak annyi, hogy csináltam egy egyszerű effektet processingben, amit most szeretnék átültetni ASM-re, hogy eltudjam indítani azt a function 2012-es demoscene-en a 256byte kategóriában.

    Szóval persze alternatíva van, valószínűleg a heap vagy a video ram flipeltetése lesz, csak így kezdőként próbáltam számomra egyszerűsíteni, és az sem eltitkolt célom, hogy én ezt tudjam is ez most nem jött össze, de nem baj, jön a következő lehetőség.

    Mutasd a teljes hozzászólást!
abcd