Forum: Compiler & IDEs 2x rcall? Was will GCC hier sagen?


von Andy H. (vinculum) Benutzerseite


Lesenswert?

Moin,

so sieht das listing eines Timer Overflows bei mir aus. Den mittleren 
Teil habe ich mal entfernt, da passiert nichts wirklich relevantes 
(nichts was den Stack betrifft und keine Sprünge in den dargestellten 
Text).
Was mich interessiert, was sollen die beiden "rcall .+0"?
Es wird die Rücksprungadresse dann ja mit POP R0 vom Stack genommen, 
aber was passiert dann?
1
// Timer1 Overflow
2
ISR(TIMER1_OVF_vect)
3
{
4
     ba0:  1f 92         push  r1
5
     ba2:  0f 92         push  r0
6
     ba4:  0f b6         in  r0, 0x3f  ; 63
7
     ba6:  0f 92         push  r0
8
     ba8:  11 24         eor  r1, r1
9
     baa:  1f 93         push  r17
10
     bac:  2f 93         push  r18
11
     bae:  3f 93         push  r19
12
     bb0:  4f 93         push  r20
13
     bb2:  5f 93         push  r21
14
     bb4:  6f 93         push  r22
15
     bb6:  7f 93         push  r23
16
     bb8:  8f 93         push  r24
17
     bba:  9f 93         push  r25
18
     bbc:  af 93         push  r26
19
     bbe:  bf 93         push  r27
20
     bc0:  ef 93         push  r30
21
     bc2:  ff 93         push  r31
22
     bc4:  df 93         push  r29
23
     bc6:  cf 93         push  r28
24
     bc8:  00 d0         rcall  .+0        ; 0xbca <__vector_13+0x2a>
25
     bca:  00 d0         rcall  .+0        ; 0xbcc <__vector_13+0x2c>
26
     bcc:  cd b7         in  r28, 0x3d  ; 61
27
     bce:  de b7         in  r29, 0x3e  ; 62
28
  // reinit counter
29
  TCNT1H = 0xC2;
30
     bd0:  82 ec         ldi  r24, 0xC2  ; 194
31
     bd2:  80 93 85 00   sts  0x0085, r24
32
  TCNT1L = 0xF7;
33
     bd6:  87 ef         ldi  r24, 0xF7  ; 247
34
     bd8:  80 93 84 00   sts  0x0084, r24
35
36
  char buf[4];
37
  buf[0]='$';  //bold
38
     c3e:  84 e2         ldi  r24, 0x24  ; 36
39
     c40:  89 83         std  Y+1, r24  ; 0x01
40
  buf[1]=cchar;
41
     c42:  9a 83         std  Y+2, r25  ; 0x02
42
  buf[2]=0;
43
     c44:  1b 82         std  Y+3, r1  ; 0x03
44
  WriteString(ccol,crow,buf);
45
     c46:  80 91 8f 01   lds  r24, 0x018F
46
     c4a:  60 91 93 01   lds  r22, 0x0193
47
     c4e:  0e 94 eb 04   call  0x9d6  ; 0x9d6 <WriteString>
48
      blink=0;
49
     c52:  10 92 91 01   sts  0x0191, r1
50
51
     c56:  0f 90         pop  r0
52
     c58:  0f 90         pop  r0
53
     c5a:  0f 90         pop  r0
54
     c5c:  0f 90         pop  r0
55
     c5e:  cf 91         pop  r28
56
     c60:  df 91         pop  r29
57
     c62:  ff 91         pop  r31
58
     c64:  ef 91         pop  r30
59
     c66:  bf 91         pop  r27
60
     c68:  af 91         pop  r26
61
     c6a:  9f 91         pop  r25
62
     c6c:  8f 91         pop  r24
63
     c6e:  7f 91         pop  r23
64
     c70:  6f 91         pop  r22
65
     c72:  5f 91         pop  r21
66
     c74:  4f 91         pop  r20
67
     c76:  3f 91         pop  r19
68
     c78:  2f 91         pop  r18
69
     c7a:  1f 91         pop  r17
70
     c7c:  0f 90         pop  r0
71
     c7e:  0f be         out  0x3f, r0  ; 63
72
     c80:  0f 90         pop  r0
73
     c82:  1f 90         pop  r1
74
     c84:  18 95         reti

von Ansgar K. (paulderbademeister)


Lesenswert?

Rcall bewirkt, dass der Programm Counter auf dem Stack gespeichert wird 
und der Stack Pointer erhöht. AVR-GCC scheint sich auf diese Weise 
dynamsich RAM zu allokieren.
1
     bc8:  00 d0         rcall  .+0        ; 0xbca <__vector_13+0x2a>
2
     bca:  00 d0         rcall  .+0        ; 0xbcc <__vector_13+0x2c>
3
     bcc:  cd b7         in  r28, 0x3d  ; 61
4
     bce:  de b7         in  r29, 0x3e  ; 62
Hier wird der Y-Pointer vor den mit RCALL reservierten Bereich gesetzt.
1
     c40:  89 83         std  Y+1, r24  ; 0x01
2
  buf[1]=cchar;
3
     c42:  9a 83         std  Y+2, r25  ; 0x02
4
  buf[2]=0;
5
     c44:  1b 82         std  Y+3, r1  ; 0x03
Und hier in diesen Bereich geschrieben.

von Andy H. (vinculum) Benutzerseite


Lesenswert?

Danke, ich hab's kapiert.
Register 61 und 62 sind ja der Stackpointer, das kann man leicht 
übersehen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andy H. schrieb:
> Register 61 und 62 sind ja der Stackpointer, das kann man leicht
> übersehen.

Dann schau dir statt des disassemblierten Codes doch den generierten
Code des Compilers an (Compileroption -S):
1
        .file   "foo.c"
2
__SREG__ = 0x3f
3
__SP_H__ = 0x3e
4
__SP_L__ = 0x3d
5
__CCP__  = 0x34
6
__tmp_reg__ = 0
7
__zero_reg__ = 1
8
        .text
9
.global foo
10
        .type   foo, @function
11
foo:
12
        push r29
13
        push r28
14
        in r28,__SP_L__
15
        in r29,__SP_H__
16
        sbiw r28,48
17
        in __tmp_reg__,__SREG__
18
        cli
19
        out __SP_H__,r29
20
        out __SREG__,__tmp_reg__
21
        out __SP_L__,r28
22
/* prologue: function */
23
/* frame size = 48 */
24
...

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.