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:
1 | convert_to_bin: load_p Y,(buffer) |
2 | ldi r18,8 |
3 | convert_to_bin_bit_loop: lsl r16 |
4 | ldi r20,18h |
5 | lsl r20 |
6 | st Y+,r20 |
7 | dec r18 |
8 | brne convert_to_bin_bit_loop |
9 | st Y,NULL |
10 | ret |
Jetzt ist aber gut ...
Noch eine Lösung ;-) BinAscii: ; zu wandelnde daten sind im reg aa ldi xx,8 ; 8 bit Zähler ldi yy,0x30 ; ASCII 0 conv: mov Txbyte,yy ; mache erstmal 0 ( ASCII 0x30) lsl aa ;ist datenbit 0 brcc countb ; inc Txbyte ;nein dann 1 (ASCII 0x31) countb: rcall putchar ;auf TTY ausgeben dec xx ;zähle bits brne conv ret ;fertig
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
Hallo Johannes, offenbar stehst Du noch ganz am Anfang. Hast Du von Deinem Lehrer keine Informationen bekommen? Naja, vielleicht hilft Dir ja das folgende Wikibook weiter: http://de.wikibooks.org/wiki/Assembler-Programmierung_f%C3%BCr_x86-Prozessoren Grüße, Steffen
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.