Benötige Bitte eine Erklärung über dieses ASM Code

Gast #3974270
Lesenswert?

Hi,

und zwar machen wir gerade in unserer Schule ein bisschen Assembler mit 
einem ATmega32. Ich habe vieles dazu bereits verstanden, nur hätte ich 
eine Frage und zwar für was ist dieser Bereich zuständig?

So wie ich das sehe werden in den Speicher Bereiche definiert, aber vor 
was diese gut sind ist mir nicht ersichtlich.

gruß

Christof


Bereich:
1
####################################
2

3
 .ORG  0x0000               
4
 rjmp  start   ;springe zu start             
5
 .ORG  0x0002
6
 rjmp  zaehlen ;springe zu zaehlen
7
 .ORG  0x0004
8
 rjmp  null    ;springe zu null
9

10
####################################
11

12
ASM_Code:
13

14

15

16
 .include    "m32def.inc"
17

18

19
 .DSEG              ; definiert den Start eines Datensegmentes
20

21
 zahl:  .BYTE 1          ; Reservierung von einen Byte 
22

23
 .CSEG               ; Datensegment definierung schließen
24

25

26
 .ORG  0x0000               
27
 rjmp  start                
28
 .ORG  0x0002
29
 rjmp  zaehlen
30
 .ORG  0x0004
31
 rjmp  null
32

33
 start:
34
 ldi  r16,LOW(RAMEND)   ; ldi = Lade Register mit Wert;  LOW-Byte der obersten RAM-Adresse 
35
 out  SPL,r16        ; kopiere Register r16 in Stack-Pointer-Register LOW = SPL
36
 ldi  r16,HIGH(RAMEND)  ; HIGH-Byte der obersten RAM-Adresse
37
 out  SPH,r16        ; kopiere Register r16 Stack-Pointer-Register HIGH = SPH
38

39
ldi    r16,0b00001011    ; Lade 00001011 in das Register r16  
40
out    MCUCR,r16      ; --> Eine steigende Flanke am INT0 Pin löst Interrupt aus (Seite66)
41
ldi    r16,0b11000000    ; Lade 11000000 in das Register r16  
42
out    gicr,r16      ; -->  Externer Interrupt 1 Freigabe für INT1 und INT0 (Seite 69)
43

44
cbi    DDRD,2        ; Bit in I/O-Register löschen (auf 0 setzen), PORT D / PIN 2  
45
cbi    DDRD,3        ; Bit in I/O-Register löschen (auf 0 setzen), PORT D / PIN 3  
46
sbi    PORTD,2        ; Bit in I/O-Register setzen  (auf 1 setzen), PORT D / PIN 2  
47
sbi    PORTD,3        ; Bit in I/O-Register setzen  (auf 1 setzen), PORT D / PIN 3  
48

49
ldi    r16, 0xFF         ; Lade 11111111 in das Register r16
50
out    DDRA,r16          ; kopiere register 16 nach PORT DDRA ??richtig??
51

52
ldi    r20,0        ; Lade 00000000 in das Register r20
53

54
sei              ; interrupt aktivieren
55

56
los:    rjmp  los     ; Springe in der Schleife los hin und her
57

58
zaehlen:
59
push  r20              ; Speichere register R20 in den Stack 
60
in    r20,SREG      ; Status Register in R20 kopieren
61
push  r20           ; Speichere register R20 in den Stack 
62
lds    r20,ZAHL          ; Lade Register r20 mit Byte (zahl) aus Datenspeicher
63
inc    r20               ; R20 Inkrementierung 
64
out    PORTA,r20         ; kopiere Register R20 in den PORT A
65
sts    ZAHL,r20      ; Speichere Register R20 in den Datenspeicher (ZAHL)
66
pop    r20          ; LADE vom Stapel(stack) in Register R20
67
out    SREG,r20          ; kopiere Register r20 in das Status Register
68
pop    r20          ; LADE vom Stapel in Register R20
69
reti                      ; Rücksprung von Interrupt - Routine  
70

71
null:
72
push  r20               ; Speichere register R20 in den Stack 
73
in    r20,SREG      ; Status Register in R20 kopieren
74
push  r20          ; Speichere register R20 in den Stack 
75
ldi    r20,0             ; Lade 0 in das Register R20
76
out    PORTA,r20      ; kopiere das Register R20 in den PORT A
77
sts    ZAHL,r20      ; Speichere Register R20 in den Datenspeicher (ZAHL)
78
pop    r20          ; LADE vom Stapel in Register R20
79
out    SREG, r20         ; kopiere Register R20 in das Status Register
80
pop    r20          ; Lade vom Stapel in Register R20 
81
reti                      ; Rücksprung von Interrupt - Routine
#3974274
Lesenswert?

Christof schrieb:
> Hi,
>
> und zwar machen wir gerade in unserer Schule ein bisschen Assembler mit
> einem ATmega32. Ich habe vieles dazu bereits verstanden, nur hätte ich
> eine Frage und zwar für was ist dieser Bereich zuständig?
>
> So wie ich das sehe werden in den Speicher Bereiche definiert,
Wo glaubst du sowas zu sehen? Was genau meinst du damit?

Poste doch mal exakt den Codeteil den du nicht verstehst.
Gast #3974295
Lesenswert?

Du meinst was dieser Auszug bedeutet?

 .ORG  0x0000
 rjmp  start
 .ORG  0x0002
 rjmp  zaehlen
 .ORG  0x0004
 rjmp  null


Das sind die Interrupt Vektoren des ATmega32

0x0000 wird ausgelöst vom Power on Reset also der Punkt an dem Dein 
Programm anfängt

0x0002 Ist der externe Interrupt 0. Wir also ausgelöst wen der Interrupt 
zustande kommt. Ich nehme an Ihr habt einen Puls an diesem Pin den Ihr 
zählen wollt.

0x0004 Ist der externe Interrupt 1. Wir also ausgelöst wen der Interrupt 
zustande kommt. Auch hier nehme ich an das ihr ein Taster dran habt der 
das Zählen zurück setzen soll.

ODER?
Gast #3974311
Lesenswert?

Cyblord ---- schrieb:
> Poste doch mal exakt den Codeteil den du nicht verstehst.

Es geht um den Bereich den Holger erklärt hat.

Holger P. schrieb:
> Das sind die Interrupt Vektoren des ATmega32
>
> 0x0000 wird ausgelöst vom Power on Reset also der Punkt an dem Dein
> Programm anfängt
>
> 0x0002 Ist der externe Interrupt 0. Wir also ausgelöst wen der Interrupt
> zustande kommt. Ich nehme an Ihr habt einen Puls an diesem Pin den Ihr
> zählen wollt.
>
> 0x0004 Ist der externe Interrupt 1. Wir also ausgelöst wen der Interrupt
> zustande kommt. Auch hier nehme ich an das ihr ein Taster dran habt der
> das Zählen zurück setzen soll.
>
> ODER?

Danke Holger für die Ausführliche Erklärung :-)
Genau an Interrupt 0 kommt ein Puls der gezählt werden soll. Das ganze 
soll über einen Taster der an Interrupt 1 angeschlossen ist wieder auf 
Null gesetzt werden.
Gast #3974327
Lesenswert?

Und somit wird beim Start des Programmes zu start: gesprungen.

Bei Irq 0 zu zaehlen:
und
Bei Irq 1 zu null:


da in den Vektoren ein rjmp steht


mit dem reti am ende der Routinen wird wieder dahin zurückgesprungen wo 
es vor dem Aufruf war.


In Deinem Fall in der Endlosschleife:

los:    rjmp  los     ; Springe in der Schleife los hin und her
#3974333
Lesenswert?

Der springende Punkt ist, dass der Prozessor bei Auftreten von 
bestimmten Ereignissen (die einzeln freigegeben werden können) seine 
Arbeit unterbricht und an genau definierte Adressen im Code springt um 
dann dort weiter zu machen.
Genau so kommen die .ORG zu Stande. Sie teilen dem Assembler mit, den 
nachfolgenden Code an genau die beim .ORG angegebene Adresse zu legen.
#3974807
Lesenswert?

Christof schrieb:
> .ORG  0x0000
>  rjmp  start
>  .ORG  0x0002
>  rjmp  zaehlen
>  .ORG  0x0004
>  rjmp  null

Wobei das in der Praxis niemand so schreibt.

Die Lage der Vektoren ist nämlich nicht in Stein gemeißelt, sondern für 
jeden AVR-Typ unterschiedlich!
Daher schreibt man nicht die Adresse als feste Nummer, sondern nimmt die 
Namen aus dem Include-File bzw. Datenblatt des Target.

Nebenbei erkennt man aus dem Namen gleich die Funktion des Vektors.
1
.org 0x001e   ; hä, wasn das ?
Aber:
1
.org UTXCaddr ; USART, Tx Complete

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