AVR-Assemblerbefehle ADD bzw. SUBI versus INC

OP (Firma: Anscheinend Corner-Cases ;-)) #2532696
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
#2532750
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.
OP (Firma: Anscheinend Corner-Cases ;-)) #2532795
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
Gast #2533339
>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
#2533411
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.

...
OP (Firma: Anscheinend Corner-Cases ;-)) #2533643
> 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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.