Forum: PC-Programmierung Assembler Programm Hex->Dualzahl


von Johannes B. (universalx)


Lesenswert?

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

von Steffen H. (avrsteffen)


Lesenswert?

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

von Thomas T. (knibbel)


Lesenswert?

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 ...

von Pastor Braune (Gast)


Lesenswert?

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

von Daniel F. (df311)


Lesenswert?

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

von Thomas T. (knibbel)


Lesenswert?

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

von Steffen (Gast)


Lesenswert?

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

von Johannes B. (universalx)


Lesenswert?

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.

von Steffen H. (avrsteffen)


Lesenswert?

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

von Steffen (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.