ich dachte, die erste Teilaufgabe ist gelöst worden? Zwar nicht mit einer 16-Bit Adressenrechnung, wie das Florian vor hatte, aber es funzt. :)
Ist das richtig so?
Druckbare Version
ich dachte, die erste Teilaufgabe ist gelöst worden? Zwar nicht mit einer 16-Bit Adressenrechnung, wie das Florian vor hatte, aber es funzt. :)
Ist das richtig so?
So, da bin ich wieder vom essen.
Das mit cp und cpc, also wie das genau funktioniert, aber das test ich dann erstmal im Simulator aus, wie Sebastian meinte.Zitat:
@ Thomas:
Was verstehst Du derzeit nicht?
Und wir meinten ja, dass der String "Hallo" 6 Bytes hat, ne? Wieso passt der dann in ein 8 Bit Register? 8 Bit sind doch nur 1 Byte, also sehr viel kleiner als 6 Byte. Oder bring ich da nun was durcheinander?
cpi kennen wir schon. Hab ich auch oben in meinem Code verwendet, aber ich glaub, so wolltest du das ja nicht haben, oder?
Hallo Thomas!
Jedes Byte wird nacheinander in das r0 geladen, nicht der ganze String auf einmal!
Sonst müsstest Du ja nicht immer lpm ausführen!
Soll ich einen Beispielcode posten?
Ja, dass es nacheinander passiert, ist mir klar, aber am Ende kann in r16 ja nicht "Hallo!" stehen, oder? Denn "Hallo!" braucht ja nunmal 6 Bytes. Also steht am Ende im Register nur ein "!"?
Wenns zum Verständniss beiträgt ;) Die Teilaufgabe haben wir ja schon gelöst, also verrätst du ja nichts.Zitat:
Soll ich einen Beispielcode posten?
[edit]
Der Befehl
cp reg1, reg2
rechnet im prinzip reg2 - reg1, oder?
cpc funzt aber irgendwie anders, wie hab ich leider noch nicht rausgefunden.
Ja, ich wollte ja nur, dass ihr ungefähr den Ablauf versteht, wie man den Speicher ausliest!Zitat:
Ja, dass es nacheinander passiert, ist mir klar, aber am Ende kann in r16 ja nicht "Hallo!" stehen, oder? Denn "Hallo!" braucht ja nunmal 6 Bytes. Also steht am Ende im Register nur ein "!"?
Ok, hier kommt die Lösung!
Jetzt erklärt mir bitte die einzelnen Segmente des Codes!Code:.include "m8def.inc"
.def lpm_reg = r0
.def temp = r16
.equ daten_laenge = 6
reset:
stack: ; Stack
ldi temp , LOW (RAMEND) ; LOW-Byte
out SPL , temp
ldi temp , HIGH (RAMEND) ; HIGH-Byte
out SPH , temp
z_register:
ldi ZL , LOW (daten * 2) ; Z-Register laden, mit der Adresse der Daten
ldi ZH , HIGH (daten * 2)
main:
lpm ; Daten laden
mov temp , lpm_reg ; in temp verschieben
adiw ZL , 1 ; Z um eins erhöhen
ldi temp , LOW ((daten * 2) + daten_laenge) ; vergleiche LOW-Byte
cp ZL , temp
ldi temp , HIGH ((daten * 2) + daten_laenge) ; vergleiche HIGH-Byte
cpc ZH , temp
breq ende ; springe zu ende, wenn letztes Byte ausgelesen
rjmp main ; nochmal
ende: ; Endschleife
rjmp ende
daten: ; Daten
.DB "Hallo!"
Ich kann dir leider nicht sagen, was das hier bedeutet
Da ich das mit dem unteren und oberen Byte ja immer noch nicht verstanden habe :(Code:ldi temp , LOW ((daten * 2) + daten_laenge) ; vergleiche LOW-Byte
cp ZL , temp
ldi temp , HIGH ((daten * 2) + daten_laenge) ; vergleiche HIGH-Byte
cpc ZH , temp
So wie ich das jetzt verstanden habe, sind die Adressen selbst auch 16 Bit.
Die Adresse 0x020F z.B. besteht aus zwei Byte nähmlich:
0x02 - High Byte
0x0F - Low Byte
Der ATmega8 kann aber nur 8-Bit-Zahlen vergleichen. (richtig so?)
Deswegen verglechen wir erstmal Low-Bytes von der Adressen und dann High-Bytes. Siehe die Post von Florian um 13:23
Und wieso dann einmal cp und einmal cpc?
also with carry heißt doch dann mit Übertrag. Was bedeutet in dem Zusammenhang "Übertrag". Ich kenn Übertrag nur beim schriftlichen Rechnen, bspw. beim Addieren, wenn die oberen beiden Zahlen > 9 sind, dann muss man bei sagen wir mal 10 ne 0 hinschreiben (unterm strich) und dann 1 als übertrag, die wir dann mitaddieren.
Hallo, o weh, es kommt Knüppeldick!
Ich erlaube mir einen Auszug aus www.avr-asm-tutorial.net zu zitieren, damit
Ihr hoffe ich sieht was wir hier machen!
Thomas hat schon richtig erkannt, was cp macht, hat sich aber noch nicht mit SREGZitat:
Addition, Subtraktion und Vergleich
Ungeheuer schwierig in Assembler ist Addieren, Dividieren und Vergleichen. Zart-besaitete Anfänger sollten sich an dieses Kapitel nicht herantrauen. Wer es trotzdem liest, ist übermütig und jedenfalls selbst schuld.
Um es gleich ganz schwierig zu machen, addieren wir die 16-Bit-Zahlen zu den Registern R1:R2 die Inhalte von R3:R4 (Das : heißt nicht Division! Das erste Register gibt das High-Byte, das zweite nach dem : das Low-Byte an).
ADD R2,R4 ; zuerst die beiden Low-Bytes
ADC R1,R3 ; dann die beiden High-Bytes
Anstelle von ADD wird beim zweiten Addieren ADC verwendet. Das addiert auch noch das Carry-Bit dazu, falls beim ersten Addieren ein Übertrag stattgefunden hat. Sind sie schon dem Herzkasper nahe?
Wenn nicht, dann kommt jetzt das Subtrahieren. Also alles wieder rückwärts und R3:R4 von R1:R2 subtrahiert.
SUB R2,R4 ; Zuerst das Low-Byte
SBC R1,R3 ; dann das High-Byte
Wieder derselbe Trick: Anstelle des SUB das SBC, das zusätzlich zum Register R3 auch gleich noch das Carry-Bit von R1 abzieht. Kriegen Sie noch Luft? Wenn ja, dann leisten sie sich das folgende: Abziehen ohne Ernst!
Jetzt kommt es knüppeldick: Ist die Zahl in R1:R2 nun größer als die in R3:R4 oder nicht? Also nicht SUB, sondern CP, und nicht SBC, sondern CPC:
CP R2,R4 ; Vergleiche untere Bytes
CPC R1,R3 ; Vergleiche obere Bytes
Wenn jetzt das Carry-Flag gesetzt ist, kann das nur heißen, dass R3:R4 größer ist als R1:R2. Wenn nicht, dann eben nicht.
so richtig auseinander gesetzt
Gruß Sebastian
Also Thomas!
Ja klar! *lol*Zitat:
So wie ich das jetzt verstanden habe, sind die Adressen selbst auch 16 Bit.
Das Adressregister ist 16Bit, da man sonst die ganzen Flashbytes nicht aufrufen könnte, sondern nur 255, das wäre etwas wenig! ;o)
Genau richtig!Zitat:
Der ATmega8 kann aber nur 8-Bit-Zahlen vergleichen. (richtig so?) Deswegen verglechen wir erstmal Low-Bytes von der Adressen und dann High-Bytes.
Nochmal ganz langsam:
ldi temp , LOW ((daten * 2) + daten_laenge)
daten ist die Adresse, zu der gesprungen werden soll.
Das nimmt man wie gewohnt mal zwei.
Dazu addieren wir dann 6 (Bytes), um das Ende festzulegen.
Das vergleichen wir dann mit der Funktion cp mit ZL, dem LOWbyte.
Das ganze dann nochmal mit dem Highbyte.
Fertig, das ist alles!