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
Ainakin koodin kommentointia on riittämiin :)
Kiva saada lisää Assemblyä.
antti on ruvennut näköjään asmaamaan oikein kunnolla :)
Melko pitkä koodi mut asmillahan tulee monesta asiasta melko pitkää :)
Oho, eipä olekaan mikään hirveän pitkä, tuossahan onkin kommentteja todella paljon :P
loistava :)
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
tiedän kyllä että sanotte "no tonhan osaa lapsikin, se on noin simppeli", mutta laitoin kuitenkin
Ai toi on ollu pitkä mun mielestä? Aha, olinpa outo joskus.
Aihe on jo aika vanha, joten et voi enää vastata siihen.