Virtuális gomb megnyomásának vizsgálata
2010-10-28T20:18:46+02:00
2010-10-29T15:54:43+02:00
2022-08-03T01:10:31+02:00
Latkóczy Dávid
Üdv!

Arra gondoltam, hogy a téglalaprajzoló szubrutinból csinálhatnék egy gombmegnyomós progit.
Az elképzelés az, hogy enter megnyomása esetén megvizsgálom a kurzorpozíciót, hogy rajta van -e az előzőleg rajzolt négyzeten. Ehez ugyanúgy végigmegyek a négyzet képpontjain, mint a kirajzoláskor, csak itt rajzolás helyett megvizsgálom a kirajzolt képpontot, és a kurzorpozíciót, hogy egyenlőek -e.

... gombrajzolo: pusha mov dx,bx mov si,320 .cikl1: mov [es:di+bx],al sub bx,1 jnc .cikl1 mov bx,dx add di,si loop .cikl1 popa ret gomb: pusha mov al,3 mov si,di mov di,321 ; kezdo pont cime mov bx,10 ; szellesseg mov cx,10 ; magassag call vizsgalat1 popa jmp olvas vizsgalat1: pusha mov dx,bx mov si,320 .cikl1: mov [es:di+bx],al ; hogy látszódjon is valami push di add di,bx cmp di,si ; logikai vizsgálat jz megnyomva pop di sub bx,1 jnc .cikl1 mov bx,dx add di,si loop .cikl1 popa ret megnyomva: jmp kilepes ...

Ez nem képpontonként rajzol, ezért van a di+bx.
De nem működik.
Mi a baj vele?
Mutasd a teljes hozzászólást!
Na itt több gond is van. Fontossági sorrendben:

1. Nem kell ciklus ahhoz, hogy meg tudd mondani, egy pont egy téglalapon belül van-e. Elég hozzá négy darab hasonlítás. Ha ilyesmivel nem vagy tisztában, akkor ne assemblyvel próbálkozz, hanem C-vel vagy Pascallal. Az alapokhoz azok is jók, és nem kell közben floppyt formáznod se.
2. A kódod alapján az SI-ben jön a koordináta, amivel hasonlítasz. A gond csak az, hogy egyből felülcsapod a kezdéskor 320-szal, mert a másik kód az SI-t még a képernyő szélességéhez használta. Gondold át, melyik regiszterben mi van, és írd át a kódot úgy, hogy ne legyen ütközés.
3. Az sose egészséges, ha lepakolsz dolgokat a veremre, aztán takarítás nélkül kiugrasz a ciklusból. Amikor a "megnyomva" címkére ugrasz, a vermen van (felülről lefelé) a DI lementett értéke, egy PUSHA által mentett regiszterhalmaz, a CALL utasítás által mentett visszatérési érték, és még egy PUSHA-mentés. Ha ezeket nem veszed le a veremről (legalább annyival, hogy a megfelelő konstanst hozzáadod az SP-hez), akkor jobb esteben memóriát pazarolsz, rosszabb esetben összeomlik a program.

Ha ragaszkodsz az assemblyhez, próbáld meg előbb magas szintű nyelven megírni, és azt átvinni asm-be. A magas szintű kódban jobban átlátod, hogy mit csinálsz, és jobban megtalálod a hibákat.
Mutasd a teljes hozzászólást!

  • 1. Persze, de nem egyszerűbb 2 ciklust írni, mint 4 összehasonlítást? És a pozíciók nincsenek x,y-ra bontva.
    teglalap teteje > DI(x)
    teglalap alja < DI(x)
    teglalap baloldala < DI(y)
    teglalap jobboldala > DI(y)
    Esetleg leírhatnád, hogy te hogyan csinálnád?
    (Nem forráskódra gondolok, lépések / alguritmus leíró nyelv)

    2. Ha si-t nem használom, helyete mov di,320 jó?
    3. Na erre aztán tényleg nem gondoltam, pedig milyen igazad van!

    Nekem ez kihívást jelent. Pont ezért kezdtem el assemblyvel foglalkozni a php és a visual basic után.
    Tudom, hogy még nagyon béna vagyok, de remélhetőleg nemsokára belejövök! Sok assembly könyvet olvasok, és sokat gyakorolok.
    Mutasd a teljes hozzászólást!
  • Persze, de nem egyszerűbb 2 ciklust írni, mint 4 összehasonlítást?

    Még ha egyszerűbb is, akkor is lassabb (négyzetes idő vs. konstans idő).
    És a pozíciók nincsenek x,y-ra bontva.

    Hmm, jogos, ezt nem is figyeltem. Az x,y koordinátákat maradékos osztással lehetne kinyerni, ami lassú, de annyira talán mégse, mint száz összehasonlítás. (És a száz összehasonlítás még csak egy kis 10x10-es téglalap esetén van. Egy 100x100-as téglalapnál már tízezer összehasonlításról beszélünk.)

    Ha si-t nem használom, helyete mov di,320 jó?

    Nem, mert a DI az aktuálisan vizsgált képpont koordinátáját tárolja. Mondom, ha másképp nem megy, írd le egy papírra az összes regisztert, és írd melléjük, hogy melyiknek mi a dolga a függvényben. Így egyből látszani fog, hogy mi maradt szabadon. Bár ebben a konkrét esetben a 320 konstans érték, nem is kéne hozzá regisztert használni. Egyszerűen adhatnál 320-at a DI-hez a ciklus végén, ahelyett hogy az SI-t adod hozzá.
    Mutasd a teljes hozzászólást!
  • x,y kiszámítást már csináltam egy másik progiban.
    Ezen a négyzetes idő dolgon elgondolkodtam...
    Tényleg sokkal értelmesebb lenne, mint összehasonlítást csinálni.

    Jah, persze, én is erre gondoltam, csak véletlenül "add di,si" helyett "mov di,si"-t írtam.

    Akkor most kipróbálom, hogy kijavítva működik -e ez a kód, aztán nekiállok az általad leírt megoldás kódolásának.

    Ha kész, megírom, mire jutottam!
    Mutasd a teljes hozzászólást!
  • Ez működik
    Köszi, adom a pontot!
    Mutasd a teljes hozzászólást!
abcd