Eli.. Olen väsäillyt tässä kelloa asmilla, ja luulin sitä aluksi helpoksi, mutta vastaan tulikin yllättäviä ongelmia. Sain ohjelman kuitenkin toimimaan, mutta jouduin karsimaan muista ominaisuuksista.
Eli tässä olisi toimiva koodi:
org 100h klo: db 'xx.xx.xx',0Dh,'$' ; Varataan muistista tilaa kellonajan tallentamiseseen. kello: ; Itse kellon silmukka. mov AH,2Ch ; Luetaan kellonaika. int 21h ; mov DL,0Ah ; Tallennetaan jakaja (10d) rekisteriin DL. xor BX,BX ; Nollataan rekisteri BX. mov BL,CH ; Siirretään tunnit rekisteriin BL... mov AX,BX ; Ja jatketaan kuin sekuntienkin käsittelyssä... div DL ; add AH,30h ; add AL,30h ; mov [klo],AL ; Ja tallennetaan muistiin... mov [klo+1d],AH ; Kuin myös... mov BL,CL ; Minuttien käsittely... mov AX,BX ; div DL ; add AH,30h ; add AL,30h ; mov [klo+3d],AL ; Ja tallennetaan muistiin... mov [klo+4d],AH ; Kuin myös... mov BL,DH ; Siirretään sekunnit rekisteriin BL. mov AX,BX ; Ja edelleen rekisteriin AX jakamista varten. div DL ; Ja sitten jakolasku... 10 jakaessa pystytään erottamaan kymmenet ja ykköset. add AH,30h ; Lisätään molempiin numeroihin 30h, silloin saadaan numeroa vastaava ASCII-merkki. add AL,30h ; Toisen numeron käsittely... mov [klo+6d],AL ; Ja tallennetaan muistiin... mov [klo+7d],AH ; Kuin myös... mov DX,klo ; Siirretään DX:ään klo:n muistiosoite. mov AH,09h ; Ja sitten tulostetaan ruudulle kellonaika. int 21h ; jmp kello ; Jatketaan. mov AH,08h ; Lopussa odotellaan näppäimenpainallusta. int 21h ; Vaikka ohjelma ei ikinä tänne asti pääse.. mov AH,4Ch ; Ja suljetaan ohjelma. int 21h ; Vaikka ohjelma ei ikinä tänne asti pääse..
(Anteeksi pitkähkö koodi tänne :P)
Ensimmäinen ongelma tulee, kun lisää muuttaa kohdan
klo: db 'xx.xx.xx',0Dh,'$' ; Varataan muistista tilaa kellonajan tallentamiseseen.
muotoon
klo: db 'Kello on xx.xx.xx',0Dh,'$' ; Varataan muistista tilaa kellonajan tallentamiseseen.
(Ja silloin muutan kyllä muistiosoitteet, joihin kirjoitetaan edempänä koodissa)
Kun tekstiin lisää tuon "Kello on..." kohdan, kone heittää herjan komentorivillä "Jaon ylivuoto" (Divide overflow toisella koneella).
xx.xx.xx toiselle puolelle voi kyllä lisätä niin paljon tekstiä.
Toinen ongelma on se, miten tehdä ohjelmaan ajastin, jolloin se poistuu silmukasta esim. minuutin kuluttua. Olen sitäkin varten kaikenlaista yrittänyt väsätä, mutta mikään ei ole tuntunut toimivan. En ole onnistunut lukemaan muistiin tallennettua lukuarvoa muistista sen vertailua varten
(cmp luku muistista,nyk.kellonaika)
PS. tietääkö kukaan keskeytystä & funktiota, jonka avulla ko. silmukasta hypättäisiin pois kun jotain näppäintä painetaan, kuitenkin niin, ettei ohjelman suoritus keskeydy napin painallusta odotellessa?
Siis selkokielellä: sammuttaa ohjelman kun painetaan esim. k:ta, sitä odotellessa pyörittäisi silmukkaa.
Kääntyy ainakin NASM:lla komentorivikomennolla
nasm kello.asm -fbin -o kello.com
Kiitos jo etukäteen
Jostain syystä elän sellaisessa kuvitelmassa, että ohjelman pitäisi alkaa koodilla. Nyt käsittääkseni ohjelmasi suoritus alkaa noista datatavuista, jolloin on melkoinen ihme, jos se toimii yhtään mitenkään. Jospa lisäisit aivan alkuun rivin "jmp kello". Voi toki olla, että näihin DOS-ohjelmiin liittyy asioita, joista en tiedä mitään.
Tosiaan alussa pitää hypätä dataosuuden yli, tai toinen vaihtoehto on laittaa data ohjelman loppuun.
Korvaa lopun hyppykomento tällä, niin mikä tahansa näppäin sulkee ohjelman.
mov ah, 01h int 16h jz kello
Jos lisäät vielä äskeisen perään tämän, näppäin ei vaikuta komentoriviin.
mov ah, 00h int 16h
Jos lisäät edellä olevien perään tämän, vain tietty näppäin sulkee ohjelman.
cmp ah, 25h jne kello
Tässä 25 on K-näppäimen scan-koodi, ja muut ovat osoitteessa:
http://heim.ifi.uio.no/~stanisls/helppc/
Samassa paikassa on tietoa keskeytyksistä:
http://heim.ifi.uio.no/~stanisls/helppc/int_16-0.html
http://heim.ifi.uio.no/~stanisls/helppc/int_16-1.html
Täytyypä kokeilla noita :) Tuosta datan loppuun sijoittamisesta vielä sen verran, että kun laitan tuon kentän klo ohjelman loppuun, tulee valitus "Jaon ylivuoto´" (tai se divide overflow, riippuu koneesta).
Ja osaisiko joku neuvoa, miten voin lukea muistista sinne sijoitetun lukuarvon esim. vertailua varten?
Lukeminen tapahtuu aivan samalla tavalla kuin kirjoittaminen, teet vain asiat käänteisesti: mov eri päin, sitten vähennys (30h).
Minulla koodi toimii varsin hyvin, kun tuon klo-osan siirtää loppuun. Tekstiä saat helpoiten lisättyä näin:
teksti: db 'Kello on ' tunnit: db 'xx' db '.' minuutit: db 'xx' db '.' sekunnit: db 'xx' db 0x0d, '$'
Kirjoitin lopunkin ohjelman uudestaan, ja se toimii oikein hyvin. Esimerkin tarkoituksena on näyttää hieman funktioiden tarkoitusta. Kun kaikki kolme kenttää formatoidaan samalla tavalla, tuo osa koodista on hyvä laittaa omaan funktioonsa. Vastaavasti mahdollisuus rekisterinkäyttövirheisiin vähenee, kun kaikki data otetaan ensin talteen ja sitten vasta formatoidaan, vaikka toki toisinkin voi tehdä.
org 100h kello: mov ah, 0x2c int 0x21 xor ax, ax ; talleta sekunnit mov al, dh mov [sekunnit], ax ; talleta minuutit mov al, cl mov [minuutit], ax ; talleta tunnit mov al, ch mov [tunnit], ax ; formatoi tunnit lea bx, [tunnit] call formatoi_bx ; formatoi minuutit lea bx, [minuutit] call formatoi_bx ; formatoi sekunnit lea bx, [sekunnit] call formatoi_bx ; tulosta ruudulle mov dx, teksti mov ah, 09h int 0x21 jmp kello mov ah, 0x08 int 0x21 mov ah, 0x4c int 0x21 formatoi_bx: ; hae data osoitteesta [bx], jaa kymmenellä ; muuta ASCIIksi ja tallenna takaisin mov ax, [bx] mov dl, 10 div dl add ax, 0x3030 mov [bx], ax ret
Kiitos näistä, pitää taas kokeilla :)
Muuten toimii mullakin ton klo:n laittamine loppuun nyt, se ei vaan toiminu pidemmällä koodilla, tuo on siitä korjailtu versio.
Osaako joku muuten kertoa, miten sais vähennettyä ton ohjelman tehosyöppöyttä, eli nythän tuo pyörittää silmukkaa ~niin nopeesti ku kone jaksaa, mut esim sillee, et tuo odottais aina jonkun aikaa silmukan lopussa, jollon ei veisi niin hirveesti tehoa?
Oikeastaan ainoa tapa odottamiseen on hlt
, joka odottaa seuraavaa keskeytystä. Jos kellokeskeytys on käytössä, tämän pitäisi toimia oikein hyvin.
Oon sitäkin kokeillu, mutta ei auta, yhä pyörittää sitä vaan täysillä :/
Koodivinkkeihin tälläinen tavara.
Kentti: Entä jos laitat monta kertaa hlt.
Scan-koodit löytyvät myös ohjelmointiputkasta: https://www.ohjelmointiputka.net/oppaat/opas.
Aihe on jo aika vanha, joten et voi enää vastata siihen.