Verpackte Dezimalzahlung der ASCII -Baugruppe
Frage
Ich versuche, gepackte Dezimalzahlen in ASCII -Saiten umzuwandeln. Hier ist mein bisheriger Verständnis:
Folgende:
bcd BYTE 34h
Sollte nach "ausgepackt" in die Dezimalzahl 34 konvertieren. Jetzt bin ich mir nicht sicher, wie man dies am besten macht. Wenn ich diese Hexadezimalzahl in Binärer umwandelte, ist es wie folgt ...
0011 0100
Wenn ich jetzt meinen Verfahren jeweils jeweils 4 -Bit -binärer Wert ausdrucken lassen habe, sollte er die ASCII -Zahlenzeichenfolge richtig ausdrucken? Wenn ich also eine Schleife durchquere, schnappe ich mich die erste 4 -Bit -Bitärzahl, drucke ihren tatsächlichen Wert aus, es wird 3 gedruckt. Dann tue das gleiche, es wird 4 drucken.
Also, hier ist meine allgemeine Idee:
Nehmen Sie einen 8 -Bit -Wert "34H", bewegern Sie ihn in Ah und Al. In Ah die zweite Hälfte der Bits mit dem Follow: klar:
and ah, 11110000b
und in AL die erste Hälfte der Bits mit Folgendem klären:
and al, 00001111b
Also ah = 0110b oder 3 und al = 0100b oder 4, dann drucken Sie diese entsprechend aus.
Ist das ein guter Ansatz? Oder gehe ich völlig falsch oder weit darüber nach, darüber nachzudenken?
Bearbeiten: Hier ist meine endgültige Lösung mit dem ursprünglichen Wert von 12345678H. Vielen Dank an alle, die geholfen haben!
;-----------------------------------------------------------------------------
PackedToAsc PROC USES eax ebx edx ecx esi
; This function displays a packed decimal value in its "ascii" form
; i.e. 12345678h would display decimal, 12345678 in decimal form
;
; Requires ECX = SIZEOF packed decimal
; ESI to be pointing to the packed decimal
;-----------------------------------------------------------------------------
mov edx, [esi] ; temp store our offset
mov eax, 0 ; clear eax
mov ebx, 0 ; clear ebx
L1: rol edx, 8 ; rotate left 8 bits to avoid little endian
mov [esi], edx ; mov our temp back to the actual value
mov al, BYTE PTR [esi] ; al = 12h 0001 0010
mov bl, BYTE PTR [esi] ; bl = 12h 0001 0010
shr al, 4 ; al = 0000 0001
and bl, 00001111b; ; bl = 0000 0010
add al, 48 ; convert to ascii
call WriteChar ; display al
mov al, bl
add al, 48 ; convert to ascii
call WriteChar ; display bl
loop L1
call Crlf
ret
PackedToAsc END
P
Lösung
BCD verwendet nur die Ziffern 0 bis 9.
Eine ausgepackte BCD -Ziffer verwendet das untere Knabbern eines gesamten Byte und um es in ASCII umzuwandeln, dass Sie 48 hinzufügen.
Die Zahl 34H ist 52 Dezimaler und wird als ausgepackter BCD als 00000101 und 00000010 dargestellt
(Änderung, um Verwirrung bei der Verwendung integrierter Anweisungen zu vermeiden.) Wenn es gepackt ist: 01010010 == BCD verpackt 52
Um es auszupacken, können Sie tun, was Sie getan haben, aber Sie müssen das Recht verschieben, um den Wert in die LO-Nibble zu platzieren. Um in ASCII zu konvertieren, fügen Sie einfach 48 hinzu.
bearbeiten
Masm (=> Alle Anweisungen, inklusive Linux), die auf 80x86-Prozessoren ausgeführt werden, verwendet das Little-Endian-Schema. CPUs wie Motorola 68000 (Apple Mac) und RISC verwenden Big-Endian.
Wenn Sie eine Zahl als BCD speichern, ist das am wenigsten signifikante Byte die niedrigste Adresse bis zum signifikantesten mit der höchsten, z. B. bei der höchsten Adresse:
my_unpacked_bcd DB 4,3,2,1 ; this is the decimal number 1234
my_packed_bcd DW 3412h ; this defines the same number as packed
Packed BCD hängt davon ab, was Sie damit machen möchten. Wenn Sie wollen ADD, MUL, DIV, SUB
Sie müssen die von diesen Anweisungen erforderlichen Werte vorlegen. Denken Sie auch daran, Null-Bytes hinzuzufügen, um Ihre Ziffern zu starten und zu beenden.