Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Assembly: Kello assemblyllä

Sivun loppuun

Kentti [03.07.2008 20:42:21]

#

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

Metabolix [03.07.2008 21:42:21]

#

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.

Antti Laaksonen [03.07.2008 22:20:14]

#

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/scan_codes.html
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

Kentti [04.07.2008 12:43:29]

#

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?

Metabolix [04.07.2008 19:52:44]

#

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

Kentti [04.07.2008 20:56:21]

#

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?

Metabolix [04.07.2008 22:54:28]

#

Oikeastaan ainoa tapa odottamiseen on hlt, joka odottaa seuraavaa keskeytystä. Jos kellokeskeytys on käytössä, tämän pitäisi toimia oikein hyvin.

Kentti [04.07.2008 23:09:42]

#

Oon sitäkin kokeillu, mutta ei auta, yhä pyörittää sitä vaan täysillä :/

Pollapoju [19.07.2008 12:41:33]

#

Koodivinkkeihin tälläinen tavara.

Dude [20.07.2008 16:53:07]

#

Kentti: Entä jos laitat monta kertaa hlt.

Scan-koodit löytyvät myös ohjelmointiputkasta: https://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=napk


Sivun alkuun

Vastaus

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

Tietoa sivustosta