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
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? Interessant wird es dann wenn du eine Division implementierst :-)
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
Es passiert das gleiche wie bei den LOW-Bytes. Das Carry wird gesetzt :-) Teste auf "Carry", dann hast du einen Überlaufdetektor. In C hättest du aber auch einen Überlauf!
Kann man den C Compiler Assembler-Code ausgeben lassen? So kann man leicht sehen wie es der Compiler macht.
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
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.
Michael Niedrat schrieb: > > Ich bin mir immer noch so unsicher mit den binären Zahlen... > > Michael Und du bist langjähriger C Programmierer? Du erhälst das gleiche Ergebnis wie in C. (wie du geschrieben hast: 64 + Carry)
Dominik S. schrieb: > > Nein, im Register steht dann 0xFF und es gibt ein Carry-Bit. > Den Rest kannst du nicht auffangen. Hä??
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
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)
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 :-)
Danke für den Link, das sieht sehr passend aus. Hab ich irgendwie nicht gefunden! Nochmals Danke an alle für die vielen tollen Antworten! Und alles in Rekordzeit! Michael
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?
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.