Addition zweier 16 bit Werte in Assembler

Gast #2856076
Lesenswert?

Hallo Forum,

ich bin langjähriger C-Programmierer und möchte mich nun etwas mit 
Inline-Assembler befassen. Ich habe auch schon den Einstieg gefunden, 
aber tue mir manchmal doch noch schwer damit, besonders mit größeren 
zusammengesetzten Operationen.

Ich möchte möglichst schnell und elegant zwei 16 bit Werte addieren in 
einem ATmega16. Die beiden 16 bit Werte stehen fest in Registern, also

R0 = Lowbyte des 16 bit Wertes 1
R1 = Highbyte des 16 bit Wertes 1

R2 = Lowbyte des 16 bit Wertes 2
R3 = Highbyte des 16 bit Wertes 2

Wie mache ich das am effektivsten in Assembler? Ich habe so meine 
Probleme mit dem Carry...

vielen Dank für alle Tips!

Michael
Gast #2856140
Lesenswert?

Hallo Udo,

vielen Dank für deine Antwort! Das kann ich nachvollziehen. Aber was 
passiert dann genau bei einem Überlauf des High-Bytes?

Beispiel:

Der erste 16-bit Wert sei 65500, der zweite 16-bit Wert sei 100. Ich 
addiere beide nach Deinem Schema oben. Was steht dann danach als 
Ergebnis ?

Puhh- ich merke schon dass man mit C einfach weit weg ist von den 
Grundlagen, dort muss man sich (fast) keine Sorgen um sowas machen...

Michael
Gast #2856164
Lesenswert?

Ok, das ist klar...

Aber was ist das Ergebnis? Steht dann also nach der Addition quasi das 
was nicht reingepasst hat als "Rest" da ?

Beispiel:

65500 + 100 = 65600  --> das passt aber nicht in einen 16-bit Wert rein

Bei 65535 erfolgt der Überlauf. Es wurden "65" zu viel addiert. Steht 
dann nach der Addition also "64" als Ergebnis (eins weniger wegen der 
NUll)?

Ich bin mir immer noch so unsicher mit den binären Zahlen...

Michael
#2856169
Lesenswert?

Martin schrieb:
> Kann man  den C Compiler  Assembler-Code  ausgeben lassen?
> So kann man leicht sehen  wie  es der Compiler macht.

Klar.
Der Compile erzeugt aus dem C-Code erstmal ein Assembler-Listing.
Eine Datei mit Namen *.lst, im Projektordner.

Michael Niedrat schrieb:
> Bei 65535 erfolgt der Überlauf. Es wurden "65" zu viel addiert. Steht
> dann nach der Addition also "64" als Ergebnis (eins weniger wegen der
> NUll)?

Nein, im Register steht dann 0xFF und es gibt ein Carry-Bit.
Den Rest kannst du nicht auffangen.
Gast #2856192
Lesenswert?

Danke, Daniel!

Offensichtlich stiftet diese Frage ja schon Verwirrung... ich hatte 
jetzt zwei unterschiedliche Antworten :-)

Soll ich noch einen draufsetzen? Also...

Wie ist das bei Einer-Komplement und Zweierkomplement ?

Es interessiert mich wirklich.

Vielen Dank an alle!!

Michael
#2856213
Lesenswert?

Dominik S. schrieb:
> Dominik S. schrieb:
>> Nein, im Register steht dann 0xFF und es gibt ein Carry-Bit.
>>
>> Den Rest kannst du nicht auffangen.
>
> Oh je ^^ das natürlich ganz schnell wieder vergessen - weiß Gott wie da
> grad drauf kam ^^
>
> So wär's natürlich nur wenn man eine Arithmetik mit Sättigung
> implementieren
> will(http://www.mikrocontroller.net/articles/AVR_Arithmetik/Saturierung)

Na das sieht ja mal ganz gut aus :-)
#2856283
Lesenswert?

Udo Schmitt schrieb:
> Du addierst die beiden Low Bytes.
> Kommt es zu einem Überlauf ist das Carry automatisch gesetzt.
> Jetzt addierst du mit Carry (dazu gibt es oft einen eigenen Befehl) die
> beiden High Bytes.
> Wo ist das Problem?

@Michael
Du mußt dir angewöhnen, Gemeinsamkeiten zwischen Zahlensystemen zu 
erkennen!

Mal dein Beispiel aufgegriffen:

in r0 -> Einerstelle ('low-Byte') der ersten Dezimalzahl
in r1 -> Zehnerstelle ('high-Byte') der ersten Dezimalzahl
in r2 -> Einerstelle ('low-Byte') der zweiten Dezimalzahl
in r3 -> Zehnerstelle ('high-Byte') der zweiten Dezimalzahl

Wie machst du jetzt eine schriftliche Addition (später Multiplikation 
und Division (auf Bit-Ebene))? -> ganz einfach, oder?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren