Maradékos osztás assemblyben
2010-09-22T18:28:35+02:00
2010-09-22T20:06:41+02:00
2022-08-02T20:35:28+02:00
Latkóczy Dávid
Üdv!

Maradékos osztást szeretnék csinálni assemblyben, de azt olvastam, hogy ilyen eljárás nincs.
Szóval nekem kellene megírnom.
El is kezdtem, de valamiért nem akar működni.

A terv:
Azt szeretném megvizsgálni, hogy DI-t 320-al osztva 0-át, vagy 1-et kapok -e maradékul. (Az osztás eredménye lényegtelen.)
Algoritmus:
osztó nagyobb vagy egyenlő, mint osztandó? igen: egyenlő? igen maradék = 0 nem osztó = osztó - osztó maradék = osztandó - osztó nem: osztó = osztó + osztó vissza az elejére

A kód:
osztas1: push SI ; SI verembe mov SI,320 ; Osztó: SI push DI ; DI verembe, Osztandó: DI call osztas pop DI ; DI visszaállítása pop SI ; SI visszaállítása ret osztas: cmp SI,DI ; Osztó nagyobb vagy egyenlő mint osztandó? jae nagyobbegyenlo ; Igen: nagyobbegyenlo jmp kisebb ; Nem: kisebb ret nagyobbegyenlo: cmp SI,DX ; Egyenlő? jz egyenlo ; Igen: egyenlo jmp nagyobb ; Nem: nagyobb ret egyenlo: ; Maradék = osztó, tehát mov DX,0 ; maradék = 0 ret nagyobb: mov CX,SI ; osztó = osztó - osztó .ciklus1 dec SI dec CX jnz .ciklus1 ;maradek mov CX,SI ; maradék = osztandó - osztó .ciklus2 dec DI dec CX jnz .ciklus2 ;maradek=DI mov DX,DI ret kisebb: ; osztó = osztó + osztó mov CX,SI .ciklus1 inc SI dec CX jnz .ciklus1 jmp osztas ret

Így próbáltam ki:

grafikus: ; Grafikus mód bekapcsolása mov AX,13h int 10h ; Képernyő beállítása mov AX,0a000h mov ES,AX mov DI,321 call osztas1 call vizsgal mov DI,640 call osztas1 call vizsgal vizsgal: cmp DX,1 jz elso cmp DX,0 jz masodik ret elso: mov byte[ES:2*320+DI],31 ; DI kirajzolása - fehér masodik: mov byte[ES:2*320+DI],40 ; DI kirajzolása - piros

Nem rajzol ki semmit.
Mi a hiba?

Ha valaki tud egy jobb megoldást/rövidebb kódot, annak is örülnék, de érdekel, hogy mit rontottam el.
Mutasd a teljes hozzászólást!
A DIV utasításnak nézz utána. Egészosztást végez, az AX regiszterbe megy a hányados, a DX-be a maradék.
Mutasd a teljes hozzászólást!

  • Pfff
    Valaki mért nem mondta előbb?
    Mindjárt megnézem...
    Mutasd a teljes hozzászólást!
  • Nemnagyon találom:
    Google

    Egyébként létezik online assembly referencia/manual?
    Vagy ez a nyelv nem egységes, több változata is van, és ezért nincs ilyen?

    A DIV-nél mit adok meg paraméternek?
    Így nem jó:
    mov DI,641
    mov CX,320
    DIV DI,CX
    nasmw azt írja, hogy invaild combination of opcode and operands.
    sima DIV-re meg azt írja, hogy byte value exceeds bunds.

    Vagy talán így kellene?
    mov AX,DI
    mov CX,320
    DIV CX
    ; maradek = DX
    ; eredmeny = AX
    Mutasd a teljes hozzászólást!
  • Úgy néz ki, ez jó:

    ; Maradékos osztás

    grafikus:
    ; Grafikus mód bekapcsolása
    mov AX,13h
    int 10h
    ; Képernyő beállítása
    mov AX,0a000h
    mov ES,AX

    mov DI,321
    call osztas
    call vizsgal

    mov DI,640
    call osztas
    call vizsgal

    vizsgal:
    cmp DX,1
    jz elso
    jmp masodik
    ret

    elso:
    mov byte[ES:2*320+DI],31 ; DI kirajzolása - fehér
    ret

    masodik:
    mov byte[ES:2*320+DI],40 ; DI kirajzolása - piros
    ret

    ;***************************************************************

    osztas:
    mov AX,DI
    mov CX,320
    DIV CX
    ; maradek = DX
    ; eredmeny = AX
    ret

    Tiéd a pont, és köszi!

    Tudom, hogy egy téma egy kérdés, de ha valaki rájön, hogy mi a hiba az én kódomban, az legyen szíves, írja meg!
    Mutasd a teljes hozzászólást!
  • Ajánlom figyelmedbe az Intel referenciáit, elsősorban a 2A és 2B köteteket (utasításkészlet-referencia A-M és N-Z). Nem kell végigolvasni az összes utasítást, mert nagyon sok modern illetve speciális van közte.

    Itt van egy másik referencia, talán jobban követhető

    A DIV egyébként úgy működik, hogy egymás mellé rakja a DX és az AX értékeit (a DX lesz a felső helyi értéken), és az így kapott értéket elosztja az általad megadott regiszter értékével. (Tehát csak egy paramétert adsz neki.) Az eredmény megy az AX-ba, a maradék a DX-be. Ha csak 16 bites számot akarsz osztani, akkor kinullázod a DX-et az osztás előtt. Ha az eredmény nem fér el az AX-be (mondjuk mert hetvenezret osztottál eggyel), akkor a programod összeomlik, ezt érdemes elkerülni. Ugyanez a hiba van akkor is, ha nullával akarsz osztani.
    Mutasd a teljes hozzászólást!
  • Szuper! Köszike!
    Mutasd a teljes hozzászólást!
abcd