Forum: Mikrocontroller und Digitale Elektronik AVR-Assemblerbefehle ADD bzw. SUBI versus INC


von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hallo zusammen,

frage mich gerade wozu der INC-Befehl gut sein soll, wenn ich doch mit
SUBI Rd,-1 das gleiche erreiche. Ich weiß der INC-Befehl beeinflußt 
zusätzlich zum ADD-Befehl nicht die Flags H und C.

Aber wozu dient dann der INC-Befehl im Besonderen ?

Die Befehlsbeschreibung hilft mir leider nicht weiter.

..., thus allowing the INC instruction to be used on a loop counter in 
multipleprecision computations.
...

Ein gutes Beispielprogrammschnipsel hönnte mir vielleicht auch helfen.
Aber dieses leider nicht :

Example:
1
  clr r22     ; clear r22
2
loop: 
3
  inc r22     ; increment r22
4
...
5
  cpi r22,$4F ; Compare r22 to $4f
6
  brne loop   ; Branch if not equal
7
  nop         ; Continue (do nothing)

Bernd_Stein




INC – Increment

Description:
Adds one -1- to the contents of register Rd and places the result in the 
destination register Rd.
The C Flag in SREG is not affected by the operation, thus allowing the 
INC instruction to be used on a loop counter in multiple-
precision computations.
When operating on unsigned numbers, only BREQ and BRNE branches can be 
expected to perform consistently. When
operating on two’s complement values, all signed branches are available.

Bernd_Stein
von Bastler (Gast)


Lesenswert?

inc und dec gehen auch bei R0 - R15
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Bastler schrieb:
> inc und dec gehen auch bei R0 - R15
>
Oh ja danke,

das habe ich wieder mal übersehen. Aber das ist hiermit wohl nicht 
gemeint oder ?

..., thus allowing the INC instruction to be used on a loop counter in
multipleprecision computations.
...

Bernd_Stein
von Stefan E. (sternst)


Lesenswert?

Bernd Stein schrieb:
> ..., thus allowing the INC instruction to be used on a loop counter in
> multipleprecision computations.

Angenommen du willst zwei 128-Bit-Werte addieren, dann kannst du das in 
einer Schleife machen, bei der der Schleifenzähler (16 Durchläufe) mit 
inc manipuliert wird. So bleibt das Carry von Durchlauf zu Durchlauf 
erhalten, und muss nicht extra gesichert werden.
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Stefan Ernst schrieb:
> Bernd Stein schrieb:
>> ..., thus allowing the INC instruction to be used on a loop counter in
>> multipleprecision computations.
>
> Angenommen du willst zwei 128-Bit-Werte addieren, dann kannst du das in
> einer Schleife machen, bei der der Schleifenzähler (16 Durchläufe) mit
> inc manipuliert wird. So bleibt das Carry von Durchlauf zu Durchlauf
> erhalten, und muss nicht extra gesichert werden.
>
Auch wenn ich mir diesen Programmschnipsel nicht vorstellen kann, denke 
ich das genau so etwas damit gemeint sein muß.

Danke.

Bernd_Stein
von Vuvuzelatus (Gast)


Lesenswert?

>Ich weiß der INC-Befehl beeinflußt
>zusätzlich zum ADD-Befehl nicht die Flags H und C.

Genau, das ist der wesentliche Unterschied, der die clevere Verwendung 
von inc und dec als Loop-Counter ermöglicht.

Im Artikel AVR-Arithmetik finden sich einige Codes, in denen davon 
Gebrauch gemacht wird, darunter die 16-Bit-mal-32-Bit-Multiplikation. 
Der letzte Teil der Routine sieht so aus:

1
_umu1: ldi  i0, 16
2
       clr  t0
3
       clr  t1
4
       ror  a1
5
       ror  a0
6
_umu2: brcc _umu3
7
       add  a2, b0
8
       adc  a3, b1
9
       adc  t0, b2
10
       adc  t1, b3
11
_umu3: ror  t1
12
       ror  t0
13
       ror  a3
14
       ror  a2
15
       ror  a1
16
       ror  a0
17
       dec  i0
18
       brne _umu2
19
       ret

Das Stück zwischen dem Label "_umu2" und ret ist eine Schleife mit i0 
als Loop-Counter. Sie wird 16 mal durchlaufen. Jeder ror-Befehl setzt 
das C-Flag, aber das "dec i0" in der drittletzten Zeile wirkt sich 
nicht darauf aus. Dadurch bleibt der Zustand des C-Flags für den 
nächsten Schleifendurchlauf erhalten, und das ist genau das, was man 
sich wünscht. Zum Testen, ob die Schleife verlassen werden kann, wird 
das Z-Flag herangezogen (brne in der vorletzten Zeile). Das 
funktioniert, weil das Z-Flag einerseits von dec gesetzt wird, und 
andererseits nirgendwo sonst eine Bedeutung hat. Beim C-Flag ist es 
genau umgekehrt.

http://www.mikrocontroller.net/articles/AVR_Arithmetik#16_Bit_.2B_16_Bit
von Hannes L. (hannes)


Lesenswert?

Bernd Stein schrieb:
> Die Befehlsbeschreibung hilft mir leider nicht weiter.

Hmmm, dann schau doch bitte auch mal hin, welche Flags im SREG von den 
einzelnen Operatoren beeinflusst werden. Und dann schau Dir bitte mal 
genau an, welche Branches von welchen Flags abhängen. Dann wirst Du 
erkennen, wie vorteilhaft es ist, Schleifenzähler programmieren zu 
können, die das Carry-Flag in Ruhe lassen.

...
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

> Hannes Lux schrieb:
>> Bernd Stein schrieb:
>> Die Befehlsbeschreibung hilft mir leider nicht weiter.
>
> Hmmm, dann schau doch bitte auch mal hin, welche Flags im SREG von den
> einzelnen Operatoren beeinflusst werden. Und dann schau Dir bitte mal
> genau an, welche Branches von welchen Flags abhängen. Dann wirst Du
> erkennen, wie vorteilhaft es ist, Schleifenzähler programmieren zu
> können, die das Carry-Flag in Ruhe lassen.
>
Du weißt doch, wenn ich versuche meine eigenen Schlüsse daraus zu 
ziehen, kommt meistens nicht das wesentliche zum Vorschein.
Deshalb lass ich mir lieber von Leuten die dies schon wissen zeigen,
was das Wesentliche dabei ist.

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