Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Assembly: Kertotaulu

Sivun loppuun

Antti Laaksonen [01.02.2004 00:40:18]

#

Tässä on kertotaulun tulostava assembly-ohjelma. Kertotaulun suurin luku voi olla 255, koska tavuun ei mahdu enempää. Tärkeässä osassa ohjelmassa on rekisterissä olevan luvun tulostaminen näytölle. Tämä ei nimittäin ole niin helppoa kuin voisi luulla, jos luku on kaksinumeroinen tai pidempi. Ohjelman kommenteissa on kuitenkin selitetty käytetty jakojäännöstekniikka sekä moni muukin asia. Kääntyy TASMilla.

; Kertotaulu, jossa korkein tulo voi olla 255
   ; tekijä Antti Laaksonen, kääntyy TASMilla
   DOSSEG
   .MODEL SMALL
   .STACK 100h
   .DATA
   ; näiden vakioiden avulla valitaan kertotaulun
   ; rivien ja sarakkeiden määrä, suurin sallittu
   ; taulun koko on 15 * 17 tai 17 * 15
KRIV equ 15
KSAR equ 15
   .CODE
   ; ch-rekisteriä käytetään rivilaskurina, minkä
   ; vuoksi sen alkuarvo on 1
   mov ch, 1
sriv:
   ; al-rekisteriä käytetään sarakelaskurina,
   ; jokaisen rivin ensimmäisen sarakkeen luku on
   ; sama kuin rivin numero
   mov al, ch
   ; dl-rekisterin avulla valvotaan, että riville
   ; tulostetaan oikea määrä lukuja
   mov dl, 1
ssar:

   ; -- LUVUN TULOSTAMINEN NÄYTÖLLE -----------------------
   ; Luvun tulostaminen näytölle on hankalaa, jos luku on
   ; kaksinumeroinen tai suurempi. Jotenkin täytyy saada
   ; tietoon luvun yksittäiset numerot. Eräs keino on
   ; käyttää apuna jakojäännöstä: kun luvun jakaa yhä
   ; uudestaan kymmenellä, jakojäännökset muodostavat
   ; käänteisessä järjestyksessä luvun numerot. Esimerkki:
   ;
   ;   178 / 10 = 17, jää 8
   ;    17 / 10 =  1, jää 7
   ;     1 / 10 =  0, jää 1
   ;
   ; Jakaminen lopetetaan silloin, kun osamäärä on nolla.
   ; Numeroiden muuntaminen ASCII-koodiksi tapahtuu lisää-
   ; mällä numeroon luku 48, joka on merkin '0' ASCII-arvo.
   ; ------------------------------------------------------

   ; laitetaan ax-rekisteri talteen pinoon
   push ax
   ; laitetaan cl-rekisteriin jakaja eli 10
   mov cl, 10
   ; bh-rekisterissä lasketaan luvun numeroita
   mov bh, 0
ujako:
   ; div-komennossa jaettava luku on koko ax-rekis-
   ; teri,joten rekisterin vasen puoli täytyy nollata
   mov ah, 0
   ; jaetaan rekisterissä ax oleva luku cl:llä, minkä
   ; seurauksena al on osamäärä ja ah on jakojäännös
   div cl
   ; lukua ei voi tulostaa heti, koska järjestys on
   ; päinvastainen, siksi se laitetaan pinoon
   push ax
   ; kasvatetaan numerolaskuria
   inc bh
   ; jos jakojäännös ei ole nolla, jaetaan luku
   ; uudestaan kymmenellä (al on valmiiksi luvun
   ; jäljellejäänyt osa)
   cmp al, 0
   jne ujako
   ; bl-rekisteriä käytetään laskurina luvun
   ; tulostamisessa (numeroiden yhteismäärä on bh:ssa)
   mov bl, 0
num:
   ; haetaan pinoon viimeksi laitettu luku
   ; ax-rekisteriin (näin numerot tulevat
   ; automaattisesti oikeassa järjestyksessä)
   pop ax
   ; jakojäännös eli tulostettava numero täytyy
   ; siirtää rekisterin oikealle puolelle, koska
   ; tulostusfunktio vaatii näin (ks. jatko)
   mov al, ah
   ; numeron muuttaminen ASCII-koodiksi tapahtuu
   ; lisäämällä numeroon luku 48 (merkki '0')
   add al, 48
   ; merkin tulostus:
   ;   o keskeytys 10h
   ;   o ah = 0eh
   ;   o al = tulostettava merkki
   mov ah, 0eh
   int 10h
   ; kasvatetaan numerolaskuria
   inc bl
   ; jatketaan, kunnes merkkejä on tulostettu yhtä
   ; monta kuin niitä laitettiin pinoon
   cmp bl, bh
   jne num
vali:
   ; tulostetaan välilyönti (ASCII-koodi 32 = 20h)
   mov ax, 0e20h
   int 10h
   ; kasvatetaan edelleen numerolaskuria
   inc bl
   ; jatketaan, kunnes tulostettujen merkkien
   ; yhteismäärä on 4 (sarakkeiden tasaus)
   cmp bl, 4
   jne vali
   ; palautetaan ax-rekisteri pinosta
   pop ax
   ; lasketaan seuraavan sarakkeen arvo, joka määräytyy
   ; suoraan rivinumeron mukaan
   add al, ch
   ; kasvatetaan sarakelaskuria
   inc dl
   ; jatketaan, kunnes seuraava tulostettava sarake
   ; olisi suurempi kuin KSAR-vakion arvo
   cmp dl, KSAR + 1
   jne ssar
   ; laitetaan ax-rekisteri talteen pinoon
   push ax
   ; tulostetaan rivinvaihto sarakkeen jälkeen
   ; (muodostuu merkeistä 13 = 0dh ja 10 = 0ah)
   mov ax, 0e0dh
   int 10h
   mov ax, 0e0ah
   int 10h
   ; palautetaan ax-rekisterin arvo
   pop ax
   ; kasvatetaan rivilaskuria
   inc ch
   ; jatketaan, kunnes seuraava tulostettava rivi
   ; olisi suurempi kuin KRIV-vakion arvo
   cmp ch, KRIV + 1
   jne sriv
   ; suljetaan ohjelma:
   ;   o keskeytys 21h
   ;   o ah = 4ch
   ;  (o al = palautusarvo)
   mov  ah,4ch
   int  21h

   END

jrantala [01.02.2004 10:34:17]

#

Ainakin koodin kommentointia on riittämiin :)

KimmoKM [01.02.2004 10:36:16]

#

Kiva saada lisää Assemblyä.

sooda [01.02.2004 10:52:25]

#

antti on ruvennut näköjään asmaamaan oikein kunnolla :)

tejeez [01.02.2004 18:16:04]

#

Melko pitkä koodi mut asmillahan tulee monesta asiasta melko pitkää :)

tejeez [01.02.2004 18:16:33]

#

Oho, eipä olekaan mikään hirveän pitkä, tuossahan onkin kommentteja todella paljon :P

nomic [23.05.2004 04:56:41]

#

loistava :)

Fisher [09.10.2004 19:36:38]

#

toi kääntyy emu8086sella jos laittaa tohon endin tilalle ret ja ton

DOSSEG
   .MODEL SMALL
   .STACK 100h
   .DATA
   ; näiden vakioiden avulla valitaan kertotaulun
   ; rivien ja sarakkeiden määrä, suurin sallittu
   ; taulun koko on 15 * 17 tai 17 * 15
KRIV equ 15
KSAR equ 15
   .CODE
   ; ch-rekisteriä käytetään rivilaskurina, minkä
   ; vuoksi sen alkuarvo on 1
   mov ch, 1
sriv:
   ; al-rekisteriä käytetään sarakelaskurina,
   ; jokaisen rivin ensimmäisen sarakkeen luku on
   ; sama kuin rivin numero

jutskan laittaa

#make_COM#


ORG 100h

jmp start:
   ; näiden vakioiden avulla valitaan kertotaulun
   ; rivien ja sarakkeiden määrä, suurin sallittu
   ; taulun koko on 15 * 17 tai 17 * 15
KRIV equ 15
KSAR equ 15
   start:
   ; ch-rekisteriä käytetään rivilaskurina, minkä
   ; vuoksi sen alkuarvo on 1
   mov ch, 1
sriv:
   ; al-rekisteriä käytetään sarakelaskurina,
   ; jokaisen rivin ensimmäisen sarakkeen luku on
   ; sama kuin rivin numero

Fisher [09.10.2004 19:39:09]

#

tiedän kyllä että sanotte "no tonhan osaa lapsikin, se on noin simppeli", mutta laitoin kuitenkin

tejeez [27.12.2004 08:58:09]

#

Ai toi on ollu pitkä mun mielestä? Aha, olinpa outo joskus.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta