Hi,
ich würde gerne ein Assembler Program schreiben, welches eine im
Register vorliegende Hex-Zahl in einer Dualzahl ausgibt. Leider weiß ich
nicht wie ich da ran gehen soll. Kann mir jemand weiterhelfen? Vielen
Dank!
MfG
Johannes
Johannes B. schrieb:> Hi,>> ich würde gerne ein Assembler Program schreiben, welches eine im> Register vorliegende Hex-Zahl in einer Dualzahl ausgibt. Leider weiß ich> nicht wie ich da ran gehen soll. Kann mir jemand weiterhelfen? Vielen> Dank!
Meinst du das etwa so:
Du willst eine Zahl/Wert als '01001001' in ASCII z.B. über die
Schnittstelle ausgeben?
Das hab ich mal gemacht. In 'r16' steht deine 8bit Zahl/Wert den du
Wandeln willst. 'buffer' ist Speicher im RAM. Für eine 8bit Zahl/Wert
mindestens 9 Byte groß.
1
convert_to_bin:
2
load_p Y,(buffer)
3
ldi r17,3
4
ldi r19,'0'
5
ldi r20,'1'
6
convert_to_bin_byte_loop:
7
ldi r18,8
8
convert_to_bin_bit_loop:
9
lsl r16
10
brcs convert_to_bin_bit_hi
11
convert_to_bin_bit_lo:
12
st Y+,r19
13
rjmp convert_to_bin_bit
14
convert_to_bin_bit_hi:
15
st Y+,r20
16
convert_to_bin_bit:
17
dec r18
18
brne convert_to_bin_bit_loop
19
dec r17
20
brne convert_to_bin_byte_loop
21
st Y,NULL
22
ret
Der String deiner DualZahl steht danach in 'buffer' mit einer '0'
terminiert. Achja, 'NULL' ist hier ein Register, dass immer den Wert '0'
hat.
Ich hoffe ich konnt helfen
Steffen
Moin,
zu Deinem Quelltext hätte ich zwei kleine Anmerkungen:
A) Register r17 wird hier gar nicht benötigt. Du hast wahrscheinlich die
Routine für den Post irgendwo ausgeschnitten und übersehen, dass man die
r17-Schleife rausnehmen könnte...
B) Das Springen hinter "lsl r16" ist nicht nötig, da man den zu
speichernden Wert einfach durch Addition (oder verodern) von "0"+Carry
bekommen könnte.
So würde die Routine dann aussehen:
1
convert_to_bin: load_p Y,(buffer)
2
ldi r18,8
3
convert_to_bin_bit_loop: lsl r16
4
clr r20
5
lsl r20
6
ori r20,'0'
7
st Y+,r20
8
dec r18
9
brne convert_to_bin_bit_loop
10
st Y,NULL
11
ret
"load_p" ist ein Makro, welches die "buffer"-Adresse in die
entsprechenden High- und Low-Register lädt.
Kurze Beschreibung, was meine drei Zeilen bewirken:
Nach dem "lsl r16" befindet sich im Carry das auszugebende Bit. "clr
r20" löscht erstmal mein Register für die Berechnung des Ascii-Zeichens.
"lsl r20" schiebt jetzt das Carrybit ins unterste Bit (LSB) von r20.
Danach ist r20 entweder immer noch 0 oder bei gesetztem Carrybit wird
r20 zu 1. Danach verodere ich den Wert in r20 mit einer Ascii-"0"-Maske
(30h) ("ori r20,'0'"). Als Ergebnis habe ich jetzt in r20 entweder 30h
("0") oder 31h ("1"). Diesen Wert kann ich mit "st Y+,r20" direkt in den
Buffer schreiben.
Gruß,
Thomas
PS: Wer ist etwas tricky mag, der kann noch eine weitere Zeile sparen:
Johannes B. schrieb:> eine im Register vorliegende Hex-Zahl in einer Dualzahl ausgibt.
da sonntag ist bin ich mal ein bisschen nett...
in den Registern einer CPU liegen Daten IMMER im Binärformat vor. Eine
Hex-Zahl ist nur eine andere Darstellung der gleichen Zahl (genauso wie
Dezimal, Oktal, oder auch jede beliebige andere Basis wie 3, 4, 7, 11,
13, ...).
von daher:
1
mov r16, r15
2
rjmp write
(unter der Annahme, dass der Inhalt des Registers r16 mit write
ausgegeben wird (wie auch immer) und r15 den Wert enthält)
was "write" dann aus dem Wert macht steht auf einem anderen Blatt, kann
aber aufgrund fehlender Informationen nicht genauer spezifiziert/erklärt
werden
Hmmm,
sehe ich erst jetzt: Das steht ja alles in "PC-Programmierung". Da
funktionieren Routinen für den AVR ja grundsätzlich nicht... ;-)
Schönen Sonntag weiterhin,
Thomas
Und selbst bei PC wäre die Plattform hilfreich...
BIOS, DOS, Windows, Linux? Welcher Assembler?
Über's PC BIOS und nasm könnte es folgendermaßen aussehen:
1
org 0x7c00
2
; 16 bit number to print in dx
3
mov dx,0xaaaa
4
mov cx,16
5
next: rcl dx,1
6
mov al,'0'
7
adc al,0
8
mov ah,0x0e
9
xor bx,bx
10
int 10h
11
loop next
12
stop: jmp stop
Auf USB Flash schreiben und booten. ^^ Nur als Beispiel und ohne
Garantie.
Grüße, Steffen
Erstmal vielen Dank für die ganzen Antworten! Es geht hier um eine
Oberstufen Informatik Aufgabe. Als Assembler verwenden wir hier
debug.exe.Leider habe ich mit Assembler bisher noch nichts zu tun gehabt
und dementsprechend wenig Ahnung. Es geht darum, dass ich eine Zahl
bspw. BB im Register DH als binäre Zahl auf dem Bildschirm ausgebe.
Thomas T. schrieb:> PS: Wer ist etwas tricky mag, der kann noch eine weitere Zeile sparen:
Das sieht sehr kurz und knackig aus. Danke dir Thomas für deinen netten
Denkanstoß. Werde meine Routine gegen deine ersetzen. Code und Zeit
gespart. Das find ich gut..
Gruß Steffen