Forum: Mikrocontroller und Digitale Elektronik 6 einfache Assembler Zeilen gehen nicht.


von Silver69 (Gast)


Lesenswert?

Ich möchte von einem Register, R17, die konstante 100 abziehen. Ist das 
Ergebnis kleiner Null, soll es Null sein:
1
  ldi r17 , 156
2
    subi r17, 100
3
4
    in r16, sreg
5
    sbrc r16,0
6
    clr r17
7
    nop

Wieso funktioniert das so nicht?

von Gast (Gast)


Lesenswert?

Ich kann nichts Fehlerhaftes daran finden. Vielleicht glaubst du 
irrtümlich, das es nicht funktioniert?

Du kannst es aber einen Tick einfacher machen:
1
    ldi  r17 , 156
2
    subi r17, 100
3
    brcc _IsGreaterZero
4
    clr  r17
5
_IsGreaterZero:
6
    nop

von peterhoppe59 (Gast)


Lesenswert?

Du willst r17 testen, testest aber das r16 (Statusregister) auf 0.
Du testest auf 0, nicht auf <0.

ldi r17,..
subi r17,..
brlo blah   ;Ohne Vorzeichen!
.
.
blah:
clr r17

von (prx) A. K. (prx)


Lesenswert?

@peterhoppe59: Er hat zwar den Trick mit den bedingten Sprüngen abhängig 
von den Flags noch nicht kapiert, aber es ist durchaus möglich, einzelne 
Bits vom Statusregister explizit zu testen. Exakt das macht er hier mit 
R16.

von Gast (Gast)


Lesenswert?

>...testest aber das r16 (Statusregister) auf 0.

Nein, er testet das Bit Nr. 0 des SREG. Das ist das Carry-Bit.

von Volker G. (voga2073)


Lesenswert?

@peterhoppe59: ...und er testet nicht r16, sondern die letzte Operation, 
die das Carry-Flag gesetzt hat und das war subi (siehe AVR-Datenblatt).

von Michael F. (nestandart)


Lesenswert?

1
ldi r17,156
2
subi r17,100 ; Subtract 100 from r17
3
brpl R17_IS_POSITIVE ; Branch if r17 positive
4
clr r17
5
R17_IS_POSITIVE:

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Michael Fr. wrote:
>
1
> brpl R17_IS_POSITIVE ; Branch if r17 positive
2
>

Nein. Das ist falsch: 10-200 ist zB positiv in 8-Bit Arithmetik (da 
66.7=0)

Der richtige Vergleich geht auf's Carry, also BRCC oder BRCS bzw. BRLO 
oder BRSH. Wobei die beiden letzteren nur Alias für die beiden ersteren 
sind.

Johann

von Peter H. (peterhoppe59)


Lesenswert?

Gast wrote:
>>...testest aber das r16 (Statusregister) auf 0.
>
> Nein, er testet das Bit Nr. 0 des SREG. Das ist das Carry-Bit.

Ja, Ihr habt Recht. Sorry für die Verwirrung.

MFG Peter

von Silver69 (Gast)


Lesenswert?

Ich wollte keinen Sprung Befehl benutzen, da ich diese Zeilen 4 mal 
nacheinander ausführen muss. Ich müsste dann also 4 Sprungmarken 
definieren und das wollte ich vermeiden. Aber Egal: Als ich gemerkt 
habe, dass es nicht funktioniert, HABE ich schon die Variante mit 
Sprungmarke getestet, das hat aber auch nicht funktioniert.

Stelle ich die Zeilen am Anfang des Programms, funktionieren sie (mit 
dem Debugger in Einzelschritt) prächtig!

An der Richtigen Stelle, wird das "CLR R17" IMMER ausgeführt. R17 ist 
nach den Anweisungen also immer 0.

Das einzige, was ich mir jetzt vorstellen könnte, ist dass nach dem SUBI 
das Programm von einem Interrupt unterbrochen wird und dass die 
Interrupt-Routine das C-Flag setzt. Jedoch sichere ich eigentlich in der 
Interrupt-Routine die Status Flags....

von Silver69 (Gast)


Lesenswert?

So, habe den Fehler gefunden.

Die Zahl in R17 war ursprünglich eine 2 Byte Zahl. Nachdem ich aber 100 
subtrahiere, wurde sie zur 1 Byte Zahl. Also wurde bei SUBI R17,100 Das 
Carry Flag IMMER gesetzt. Deshalb dachte ich fälschlicherweise, es wäre 
ein Fehler in den paar Zeilen.

Die Lösung: ich ziehe von der 2 Byte Zahl in R17 UND R18 100 ab. R18 
muss danach 0 sein, ist es 255, fand ein Überlauf statt...

Klappt Wunderbar.

von Gast (Gast)


Lesenswert?

Man kann die Sprungbefehle (br**, rjmp) auch ohne Sprungmarken 
verwenden:
1
    ldi  r17, 156
2
    subi r17, 100
3
4
    brcc PC+2         ; PC = program counter
5
    clr  r17
6
7
    nop

>Die Lösung: ich ziehe von der 2 Byte Zahl in R17 UND R18 100 ab. R18
>muss danach 0 sein, ist es 255, fand ein Überlauf statt...

Hoffentlich machst Du das ordentlich, sonst liegt der nächste 
"unerklärliche" Fehler schon auf der Lauer.

von Silver69 (Gast)


Lesenswert?

Das mit dem PC + 2 ist gut, gefällt mir... ist fast wie früher ;-)

Denke schon dass ich das Ordentlich mache, bisher funktioniert zumindest 
alles. Naja fast alles. Das nächste Problem lauert schon in der Ecke und 
wartet nur darauf losgelassen zu werden. ;-) Hat aber nichts hiermit zu 
tun...

Vielen Dank für Eure Hilfe!!!

von Kachel - Heinz (Gast)


Lesenswert?

> Das mit dem PC + 2 ist gut, gefällt mir... ist fast wie früher ;-)

Stimmt, das ist gut, besonders für Macros. Achte aber darauf, welche 
Befehle Du damit überspringst. Denn nicht jeder Befehl passt in ein 
Word. Wenn man das nicht berücksichtigt, dann hat man sich schnell mal 
verzählt.

Was hast Du eigentlich für eine Motivation, Labels einsparen zu wollen? 
Labels fressen doch keine Ressourcen im AVR, und im PC verriecht sich 
deren Ressourcenverbrauch.

KH

von spess53 (Gast)


Lesenswert?

Hi

>Stimmt, das ist gut, besonders für Macros.

In Macros kannst du ganz normal Labels einsetzen.

MfG Spess

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.