Assembler Programm Frage

#4101016
Lesenswert?
• ▲
▼
Bert Siegfried schrieb:
> Hi,
>
> warum ist für obiges Programm die Antwort (4,500) falsch? Dies führt
> doch auch zu 1000 Ausführungen, genauso wie (16,125)?
>
> Gruss Bert

Hallo Bert,

das Listing ist sehr wahrscheinlich ein Assembler Programm für einen 
8bit AVR µC. r18 und r19 sind somit 8bit Register. Damit ist das laden 
von 500 nicht möglich. So mal die Vermutung.

Der Vergleich mit brne in Zusammenhang mit dem subi r18, 2 setzt eine 
gerade Zahl für Value1 vorraus.

Somit kann nur Antwort 2 (16,125) richtig sein

Gruß Thomas
(Firma: Vescomp) #4101137
Lesenswert?
• ▲
▼
Bert Siegfried schrieb:
> value2 wird ja auch immer nur subi r19, 0x01. Muss das mal mit dem
> Simulator testen.

 Brauchst du nicht, Thomas hat es dir schon erklart, aber hier
 nochmal:

 1) 4, 500 - geht nicht, auch ein ATMega 128 hat nur 8-bit Register.
 2) 16, 125 - Richtig, weil: 16/2 = 8*125 = 1000
 3) 200, 5 - Falsch, weil: 200/2 = 100 * 5 = 500
 4) 125, 16 - 125 ist ungerade Zahl, geht auch nicht
    (und aus diesem Loop kommst du nie raus).
(Firma: Vescomp) #4101590
Lesenswert?
• ▲
▼
Peter Dannegger schrieb:
> Immer diese praxisfernen Beispiele.
> So würde das ein Programmierer nie schreiben, sondern so:#define val
> 1000
>   ldi r18, low(val)
>   ldi r19, high(val)
> m1:
>   subi r18, low(1)
>   sbci r19, high(1)
>   brne m1

 Süß, aber beim AVR unnötig.
1
#define val 1000
2
  ldi r24, low(val)
3
  ldi r25, high(val)
4
m1:
5
  sbiw  r24, 1
6
  brne  m1

 Trotzdem cute, gefällt mir.
Gast #4101966
Lesenswert?
• ▲
▼
Peter Dannegger schrieb:

> Immer diese praxisfernen Beispiele.

Harharhar...

> So würde das ein Programmierer nie schreiben, sondern so:
[...]

Jetzt wird mir klar, warum du unfähig bist, gestaffelte Zählschleifen 
korrekt zu bewerten. Du machst es einfach immer so, wie es dein 
geliebter Compiler machen würde...

Aber nein, in manchen Fällen ist eine gestaffelte Schleife halt die 
bessere Lösung, z.B. wenn man in der inneren Schleife die eine Sache mit 
der Häufigkeit X erledigen will, in der äußeren Schleife aber eine 
andere Sache mit der Häufigkeit Y.

Übrigens ein sehr schönes Beispiel für die mangelnde Intelligenz von 
Compilern. KEINER ist in der Lage, die Ambition zweier Quasi-Parallel 
laufender Vorgänge mit unterschiedlicher Häufigkeit in einer Schleife 
aus dem C-Code zu erahnen und die Optimierung als gestaffelte Schleife 
zu wählen. Ich liebe es, wenn die C-Lover selber die Munition liefern, 
mit denen ich sie beschiessen kann...
#4103839
Lesenswert?
• ▲
▼
Peter Dannegger schrieb:
> Immer diese praxisfernen Beispiele.
> So würde das ein Programmierer nie schreiben, sondern so:
>
1
> #define val 1000
2
>   ldi r18, low(val)
3
>   ldi r19, high(val)
4
> m1:
5
>   subi r18, low(1)
6
>   sbci r19, high(1)
7
>   brne m1
8
>

Peter, ich bin sicher nicht derjenige der grad Deinen Code in Frage 
stellen würde, aber bricht das nicht bei 0xFF bereits ab? Wegen

(bei val 0x100, d.h. r18=0x00, r19=0x01)

subi r18, 1 -> r18=0xff, CF=1, ZF=0
sbci r19, 0 -> r19=0x00, CF=0, ZF=1
brne -> false wegen ZF=1 -> Kein Sprung.


Ich hätte gemeint, dass ein dec r18 vor der Schleife (mit vorherigem 
oder implizitem Sicherstellen von val>=1 beim Start) mit brsh als 
Schleifenbedingung korrekt wäre. Also, Abbruch auf CF=1 statt ZF=1, und 
das dec halt weil wir bis "-1" statt bis 0 zählen müssen.

Oder wo hab ich den Denkfehler?
#4103848
Lesenswert?
• ▲
▼
Heinz L. schrieb:
> subi r18, 1 -> r18=0xff, CF=1, ZF=0
> sbci r19, 0 -> r19=0x00, CF=0, ZF=1
> brne -> false wegen ZF=1 -> Kein Sprung.
>
> Ich hätte gemeint, dass ein dec r18 vor der Schleife (mit vorherigem
> oder implizitem Sicherstellen von val>=1 beim Start) mit brsh als
> Schleifenbedingung korrekt wäre. Also, Abbruch auf CF=1 statt ZF=1, und
> das dec halt weil wir bis "-1" statt bis 0 zählen müssen.

Wird ZF bei gesetztem CF denn 1?

Datenblatt sagt:
SBCI Rd, K => "Rd ← Rd - K - C"

Heißt für mich:
r19 ← 0x00 - 0 - 1

r19 ← 0xFF

Woraus doch folgt:
CF = 1, ZF = 0
#4103852
Lesenswert?
• ▲
▼
r19 ist vor der Schleife ja 1, nicht 0. 0x100 ist der Wert von val vor 
dem Schleifendurchgang, mit r19=1, r18=0. r18 wird mit "subi r18, 1" um 
1 erniedrigt, damit das CF gesetzt. Mit "sbci r19, 0" wird von r19 0 und 
das CF (gesetzt) abgezogen, also 1 - 0 - 1 = 0, damit dann CF=0 und 
ZF=1.
#4103855
Lesenswert?
• ▲
▼
Heinz L. schrieb:
> r19 ist vor der Schleife ja 1, nicht 0. 0x100 ist der Wert von val vor
> dem Schleifendurchgang, mit r19=1, r18=0. r18 wird mit "subi r18, 1" um
> 1 erniedrigt, damit das CF gesetzt. Mit "sbci r19, 0" wird von r19 0 und
> das CF (gesetzt) abgezogen, also 1 - 0 - 1 = 0, damit dann CF=0 und
> ZF=1.

Ok, mein Fehler.
Ich habe nicht alles bedacht, als ich meine Ausführung schrieb.

Heinz L. schrieb:
> (bei val 0x100, d.h. r18=0x00, r19=0x01)
>
> subi r18, 1 -> r18=0xff, CF=1, ZF=0
> sbci r19, 0 -> r19=0x00, CF=0, ZF=1
> brne -> false wegen ZF=1 -> Kein Sprung.

Hier nochmal, aber diesmal (hoffentlich) richtig bedacht. Ich habe
r18 bzw. r19 durch den jeweils aktuellen Wert ersetzt
angefangen bei 0x102.

subi 0x02, 0x01 -> 0x01, CF=0, ZF=0
sbci 0x01, 0x00 -> 0x01, CF=0, ZF=0
brne => Sprung

subi 0x01, 0x01 -> 0x00, CF=0, ZF=1
sbci 0x01, 0x00 -> 0x01, CF=0, ZF=0
brne => Sprung

subi 0x00, 0x01 -> 0xff, CF=1, ZF=0
sbci 0x01, 0x00 -> 0x00, CF=0, ZF=1
brne => kein Sprung

also kein weiterer Durchlauf.
Gast #4104052
Lesenswert?
• ▲
▼
wo bleibt c-hater wenn man ihn mal braucht?

Marcel Papst schrieb:
> subi 0x00, 0x01 -> 0xff, CF=1, ZF=0
> sbci 0x01, 0x00 -> 0x00, CF=0, ZF=1
> brne => kein Sprung

das ist falsch, weil laut der Beschreibung zum SBCI-Befehl:
1
[the Z-flag] remains unchanged when the result is zero; cleared otherwise

Oder auf deutsch: der SBCI-Befehl lässt das Z-Flag unverändert wenn das 
Resultat null ist und löscht das Z-Flag wenn das Resultat nicht null 
ist.

Dies genau aus diesem Grund: damit bei einer Subtraktion über 2 oder 
mehr Bytes das Z-Flag genau dann gesetzt ist, wenn alle Teilergebnisse 
null sind (und damit das Gesamtresultat null ist.)
(Firma: Vescomp) #4104053
Lesenswert?
• ▲
▼
Marcel Papst schrieb:
> subi 0x02, 0x01 -> 0x01, CF=0, ZF=0
> sbci 0x01, 0x00 -> 0x01, CF=0, ZF=0
> brne => Sprung
>
> subi 0x01, 0x01 -> 0x00, CF=0, ZF=1
> sbci 0x01, 0x00 -> 0x01, CF=0, ZF=0
> brne => Sprung
>
> subi 0x00, 0x01 -> 0xff, CF=1, ZF=0
> sbci 0x01, 0x00 -> 0x00, CF=0, ZF=1
> brne => kein Sprung

 Flags und Registerwerte nach Befehlsbearbeitung.
1
  r18 = 2, r19 = 1
2
;==========================================
3
   subi r18, 1      ; r18 = 1 / ZF = 0 / CF = 0
4
   sbci r19, 0      ; r19 = 1 / ZF = 0 / CF = 0  => Sprung
5

6
   subi r18, 1      ; r18 = 0 / ZF = 1 / CF = 0
7
   sbci r19, 0      ; r19 = 1 / ZF = 0 / CF = 0  => Sprung
8

9
   subi r18, 1      ; r18 = FF / ZF = 0 / CF = 1
10
   sbci r19, 0      ; r19 =  0 / ZF = 0 / CF = 0  => Sprung
11
;===========================================

 Also doch weiterer Durchlauf.

 Und ThomasK hat dir erklart, warum das so ist.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

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.