Forum: Mikrocontroller und Digitale Elektronik AVR while / do-while Schleife in Assembler


von O. A. (sokrates1989)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein paar Aufgaben vorliegen bei denen ich etwas Hilfe bräuchte.

und zwar möchte ich einen Zähler welcher von 1 bis 10 zählt 
programmieren.

ich habe bereits ein Programm gemacht welches dies macht. Allerdings 
weiß ich nicht ob mein Code einer do-while oder while Schleife 
entpsricht.

Wie würde in Assembler eines davon aussehen? Und entspricht meines einem 
davon?

Danke!
1
;+------------------------------------------------------------------------------
2
;| Titel : Aufgabe 1b
3
;| Prozessor : ATmega8
4
;| Frequenz : 3,6864 MHz
5
;| Datum :
6
;| Autor : Ostap Antonez,
7
;| Guppe :
8
;|
9
;| ...
10
;+------------------------------------------------------------------------------
11
12
.include "m8def.inc" 
13
.DEF zaehler = r16
14
.DEF speicher = r18
15
16
;-------------------------------------------------------------------------------
17
; Reset and Interruptvectoren ; VNr. Beschreibung
18
begin:
19
 
20
rjmp main ; 1 POWER ON RESET
21
reti ; 2 Int0-Interrupt
22
reti ; 3 Int1-Interrupt
23
reti ; 4 TC2 Compare Match
24
reti ; 5 TC2 Overflow
25
reti ; 6 TC1 Capture
26
reti ; 7 TC1 Compare Match A
27
reti ; 8 TC1 Compare Match B
28
reti ; 9 TC1 Overflow
29
reti ; 10 TC0 Overflow
30
reti ; 11 SPI, STC Serial Transfer Complete
31
reti ; 12 UART Rx Complete
32
reti ; 13 UART Data Register Empty
33
reti ; 14 UART Tx Complete
34
reti ; 15 ADC Conversion Complete
35
reti ; 16 EEPROM Ready
36
reti ; 17 Analog Comparator
37
reti ; 18 TWI (I²C) Serial Interface
38
reti ; 19 Store Program Memory Ready
39
;--------------------------------------------------------------------------------
40
41
; Aufwärtszähler von 1 bis 10
42
; Die Werte sollen in r18= Speicher gespeichert werden.
43
;--------------------------------------------------------------------------------
44
; Start
45
46
main: 
47
48
ldi r16 , LOW(RAMEND)   ; Init Stackpointer Low
49
out SPL , r16       ; init Stack
50
ldi r16 , HIGH(RAMEND)   ; init Stackpointer High
51
out SPH , r16       ; init Stack
52
53
ldi zaehler, 0x01    ; setze Zähler auf den Wert "1"
54
55
mainloop:
56
57
inc zaehler        ; erhöhe den Wert im Zähler um den Wert "1"
58
59
cpi zaehler, 10      ; vergleiche den Zähler mit dem Wert "10", setze Z-Flag
60
61
mov speicher, zaehler  ; bringe den Wert ins Register 18
62
63
breq naechste_zaehlung  ; springe zur nächsten Zählung wenn der Wert "10" erreicht ist.
64
65
rjmp mainloop      ; kehre zurück zur mainloop
66
67
68
69
naechste_zaehlung: 
70
71
ldi zaehler, 0x01    ; der Zähler wird wieder auf "1" gesetzt
72
73
rjmp mainloop      ; kehre zurück zur mainloop

von Einer K. (Gast)


Lesenswert?

Ich sehe gar nicht, wo deine Schleife anfängt und aufhört!

Wenigstens so Kommentare/Lables wie:
1. Schleifenkopf
2. Schleifenkörper
3. Schleifenfuß

Würde ich erwarten.
Klar abgegrenzt.
Und wenn dir dann noch klar ist, was der Unterschied zwischen while und 
do-while sein könnte, dann hast du schon fast 100 Punkte

(bin jetzt aber nicht der Assembler Spezi, dass ich dir das aus dem 
Ärmel schütteln könnte)

von guest (Gast)


Lesenswert?

Asssembler ist zwar nicht so ganz mein Fall, aber das sieht rudimentär 
nach Variante b) aus, zählt allerdings von 2 bis 10

von Markus F. (mfro)


Lesenswert?

was könnte denn wohl der Unterschied zwischen "do ... while (Bedingung)" 
und "while (Bedingung) do" sein?

Hinweis: in altmodischem Informatiker-Deutsch heisst das "nicht 
abweisende" beziehungsweise "abweisende" Schleife.

von derjaeger (Gast)


Lesenswert?

oder kopfschleife und fußschleife

von Michael U. (amiga)


Lesenswert?

Hallo,

zum etwas chaotischen Ablauf wurde ja schon was geschrieben.
Ansonste ist es meiner Meinung nach eine Do-While weil die Schleife 
mindestens einmal durchlaufen wird. Bei einer While müßte die Abfrage 
auf den Endwert am Anfang stehen, so daß der Inhalt der Schleife 
garnicht ausgeführt wird wenn die Bedingung nicht erfüllt ist.
1
mainloop:
2
3
ldi zaehler, 0x01    ; setze Zähler auf den Wert "1"
4
5
while_begin:         ; Beginn Schleife
6
cpi zaehler, 10      ; Bedingung abfragen
7
breq weiter          ; wenn erfüllt raus aus der Schleife
8
9
inc zaehler
10
mov speicher, zaehler
11
rjmp while_begin     ; Ende Schleife  
12
13
weiter:              ; Programm hinter der While Schleife fortsetzen  
14
15
rjmp mainloop        ; hier nur kehre zurück zur mainloop und zähle neu

Gruß aus Berlin
Michael

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

O. A. schrieb:

> Allerdings
> weiß ich nicht ob mein Code einer do-while oder while Schleife
> entpsricht.

Dann sind dir zwei Sachen nicht klar:
1) Was der springende Punkt beim Unterschied zwischen "while" und "do 
while" ist
2) Was dein Programm eigenlich tut.

Nicht gut...

> Wie würde in Assembler eines davon aussehen? Und entspricht meines einem
> davon?

Ja, das ist eine Schleife vom Typ "do while".

Übrigens: der entscheidende Trick, mit dem man in Assembler am 
effizientesten aus "do while" ein "while" macht, ist direkt suggestiv in 
der Aufgabenstellung formuliert. Man braucht die eigentlich bloß 
verstehend zu lesen und stellt fest, dass die Aufgabenstellung den 
wesentlichen Punkt der Lösung bereits selber liefert...

Wenn man nun noch sinnvolle Labels (im Sinne der Aufgabenstellung) 
verwendet, sieht dein Programm derzeit prinzipiell so aus (den mit der 
Schleife nicht direkt zusammenhängenden Kram habe ich weggelassen):
1
init:
2
 ldi zaehler, 0x01    ; setze Zähler auf den Wert "1"
3
4
do:
5
 inc zaehler        ; erhöhe den Wert im Zähler um den Wert "1"
6
7
 cpi zaehler, 10      ; vergleiche den Zähler mit dem Wert "10", setze Z-Flag
8
9
 mov speicher, zaehler  ; bringe den Wert ins Register 18
10
11
while:
12
 breq reinit  ; springe zur nächsten Zählung wenn der Wert "10"  erreicht ist.
13
 rjmp do      ; kehre zurück zur mainloop
14
15
reinit:
16
 ldi zaehler, 0x01    ; der Zähler wird wieder auf "1" gesetzt
17
 rjmp do      ; kehre zurück zur mainloop

Das würde man aus Gründen der Effizienz, Korrektheit und Lesbarkeit 
erstmal so umformulieren:
1
init:
2
 ldi zaehler, 0x01    ; setze Zähler auf den Wert "1"
3
4
do:
5
 mov speicher, zaehler  ; bringe den Wert ins Register 18
6
 inc zaehler        ; erhöhe den Wert im Zähler um den Wert "1"
7
8
while:
9
 cpi zaehler, 10      ; vergleiche den Zähler mit dem Wert "10", setze Z-Flag
10
 brne do  ; springe zur Schleife, wenn der Wert "10"  nicht erreicht ist.
11
 rjmp init     ; reinitialisiere die Schleife

Wie man nun mit einer einzigen zusätzlichen Zeile eine Schleife vom Typ 
"while" daraus macht, überlasse ich dir. Beachte die Aufgabenstellung, 
da steht das, wie gesagt, schon drin.

von guest (Gast)


Lesenswert?

c-hater schrieb:
> Korrektheit

Naja.
Während sein Beispiel von 2 bis 10 zählt, zählt Deines von 1 bis 9.
Soviel zum Thema Korrektheit.

von Ralf (Gast)


Lesenswert?

Und schon wieder wurden die Hausaufgaben von jemand anderes gemacht!

von Egon N. (egon2321)


Lesenswert?

Ralf schrieb:
> Und schon wieder wurden die Hausaufgaben von jemand anderes
> gemacht!

Naja, wer programmiert ernsthaft noch Schleifen direkt in ASM?!

von S. R. (svenska)


Lesenswert?

Egon N. schrieb:
> Naja, wer programmiert ernsthaft noch Schleifen direkt in ASM?!

Ich. Davon abgesehen geht es bei Hausaufgaben nicht um sinnvollen 
Produktivcode im Unternehmen, sondern ums Lernen.

von Norbert T. (atos)


Lesenswert?

Ich ebenfalls.

von guest...Rainer (Gast)


Lesenswert?

Egon N. schrieb:
> Naja, wer programmiert ernsthaft noch Schleifen direkt in ASM?!

Ich auch :-)

von Thomas F. (igel)


Lesenswert?

Egon N. schrieb:
> Naja, wer programmiert ernsthaft noch Schleifen direkt in ASM?

Und ich.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Ja, ich auch. Aber nur wenns schnell gehen muss. Und dann mach' ich auch 
noch gleich ein loop-unrolling ;-)
1
inc zaehler
2
inc zaehler
3
inc zaehler
4
inc zaehler
5
inc zaehler
6
inc zaehler
7
inc zaehler
8
inc zaehler
9
inc zaehler

Gruss
WK

von Heinz V. (heinz_v)


Lesenswert?

me2

von O. A. (sokrates1989)


Lesenswert?

Danke soweit.!

von Arno (Gast)


Lesenswert?

Wenn der Lehrer die Aufgabe schon so seltsam formuliert...

[quote]Es sollen die Zahlen von 1 bis 10 programmiert werden[/quote]

...ist es kein Wunder, dass die Ergebnisse seiner Schüler auch nicht 
weniger chaotisch werden.

MfG, Arno

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.