AVR while / do-while Schleife in Assembler

OP #5383770
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
Angehängte Dateien:
Gast #5383796
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)
#5383813
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
Gast #5383947
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.
Gast #5389111
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren