Pfad: Home => AVR-Übersicht => Binäres Rechnen => Zahlenumwandlung => Quelltext    (This page in English: Flag EN) Logo
AT90S8515

Quelltext der Zahlenumwandlungsroutinen

asm-Version dieses Quelltextes: konvert.asm

Allgemeine Bedingungen


; ********************************************************
; * Routinen zur Zahlumwandlung, Version 0.1 Januar 2002 *
; * (C)2002 by info!at!avr-asm-tutorial.net              *
; ********************************************************
;
; Die folgenden Regeln gelten für alle Routinen zur Zahl-
; umwandlung:
; - Fehler während der Umwandlung werden durch ein gesetz-
;   tes T-Bit im Status-Register signalisiert.
; - Der Z Zeiger zeigt entweder in das SRAM (Adresse >=
;   $0060) oder auf einen Registerbereich (Adressen $0000
;   bis $001D), die Register R0, R16 und R30/31 dürfen
;   nicht in dem benutzten Bereich liegen!
; - ASCII- und BCD-kodierte mehrstellige Zahlen sind ab-
;   steigend geordnet, d.h. die höherwertigen Ziffern ha-
;   ben die niedrigerwertigen Adressen.
; - 16-bit-Binärzahlen sind generell in den Registern
;   rBin1H:rBin1L lokalisiert, bei einigen Routinen wird
;   zusätzlich rBin2H:rBin2L verwendet. Diese müssen im
;   Hauptprogramm definiert werden.
; - Bei Binärzahlen ist die Lage im Registerbereich nicht
;   maßgebend, sie können auf- oder absteigend geordnet
;   sein oder getrennt im Registerraum liegen. Zu vernei-
;   den ist eine Zuordnung zu R0, rmp, ZH oder ZL.
; - Register rmp (Bereich: R16..R29) wird innerhalb der
;   Rechenroutinen benutzt, sein Inhalt ist nach Rückkehr
;   nicht definiert.
; - Das Registerpaar Z wird innerhalb von Routinen verwen-
;   det. Bei der Rückkehr ist sein Inhalt abhängig vom
;   Fehlerstatus definiert.
; - Einige Routinen verwenden zeitweise Register R0. Sein
;   Inhalt wird vor der Rückkehr wieder hergestellt.
; - Wegen der Verwendung des Z-Registers ist in jedem Fall
;   die Headerdatei des Prozessors einzubinden oder ZL
;   (R30) und ZH (R31) sind manuell zu definieren. Wird
;   die Headerdatei oder die manuelle Definition nicht
;   vorgenommen, gibt es beim Assemblieren eine Fehlermel-
;   dung oder es geschehen rätselhafte Dinge.
; - Wegen der Verwendung von Unterroutinen muss der Sta-
;   pelzeiger (SPH:SPL bzw. SPL bei mehr als 256 Byte SRAM)
;   initiiert sein.

Überblick zur Zahlenumwandlung


;
; ************* Überblick über die Routinen **************
; Routine    Aufruf       Bedingungen          Rückkehr,
;                                              Fehler
; --------------------------------------------------------
; AscToBin2  Z zeigt auf  Beendet beim ersten  16-bit-Bin
;            erstes       Zeichen, das nicht   rBin1H:L,
;            ASCII-       einer Dezimalziffer  Überlauf-
;            Zeichen      entspricht, über-    fehler
;                         liest Leerzeichen
;                         und führende Nullen
; Asc5ToBin2 Z zeigt auf  Benötigt exakt 5     16-bit-Bin
;            erstes       gültige Ziffern,     rBin1H:L,
;            ASCII-       überliest Leerzei-   Überlauf
;            Zeichen      chen und Nullen      oder ungül-
;                                              tige Ziffern
; Bcd5ToBin2 Z zeigt auf  Benötigt exakt 5     16-bit-Bin
;            5-stellige   gültige Ziffern      rBin1H:L
;            BCD-Zahl                          Überlauf
;                                              oder ungül-
;                                              tige Ziffern
; Bin2ToBcd5 16-bit-Bin   Z zeigt auf erste    5-digit-BCD
;            in rBin1H:L   BCD-Ziffer (auch     ab Z, keine
;                         nach Rückkehr)       Fehler
; Bin2ToHex4 16-bit-Bin   Z zeigt auf erste    4-stellige
;            in rBin1H:L  Hex-ASCII-Stelle,    Hex-Zahl ab
;                         Ausgabe A...F        Z, keine
;                                              Fehler
; Hex4ToBin2 4-digit-Hex  Benötigt exakt vier  16-bit-Bin
;            Z zeigt auf  Stellen Hex-ASCII,   rBin1H:L,
;            erste Stelle akzeptiert A...F und ungültige
;                         a...f                Hex-Ziffer
;
; ******************* Umwandlungscode ********************
;
; Paket I: Von ASCII bzw. BCD nach Binär
;

Von ASCII nach Binär


; AscToBin2
; =========
; wandelt eine ASCII-kodierte Zahl in eine 2-Byte-/16-Bit-
;   Binärzahl um.
; Aufruf: Z zeigt auf erste Stelle der umzuwandelnden
;   Zahl, die Umwandlung wird bei der ersten nicht dezima-
;   len Ziffer beendet.
; Stellen: Zulässig sind alle Zahlen, die innerhalb des
;   Wertebereiches von 16 Bit binär liegen (0..65535).
; Rückkehr: Gesetztes T-Flag im Statusregister zeigt Feh-
;   ler an.
;   T=0: Zahl in rBin1H:L ist gültig, Z zeigt auf erstes
;     Zeichen, das keiner Dezimalziffer entsprach
;   T=1: Überlauffehler (Zahl zu groß), rBin1H:L undefi-
;     niert, Z zeigt auf Zeichen, bei dessen Verarbeitung
;     der Fehler auftrat.
; Benötigte Register: rBin1H:L (Ergebnis), rBin2H:L (wieder
;   hergestellt), rmp
; Benötigte Unterroutinen: Bin1Mul10
;
AscToBin2:
	clr rBin1H ; Ergebnis auf Null setzen
	clr rBin1L
	clt ; Fehlerflagge zurücksetzen
AscToBin2a:
	ld rmp,Z+ ; lese Zeichen
	cpi rmp,' ' ; ignoriere führende Leerzeichen ...
	breq AscToBin2a
	cpi rmp,'0' ; ... und Nullen
	breq AscToBin2a
AscToBin2b:
	subi rmp,'0' ; Subtrahiere ASCII-Null
	brcs AscToBin2d ; Ende der Zahl erkannt
	cpi rmp,10 ; prüfe Ziffer
	brcc AscToBin2d ; Ende der Umwandlung
	rcall Bin1Mul10 ; Binärzahl mit 10 malnehmen
	brts AscToBin2c ; Überlauf, gesetztes T-Flag
	add rBin1L,rmp ; Addiere Ziffer zur Binärzahl
	ld rmp,Z+ ; Lese schon mal nächstes Zeichen
	brcc AscToBin2b ; Kein Überlauf ins MSB
	inc rBin1H ; Überlauf ins nächste Byte
	brne AscToBin2b ; Kein Überlauf ins nächste Byte
	set ; Setze Überlauffehler-Flagge
AscToBin2c:
	sbiw ZL,1 ; Überlauf trat bei letztem Zeichen auf
AscToBin2d:
	ret ; fertig, Rückkehr

Fünfstellige ASCII-Zahl nach Binär


;
; Asc5ToBin2
; ==========
; wandelt eine fünfstellige ASCII-kodierte Zahl in 2-Byte-
; Binärzahl um.
; Aufruf: Z zeigt auf erste Stelle der ASCII-kodierten
;   Zahl, führende Leerzeichen und Nullen sind erlaubt.
; Stellen: Die Zahl muss exakt 5 gültige Stellen haben.
; Rückkehr: T-Flag zeigt Fehlerbedingung an:
;   T=0: Binärzahl in rBin1H:L ist gültig, Z zeigt auf
;     erste Stelle der ASCII-kodierten Zahl.
;   T=1: Fehler bei der Umwandlung. Entweder war die Zahl
;     zu groß (0..65535, Z zeigt auf die Ziffer, bei der
;     der Überlauf auftrat) oder sie enthilt ein ungülti-
;     ges Zeichen (Z zeigt auf das ungültige Zeichen).
; Benötigte Register: rBin1H:L (Ergebnis), R0 (wiederher-
;   gestellt), rBin2H:L (wieder hergestellt), rmp
; Aufgerufene Unterroutinen: Bin1Mul10
;
Asc5ToBin2:
	push R0 ; R0 wird als Zähler verwendet, retten
	ldi rmp,6 ; Fünf Ziffern, einer zu viel
	mov R0,rmp ; in Zählerregister R0
	clr rBin1H ; Ergebnis auf Null setzen
	clr rBin1L
	clt ; Fehlerflagge T-Bit zurücksetzen
Asc5ToBin2a:
	dec R0 ; Alle Zeichen leer oder Null?
	breq Asc5ToBin2d ; Ja, beenden
	ld rmp,Z+ ; Lese nächstes Zeichen
	cpi rmp,' ' ; überlese Leerzeichen
	breq Asc5ToBin2a ; geh zum nächsten Zeichen
	cpi rmp,'0' ; überlese führende Nullen
	breq Asc5ToBin2a ; geh zum nächsten Zeichen
Asc5ToBin2b:
	subi rmp,'0' ; Behandle Ziffer, ziehe ASCII-0 ab
	brcs Asc5ToBin2e ; Ziffer ist ungültig, raus
	cpi rmp,10 ; Ziffer größer als neun?
	brcc Asc5ToBin2e ; Ziffer ist ungültig, raus
	rcall Bin1Mul10 ; Multipliziere Binärzahl mit 10
	brts Asc5ToBin2e ; Überlauf, raus
	add rBin1L,rmp ; addiere die Ziffer zur Binärzahl
	ld rmp,z+ ; lese schon mal das nächste Zeichen
	brcc Asc5ToBin2c ; Kein Überlauf in das nächste Byte
	inc rBin1H ; Überlauf in das nächste Byte
	breq Asc5ToBin2e ; Überlauf auch ins übernächste Byte
Asc5ToBin2c:
	dec R0 ; Verringere Zähler für Anzahl Zeichen
	brne Asc5ToBin2b ; Wandle weitere Zeichen um
Asc5ToBin2d: ; Ende der ASCII-kodierten Zahl erreicht
	sbiw ZL,5 ; Stelle die Startposition in Z wieder her
	pop R0 ; Stelle Register R0 wieder her
	ret ; Kehre zurück
Asc5ToBin2e: ; Letztes Zeichen war ungültig
	sbiw ZL,1 ; Zeige mit Z auf ungültiges Zeichen
	pop R0 ; Stelle Register R0 wieder her
	set ; Setze T-Flag für Fehler
	ret ; und kejre zurück
;

Von BCD zu Binär


; Bcd5ToBin2
; ==========
; wandelt eine 5-bit-BCD-Zahl in eine 16-Bit-Binärzahl um
; Aufruf: Z zeigt auf erste Stelle der BCD-kodierten
;   Zahl
; Stellen: Die Zahl muss exakt 5 gültige Stellen haben.
; Rückkehr: T-Flag zeigt Fehlerbedingung an:
;   T=0: Binärzahl in rBin1H:L ist gültig, Z zeigt auf
;     erste Stelle der BCD-kodierten Zahl.
;   T=1: Fehler bei der Umwandlung. Entweder war die Zahl
;     zu groß (0..65535, Z zeigt auf die Ziffer, bei der
;     der Überlauf auftrat) oder sie enthielt ein ungülti-
;     ges Zeichen (Z zeigt auf das ungültige Zeichen).
; Benötigte Register: rBin1H:L (Ergebnis), R0 (wiederher-
;   gestellt), rBin2H:L (wieder hergestellt), rmp
; Aufgerufene Unterroutinen: Bin1Mul10
;
Bcd5ToBin2:
	push R0 ; Rette Register R0
	clr rBin1H ; Setze Ergebnis Null
	clr rBin1L
	ldi rmp,5 ; Setze Zähler auf 5 Ziffern
	mov R0,rmp ; R0 ist Zähler
	clt ; Setze Fehlerflagge zurück
Bcd5ToBin2a:
	ld rmp,Z+ ; Lese BCD-Ziffer
	cpi rmp,10 ; prüfe ob Ziffer korrekt
	brcc Bcd5ToBin2c ; ungültige BCD-Ziffer
	rcall Bin1Mul10 ; Multipliziere Ergebnis mit 10
	brts Bcd5ToBin2c ; Überlauf aufgetreten
	add rBin1L,rmp ; Addiere Ziffer
	brcc Bcd5ToBin2b ; Kein Überlauf ins nächste Byte
	inc rBin1H ; Überlauf ins nächste Byte
	breq Bcd5ToBin2c ; Überlauf ins übernächste Byte
Bcd5ToBin2b:
	dec R0 ; weitere Ziffer?
	brne Bcd5ToBin2a ; Ja
	pop R0 ; Stelle Register wieder her
	sbiw ZL,5 ; Setze Zeiger auf erste Stelle der BCD-Zahl
	ret ; Kehre zurück
Bcd5ToBin2c:
	sbiw ZL,1 ; Eine Ziffer zurück
	pop R0 ; Stelle Register wieder her
	set ; Setze T-flag, Fehler
	ret ; Kehre zurück

Binärzahl mit 10 multiplizieren


;
; Bin1Mul10
; =========
; Multipliziert die 16-Bit-Binärzahl mit 10
; Unterroutine benutzt von AscToBin2, Asc5ToBin2, Bcd5ToBin2
; Aufruf: 16-Bit-Binärzahl in rBin1H:L
; Rückkehr: T-Flag zeigt gültiges Ergebnis an.
;   T=0: rBin1H:L enthält gültiges Ergebnis.
;   T=1: Überlauf bei der Multiplikation, rBin1H:L undefiniert
; Benutzte Register: rBin1H:L (Ergebnis), rBin2H:L (wird wieder
;   hergestellt)
;
Bin1Mul10:
	push rBin2H ; Rette die Register rBin2H:L
	push rBin2L
	mov rBin2H,rBin1H ; Kopiere die Zahl dort hin
	mov rBin2L,rBin1L
	add rBin1L,rBin1L ; Multipliziere Zahl mit 2
	adc rBin1H,rBin1H
	brcs Bin1Mul10b ; Überlauf, raus hier!
Bin1Mul10a:
	add rBin1L,rbin1L ; Noch mal mit 2 malnehmen (=4*Zahl)
	adc rBin1H,rBin1H
	brcs Bin1Mul10b ; Überlauf, raus hier!
	add rBin1L,rBin2L ; Addiere die Kopie (=5*Zahl)
	adc rBin1H,rBin2H
	brcs Bin1Mul10b ;Überlauf, raus hier!
	add rBin1L,rBin1L ; Noch mal mit 2 malnehmen (=10*Zahl)
	adc rBin1H,rBin1H
	brcc Bin1Mul10c ; Kein Überlauf, überspringe
Bin1Mul10b:
	set ; Überlauf, setze T-Flag
Bin1Mul10c:
	pop rBin2L ; Stelle die geretteten Register wieder her
	pop rBin2H
	ret ; Kehre zurück
;
; ************************************************
;
; Paket II: Von Binär nach ASCII bzw. BCD
;

Von binär nach ASCII


; Bin2ToAsc5
; ==========
; wandelt eine 16-Bit-Binärzahl in eine fünfstellige ASCII-
;   kodierte Dezimalzahl um
; Aufruf: 16-Bit-Binärzahl in rBin1H:L, Z zeigt auf Anfang
;   der Zahl
; Rückkehr: Z zeigt auf Anfang der Zahl, führende Nullen sind
;   mit Leerzeichen überschrieben
; Benutzte Register: rBin1H:L (bleibt erhalten), rBin2H:L
;   (wird überschrieben), rmp
; Aufgerufene Unterroutinen: Bin2ToBcd5
;
Bin2ToAsc5:
	rcall Bin2ToBcd5 ; wandle Binärzahl in BCD um
	ldi rmp,4 ; Zähler auf 4
	mov rBin2L,rmp
Bin2ToAsc5a:
	ld rmp,z ; Lese eine BCD-Ziffer
	tst rmp ; prüfe ob Null
	brne Bin2ToAsc5b ; Nein, erste Ziffer ungleich 0 gefunden
	ldi rmp,' ' ; mit Leerzeichen überschreiben
	st z+,rmp ; und ablegen
	dec rBin2L ; Zähler um eins senken
	brne Bin2ToAsc5a ; weitere führende Leerzeichen
	ld rmp,z ; Lese das letzte Zeichen
Bin2ToAsc5b:
	inc rBin2L ; Ein Zeichen mehr
Bin2ToAsc5c:
	subi rmp,-'0' ; Addiere ASCII-0
	st z+,rmp ; und speichere ab, erhöhe Zeiger
	ld rmp,z ; nächstes Zeichen lesen
	dec rBin2L ; noch Zeichen behandeln?
	brne Bin2ToAsc5c ; ja, weitermachen
	sbiw ZL,5 ; Zeiger an Anfang
	ret ; fertig

Binär in ASCII ohne führende Leerzeichen


;
; Bin2ToAsc
; =========
; wandelt eine 16-Bit-Binärzahl in eine fünfstellige ASCII-
;   kodierte Dezimalzahl um, Zeiger zeigt auf die erste signi-
;   fikante Ziffer der Zahl, und gibt Anzahl der Ziffern zu-
;   rück
; Aufruf: 16-Bit-Binärzahl in rBin1H:L, Z zeigt auf Anfang
;   der Zahl (5 Stellen erforderlich, auch bei kleineren Zah-
;   len!)
; Rückkehr: Z zeigt auf erste signifikante Ziffer der ASCII-
;   kodierten Zahl, rBin2L enthält Länge der Zahl (1..5)
; Benutzte Register: rBin1H:L (bleibt erhalten), rBin2H:L
;   (wird überschrieben), rmp
; Aufgerufene Unterroutinen: Bin2ToBcd5, Bin2ToAsc5
;
Bin2ToAsc:
	rcall Bin2ToAsc5 ; Wandle Binärzahl in ASCII
	ldi rmp,6 ; Zähler auf 6
	mov rBin2L,rmp
Bin2ToAsca:
	dec rBin2L ; verringere Zähler
	ld rmp,z+ ; Lese Zeichen und erhöhe Zeiger
	cpi rmp,' ' ; war Leerzeichen?
	breq Bin2ToAsca ; Nein, war nicht
	sbiw ZL,1 ; ein Zeichen rückwärts
	ret ; fertig

Von binär nach BCD


;
; Bin2ToBcd5
; ==========
; wandelt 16-Bit-Binärzahl in 5-stellige BCD-Zahl um
; Aufruf: 16-Bit-Binärzahl in rBin1H:L, Z zeigt auf die
;   erste Stelle der BCD-kodierten Resultats
; Stellen: Die BCD-Zahl hat exakt 5 gültige Stellen.
; Rückkehr: Z zeigt auf die höchste BCD-Stelle
; Benötigte Register: rBin1H:L (wird erhalten), rBin2H:L
;   (wird nicht wieder hergestellt), rmp
; Aufgerufene Unterroutinen: Bin2ToDigit
;
Bin2ToBcd5:
	push rBin1H ; Rette Inhalt der Register rBin1H:L
	push rBin1L
	ldi rmp,HIGH(10000) ; Lade 10.000 in rBin2H:L
	mov rBin2H,rmp
	ldi rmp,LOW(10000)
	mov rBin2L,rmp
	rcall Bin2ToDigit ; Ermittle 5.Stelle durch Abziehen
	ldi rmp,HIGH(1000) ; Lade 1.000 in rBin2H:L
	mov rBin2H,rmp
	ldi rmp,LOW(1000)
	mov rBin2L,rmp
	rcall Bin2ToDigit ; Ermittle 4.Stelle durch Abziehen
	ldi rmp,HIGH(100) ; Lade 100 in rBin2H:L
	mov rBin2H,rmp
	ldi rmp,LOW(100)
	mov rBin2L,rmp
	rcall Bin2ToDigit ; Ermittle 3.Stelle durch Abziehen
	ldi rmp,HIGH(10) ; Lade 10 in rBin2H:L
	mov rBin2H,rmp
	ldi rmp,LOW(10)
	mov rBin2L,rmp
	rcall Bin2ToDigit ; Ermittle 2.Stelle durch Abziehen
	st z,rBin1L ; Rest sind Einer
	sbiw ZL,4 ; Setze Zeiger Z auf 5.Stelle (erste Ziffer)
	pop rBin1L ; Stelle den Originalwert wieder her
	pop rBin1H
	ret ; und kehre zurück
;
; Bin2ToDigit
; ===========
; ermittelt eine dezimale Ziffer durch fortgesetztes Abziehen
; einer binär kodierten Dezimalstelle
; Unterroutine benutzt von: Bin2ToBcd5, Bin2ToAsc5, Bin2ToAsc
; Aufruf: Binärzahl in rBin1H:L, binär kodierte Dezimalzahl
;   in rBin2H:L, Z zeigt auf bearbeitete BCD-Ziffer
; Rückkehr: Ergebis in Z (bei Aufruf), Z um eine Stelle er-
;   höht, keine Fehlerbehandlung
; Benutzte Register: rBin1H:L (enthält Rest der Binärzahl),
;   rBin2H (bleibt erhalten), rmp
; Aufgerufene Unterroutinen: -
;
Bin2ToDigit:
	clr rmp ; Zähler auf Null
Bin2ToDigita:
	cp rBin1H,rBin2H ; Vergleiche MSBs miteinander
	brcs Bin2ToDigitc ; MSB Binärzahl kleiner, fertig
	brne Bin2ToDigitb ; MSB Binärzahl größer, subtrahiere
	cp rBin1L,rBin2L ; MSB gleich, vergleiche LSBs
	brcs Bin2ToDigitc ; LSB Binärzahl kleiner, fertig
Bin2ToDigitb:
	sub rBin1L,rBin2L ; Subtrahiere LSB Dezimalzahl
	sbc rBin1H,rBin2H ; Subtrahiere Carry und MSB
	inc rmp ; Erhöhe den Zähler
	rjmp Bin2ToDigita ; Weiter vergleichen/subtrahieren
Bin2ToDigitc:
	st z+,rmp ; Speichere das Ergebnis und erhöhe Zeiger
	ret ; zurück
;
; ***********************************************
;
; Paket III: Von Binär nach Hex-ASCII
;

Von binär nach Hex


; Bin2ToHex4
; ==========
; wandelt eine 16-Bit-Binärzahl in Hex-ASCII
; Aufruf: Binärzahl in rBin1H:L, Z zeigt auf erste Position
;   des vierstelligen ASCII-Hex
; Rückkehr: Z zeigt auf erste Position des vierstelligen
;   ASCII-Hex, ASCII-Ziffern A..F in Großbuchstaben
; Benutzte Register: rBin1H:L (bleibt erhalten), rmp
; Aufgerufene Unterroutinen: Bin1ToHex2, Bin1ToHex1
;
Bin2ToHex4:
	mov rmp,rBin1H ; MSB in rmp kopieren
	rcall Bin1ToHex2 ; in Hex-ASCII umwandeln
	mov rmp,rBin1L ; LSB in rmp kopieren
	rcall Bin1ToHex2 ; in Hex-ASCII umwandeln
	sbiw ZL,4 ; Zeiger auf Anfang Hex-ASCII
	ret ; fertig
;
; Bin1ToHex2 wandelt die 8-Bit-Binärzahl in rmp in Hex-ASCII
; gehört zu: Bin2ToHex4
;
Bin1ToHex2:
	push rmp ; Rette Byte auf dem Stapel
	swap rmp ; Vertausche die oberen und unteren 4 Bit
	rcall Bin1ToHex1 ; wandle untere 4 Bits in Hex-ASCII
	pop rmp ; Stelle das Byte wieder her
Bin1ToHex1:
	andi rmp,$0F ; Maskiere die oberen vier Bits
	subi rmp,-'0' ; Addiere ASCII-0
	cpi rmp,'9'+1 ; Ziffern A..F?
	brcs Bin1ToHex1a ; Nein
	subi rmp,-7 ; Addiere 7 für A..F
Bin1ToHex1a:
	st z+,rmp ; abspeichern und Zeiger erhöhen
	ret ; fertig
;
; ***********************************************
;
; Paket IV: Von Hex-ASCII nach Binär
;

Von Hex nach Binär


; Hex4ToBin2
; ==========
; wandelt eine vierstellige Hex-ASCII-Zahl in eine 16-Bit-
;   Binärzahl um
; Aufruf: Z zeigt auf die erste Stelle der Hex-ASCII-Zahl
; Rückkehr: T-Flag zeigt Fehler an:
;   T=0: rBin1H:L enthält die 16-Bit-Binärzahl, Z zeigt
;     auf die erste Hex-ASCII-Ziffer wie beim Aufruf
;   T=1: ungültige Hex-ASCII-Ziffer, Z zeigt auf ungültige
;     Ziffer
; Benutzte Register: rBin1H:L (enthält Ergebnis), R0 (wie-
;   der hergestellt), rmp
; Aufgerufene Unterroutinen: Hex2ToBin1, Hex1ToBin1
;
Hex4ToBin2:
	clt ; Lösche Fehlerflag
	rcall Hex2ToBin1 ; Wandle zwei Hex-ASCII-Ziffern
	brts Hex4ToBin2a ; Fehler, beende hier
	mov rBin1H,rmp ; kopiere nach MSB Ergebnis
	rcall Hex2ToBin1 ; Wandle zwei Hex-ASCII-Ziffern
	brts Hex4ToBin2a ; Fehler, beende hier
	mov rBin1L,rmp ; kopiere nach LSB Ergebnis
	sbiw ZL,4 ; Ergebis ok, Zeiger auf Anfang
Hex4ToBin2a:
	ret ; zurück
;
; Hex2ToBin1 wandelt 2-stellig-Hex-ASCII nach 8-Bit-Binär
;
Hex2ToBin1:
	push R0 ; Rette Register R0
	rcall Hex1ToBin1 ; Wandle nächstes Zeichen in Byte
	brts Hex2ToBin1a ; Fehler, stop hier
	swap rmp; untere vier Bits in obere vier Bits
	mov R0,rmp ; zwischenspeichern
	rcall Hex1ToBin1 ; Nächstes Zeichen umwandeln
	brts Hex2ToBin1a ; Fehler, raus hier
	or rmp,R0 ; untere und obere vier Bits zusammen
Hex2ToBin1a:
	pop R0 ; Stelle R0 wieder her
	ret ; zurück
;
; Hex1ToBin1 liest ein Zeichen und wandelt es in Binär um
;
Hex1ToBin1:
	ld rmp,z+ ; Lese Zeichen
	subi rmp,'0' ; Ziehe ASCII-0 ab
	brcs Hex1ToBin1b ; Fehler, kleiner als 0
	cpi rmp,10 ; A..F ; Ziffer größer als 9?
	brcs Hex1ToBin1c ; nein, fertig
	cpi rmp,$30 ; Kleinbuchstaben?
	brcs Hex1ToBin1a ; Nein
	subi rmp,$20 ; Klein- in Grossbuchstaben
Hex1ToBin1a:
	subi rmp,7 ; Ziehe 7 ab, A..F ergibt $0A..$0F
	cpi rmp,10 ; Ziffer kleiner $0A?
	brcs Hex1ToBin1b ; Ja, Fehler
	cpi rmp,16 ; Ziffer größer als $0F
	brcs Hex1ToBin1c ; Nein, Ziffer in Ordnung
Hex1ToBin1b: ; Error
	sbiw ZL,1 ; Ein Zeichen zurück
	set ; Setze Fehlerflagge
Hex1ToBin1c:
	ret ; Zurück



Zum Seitenanfang

©2002 by http://www.avr-asm-tutorial.net