Forum: Compiler & IDEs XOR / pointer - Problem


von Ralf (Gast)


Lesenswert?

Hallo,

ich scheitere an einem eigenartigem Problem beim Versuch den QUISCI - 
Algorithmus auf einem ATtiny zu implementieren. Folgender Codeausschnitt 
funktioniert, wenn er mit Visual Studio übersetzt wird einwandfrei, 
liefert jedoch falsche Ergebnisse, wenn er auf dem ATtiny ausgeführt 
wird.

Das komische daran ist, dass der erste Schleifendurchlauf durchaus das 
richtige Ergebniss liefert. Dieses wird dann beim 2. Durchlauf jedoch 
wieder überschrieben, obwohl pdata weitergezählt wird?!

Hoffe mir kann jemand helfen.

Ralf
1
void quisci(unsigned char *pdata, unsigned char SN, unsigned char C){
2
  unsigned char SK[] = {0x1B, 0x60, 0x80, 0x04, 0x10, 0xF0, 0x17, 0xA7, 0x6B};
3
  unsigned char SHN;  
4
  unsigned char i=0;
5
  SHN = SN;
6
  for(i=0; i<4; i++){
7
    SN = (unsigned char)((SN + SK[SHN])%8);
8
    if(SN!=0){      
9
      C = (SN^SK[SHN]);
10
      SK[SHN] = SN;
11
      SHN = _SN;    
12
      *pdata ^= C;  
13
    }else{
14
      _SN = SK[SHN]^0xFF;
15
      SK[SHN] = C;
16
      *pdata ^= SN;      
17
    }    
18
    pdata++;
19
  }
20
}

von Ralf (Gast)


Lesenswert?

noch 2 kleine fehler im code: _SN muss SN werden ...

von Oliver (Gast)


Lesenswert?

Wie und womit wird quisci() denn aufgerufen?

Oliver

von Ralf (Gast)


Lesenswert?

Hallo Oliver

quisci wird so aufgrufen:
1
unsigned char data[8];
2
3
[...]empfangen.... 
4
5
quisci(data, (unsigned char)data[5], (unsigned char)data[4]);

von Stefan E. (sternst)


Lesenswert?

> Folgender Codeausschnitt funktioniert, wenn er mit
> Visual Studio übersetzt wird einwandfrei, ...

> noch 2 kleine fehler im code: _SN muss SN werden ...

Daraus schließe ich, dass du nicht den Originalcode gepostet hast, 
sondern möglicherweise irgend etwas Eingetipptes. Das ist keine gute 
Idee, denn nicht selten basieren die Probleme auf kleinen Tippfehlern, 
die bei dieser Art der Reproduktion schnell mal verloren gehen.
Bitte poste nochmal genau den Code, der nicht funktioniert, also am 
besten per Cut&Paste hier einfügen.

von Ralf (Gast)


Lesenswert?

Hallo stefan... das ist der originalcode (fast)

ich habe nur ein wenig rumprobiert und allem eine eigene variable 
zugewiesen (also nicht das übergebene SN genommen sondern nocheinmal ein 
unsigned char _SN = SN dazugenommen -> hat leider nix gebracht, also 
habe ich es wieder entfernt, damit alle die das lesen nicht unnötigen 
käse konsumieren müssen.

wenns dich berhigt hier nochmal der originalcode:
1
void quisci(unsigned char *pdata, unsigned char SN, unsigned char C){
2
  unsigned char SK[] = {0x1B, 0x60, 0x80, 0x04, 0x10, 0xF0, 0x17, 0xA7, 0x6B};
3
  unsigned char SHN;  
4
  unsigned char i=0;
5
  SHN = SN;
6
  for(i=0; i<4; i++){
7
    SN = (unsigned char)((SN + SK[SHN])%8);
8
    if(SN!=0){      
9
      C = (SN^SK[SHN]);
10
      SK[SHN] = SN;
11
      SHN = SN;    
12
      *pdata ^= C;  
13
    }else{
14
      SN = SK[SHN]^0xFF;
15
      SK[SHN] = C;
16
      *pdata ^= SN;      
17
    }    
18
    pdata++;
19
  }
20
}

von Stefan E. (sternst)


Lesenswert?

Ich kann beim besten Willen diesen Sourcecode nicht mit deiner 
Fehlerbeschreibung in Einklang bringen. Denn egal ob der Algorithmus im 
allgemeinen richtig implementiert ist, beschreibt er doch auf jeden Fall 
pdata[0] bis pdata[3], und nicht pdata[0] zweimal hintereinander.

Als Beispiel mal zwei mögliche Tippfehler, die zu deiner 
Fehlerbeschreibung passen würden:
1) Bei den }-Klammern vertippt, so dass das "pdata++;" in den else-Zweig 
oder hinter die for-Schleife gerutscht ist.
2) Bei "pdata++;" beim Namen vertippt, so dass versehentlich eine 
globale Variable (data?) weitergezählt wird, und nicht pdata.

von Ralf (Gast)


Lesenswert?

Das beruhigt mich irgendwie, auch wenn es mir nicht wirklich weiter 
hilft.
Habe gestern schon den halben Tag nach dem Fehler gesucht und nix 
gefunden...

Der Algorithmus beschreibt ja auch data[0] bis data[3], er ändert jedoch 
in jeder schleife die vorher schon geschriebenen werte (so scheint mir 
zumindest). Also im 1. Durchlauf wird data[0] geändert, im 2. data[1] 
und data[0] usw. :-(

Ich kann leider auch nicht wirklich debuggen - habe keinen JTAGICE mkII 
:-(. Werde mir jetzt mal ein Software UART dran bauen und mit in jedem 
Durchlauf alle Werte ausgeben lassen. Vielleicht hilfts ja.

Dank dir trotzdem für deine Mühe..

von Stefan E. (sternst)


Lesenswert?

Hast du mal den Speicherbedarf deines Programms geprüft?
Vielleicht hast du einen Stack-Overflow.

von Oliver (Gast)


Lesenswert?

>Ich kann leider auch nicht wirklich debuggen

Um so etwas zu debuggen, braucht es keinen JTAG. Das geht im Simulator 
vom AVRStudio viel besser.

Oliver

von G. L. (sprintersb)


Lesenswert?

ist denn SHN immer in {0...8} ? Das seh ich net, und dann greifst Du 
über SK[] hinweg.

Ausserdem hat SK[] 9 Elemente  und irgendwie willst Du mod 8 rechnen 
#grübel#

von Ralf (Gast)


Lesenswert?

@ oliver: werd ich mal versuchen...

@ georg: SHN ist immer in 0..8, da SHN = SN und SN = irgenwas % 8
das SK 9 elemente hat ist mir noch garni aufgefallen ;-) sollte doch 
aber eigentlich nix an der funktionalität ändern, da sowieso immer nur 
die ersten 8 verwendet werden.

@stefan: nein ... - werde den google dazu mal befragen ... hab nämlich 
keine ahnung wie das geht :-)

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


Lesenswert?

Der Missbrauch eines Parameters als lokale Variable mutet schon
etwas seltsam an.  Warum dies?  Das dürfte selbst in C++ so nicht
legal sein, es sei denn, dein Prototyp initialisiert C mit einem
Default-Wert.

Wie wird eigentlich sichergestellt, dass das übergebene SN nie
größer als 7 bzw. 8 ist?  Es dient ja als initialer Index in die
Tabelle.

Einen wirklichen Zusammenhang zum originalen Quisci-Algorithmus
kann ich in deinen Ausführungen nicht finden.

Du weißt, dass es zumindest eine Behauptung in einem Newsartikel
gibt, dass der Algorithmus kryptographisch eher schwach und leicht
kompromittierbar ist?

von Ralf (Gast)


Lesenswert?

Hallo Jörg,

ich wollte hier nicht über die sicherheit / unsicherheit des 
Algorithmusses spekulieren. Ich habe auch den originalen Algorithmus 
seit gestern immer weiter 'zurückgebaut' um dem Fehler näher zu 
kommen....

Der Missbrauch des Parameters als lokale Variable funktioniert übrigends 
wirklich. Man muss sich nur im klaren darüber sein, dass dieser nach dem 
Funktionsaufruf in einer anderen Funktion nicht mehr dem Wert vor dem 
Aufruf entspricht.

----

habe die lösunge gerade gefunden, auch wenn ichs nicht verstehe warum es 
jetzt geht??!!

aus
1
unsigned char SK[] = {0x1B, 0x60, 0x80, 0x04, 0x10, 0xF0, 0x17, 0xA7, 0x6B};

habe ich
1
 
2
unsigned char SK[8];
3
SK[0] = 0x1B;
4
SK[1] = 0x60;
5
SK[2] = 0x80;
6
SK[3] = 0x04;
7
SK[4] = 0x10;
8
SK[5] = 0xF0;
9
SK[6] = 0x17;
10
SK[7] = 0xA7;

gemacht. Und jetzt läufts?! Darauf gekommen bin ich weil mir der AVR 
Simulator angezeigt hat das SK[] nur Nullen enthält?! Kann mir das 
vielleicht noch jemand erklären?!

von Stefan E. (sternst)


Lesenswert?

Jörg Wunsch wrote:
> Der Missbrauch eines Parameters als lokale Variable mutet schon
> etwas seltsam an.  Warum dies?  Das dürfte selbst in C++ so nicht
> legal sein, es sei denn, dein Prototyp initialisiert C mit einem
> Default-Wert.

???
Dass Parameter in der Funktion verändert werden, ist doch gang und gäbe 
in C.

EDIT:
Und auch in C++ dürfte das uneingeschränkt erlaubt sein.

von Stefan E. (sternst)


Lesenswert?

Ralf wrote:

> Der Missbrauch des Parameters als lokale Variable funktioniert übrigends
> wirklich. Man muss sich nur im klaren darüber sein, dass dieser nach dem
> Funktionsaufruf in einer anderen Funktion nicht mehr dem Wert vor dem
> Aufruf entspricht.

Die Parameter werden als Kopie übergeben, der Originalwert bleibt 
unverändert.

von Ralf (Gast)


Lesenswert?

> Die Parameter werden als Kopie übergeben, der Originalwert bleibt
> unverändert.

gut zu wissen... hätte ich jetzt anders angenommen :-) jaja so ist das 
mit dem gefühlten wissen :-)

von Oliver (Gast)


Lesenswert?

>habe die lösunge gerade gefunden, auch wenn ichs nicht verstehe warum es
>jetzt geht??!!

Very seltsam - welche Compilerverison nutzt du denn?

Oliver

von Ralf (Gast)


Lesenswert?

seh ich auch so...

avr-gcc (GCC) 4.2.2 (WinAVR 20071221)

zumal es an anderer Stelle im programm funktioniert...
1
char S8_Box[] = { 0x28, 0x0C, 0x09, 0x39, 0x12, 0x16, 0x02, 0x1D};
macht was es soll...

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


Lesenswert?

Ralf wrote:

> ich wollte hier nicht über die sicherheit / unsicherheit des
> Algorithmusses spekulieren.

Ich habe mir angesichts dessen nur die Frage gestellt, wofür das
Ganze gut ist.

> habe die lösunge gerade gefunden, auch wenn ichs nicht verstehe warum es
> jetzt geht??!!

Ich auch nicht.  Der generierte Code sollte in beiden Fällen gleich
sein.  Hast du dir den denn mal angeguckt?

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


Lesenswert?

Stefan Ernst wrote:

>> Der Missbrauch eines Parameters als lokale Variable mutet schon
>> etwas seltsam an.

> ???
> Dass Parameter in der Funktion verändert werden, ist doch gang und gäbe
> in C.

Der Code ist arg verwurschtelt, ich hatte ursprünglich angenommen, der
Parameter würde nur dafür überhaupt benutzt, in der Funktion eine
lokale Variable zu besitzen.  Aber er wird ja in der Tat u. U. auch
als Parameter benutzt, das sehe ich jetzt erst so recht.

von Ralf (Gast)


Lesenswert?

naja der generierte Code von
1
unsigned char SK[8]; 
2
SK[0] = 0x1B;
3
SK[1] = 0x60;
4
SK[2] = 0x80;
5
SK[3] = 0x04;
6
SK[4] = 0x10;
7
SK[5] = 0xF0;
8
SK[6] = 0x17;
9
SK[7] = 0xA7;

ist

000007d8 <quisci>:
 7d8:  cf 93         push  r28
 7da:  df 93         push  r29
 7dc:  cd b7         in  r28, 0x3d  ; 61
 7de:  de b7         in  r29, 0x3e  ; 62
 7e0:  cc 50         subi  r28, 0x0C  ; 12
 7e2:  cd bf         out  0x3d, r28  ; 61
 7e4:  9a 87         std  Y+10, r25  ; 0x0a
 7e6:  89 87         std  Y+9, r24  ; 0x09
 7e8:  6b 87         std  Y+11, r22  ; 0x0b
 7ea:  4c 87         std  Y+12, r20  ; 0x0c
 7ec:  8b e1         ldi  r24, 0x1B  ; 27
 7ee:  89 83         std  Y+1, r24  ; 0x01
 7f0:  80 e6         ldi  r24, 0x60  ; 96
 7f2:  8a 83         std  Y+2, r24  ; 0x02
 7f4:  80 e8         ldi  r24, 0x80  ; 128
 7f6:  8b 83         std  Y+3, r24  ; 0x03
 7f8:  84 e0         ldi  r24, 0x04  ; 4
 7fa:  8c 83         std  Y+4, r24  ; 0x04
 7fc:  80 e1         ldi  r24, 0x10  ; 16
 7fe:  8d 83         std  Y+5, r24  ; 0x05
 800:  80 ef         ldi  r24, 0xF0  ; 240
 802:  8e 83         std  Y+6, r24  ; 0x06
 804:  87 e1         ldi  r24, 0x17  ; 23
 806:  8f 83         std  Y+7, r24  ; 0x07
 808:  87 ea         ldi  r24, 0xA7  ; 167
 80a:  88 87         std  Y+8, r24  ; 0x08
 80c:  c4 5f         subi  r28, 0xF4  ; 244
 80e:  cd bf         out  0x3d, r28  ; 61
 810:  df 91         pop  r29
 812:  cf 91         pop  r28
 814:  08 95         ret

während
1
unsigned char SK[] = {0x1B, 0x60, 0x80, 0x04, 0x10, 0xF0, 0x17, 0xA7};

sowas erzeugt:

 7d8:  cf 93         push  r28
 7da:  df 93         push  r29
 7dc:  cd b7         in  r28, 0x3d  ; 61
 7de:  de b7         in  r29, 0x3e  ; 62
 7e0:  c2 51         subi  r28, 0x12  ; 18
 7e2:  cd bf         out  0x3d, r28  ; 61
 7e4:  9b 87         std  Y+11, r25  ; 0x0b
 7e6:  8a 87         std  Y+10, r24  ; 0x0a
 7e8:  6c 87         std  Y+12, r22  ; 0x0c
 7ea:  4d 87         std  Y+13, r20  ; 0x0d
 7ec:  ce 01         movw  r24, r28
 7ee:  01 96         adiw  r24, 0x01  ; 1
 7f0:  9f 87         std  Y+15, r25  ; 0x0f
 7f2:  8e 87         std  Y+14, r24  ; 0x0e
 7f4:  e0 e6         ldi  r30, 0x60  ; 96
 7f6:  f0 e0         ldi  r31, 0x00  ; 0
 7f8:  f9 8b         std  Y+17, r31  ; 0x11
 7fa:  e8 8b         std  Y+16, r30  ; 0x10
 7fc:  f9 e0         ldi  r31, 0x09  ; 9
 7fe:  fa 8b         std  Y+18, r31  ; 0x12
 800:  e8 89         ldd  r30, Y+16  ; 0x10
 802:  f9 89         ldd  r31, Y+17  ; 0x11
 804:  00 80         ld  r0, Z
 806:  88 89         ldd  r24, Y+16  ; 0x10
 808:  99 89         ldd  r25, Y+17  ; 0x11
 80a:  01 96         adiw  r24, 0x01  ; 1
 80c:  99 8b         std  Y+17, r25  ; 0x11
 80e:  88 8b         std  Y+16, r24  ; 0x10
 810:  ee 85         ldd  r30, Y+14  ; 0x0e
 812:  ff 85         ldd  r31, Y+15  ; 0x0f
 814:  00 82         st  Z, r0
 816:  8e 85         ldd  r24, Y+14  ; 0x0e
 818:  9f 85         ldd  r25, Y+15  ; 0x0f
 81a:  01 96         adiw  r24, 0x01  ; 1
 81c:  9f 87         std  Y+15, r25  ; 0x0f
 81e:  8e 87         std  Y+14, r24  ; 0x0e
 820:  9a 89         ldd  r25, Y+18  ; 0x12
 822:  91 50         subi  r25, 0x01  ; 1
 824:  9a 8b         std  Y+18, r25  ; 0x12
 826:  ea 89         ldd  r30, Y+18  ; 0x12
 828:  ee 23         and  r30, r30
 82a:  51 f7         brne  .-44       ; 0x800 <quisci+0x28>
 82c:  ce 5e         subi  r28, 0xEE  ; 238
 82e:  cd bf         out  0x3d, r28  ; 61
 830:  df 91         pop  r29
 832:  cf 91         pop  r28
 834:  08 95         ret

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


Lesenswert?

Irgendwas muss an deinen Compileroptionen schräg sein.  Wenn ich deine
obigen Funktion compiliere, bekomme ich:
1
.global quisci
2
        .type   quisci, @function
3
quisci:
4
/* prologue: frame size=9 */
5
        push r16
6
        push r17
7
        push r28
8
        push r29
9
        in r28,__SP_L__
10
        in r29,__SP_H__
11
        sbiw r28,9
12
        in __tmp_reg__,__SREG__
13
        cli
14
        out __SP_H__,r29
15
        out __SREG__,__tmp_reg__
16
        out __SP_L__,r28
17
/* prologue end (size=12) */
18
        movw r26,r24
19
        movw r18,r28
20
        subi r18,lo8(-(1))
21
        sbci r19,hi8(-(1))
22
        ldi r16,lo8(C.0.1477)
23
        ldi r17,hi8(C.0.1477)
24
        ldi r24,lo8(9)
25
.L2:
26
        movw r30,r16
27
        ld r0,Z+
28
        movw r16,r30
29
        movw r30,r18
30
        st Z+,r0
31
        movw r18,r30
32
        subi r24,lo8(-(-1))
33
        brne .L2
34
        mov r18,r22
35
        ldi r25,lo8(0)
36
        movw r16,r28
37
        subi r16,lo8(-(1))
38
        sbci r17,hi8(-(1))
39
.L3:
40
        movw r30,r16
41
        add r30,r18
42
        adc r31,__zero_reg__
43
        ld r24,Z
44
        add r22,r24
45
        andi r22,lo8(7)
46
        breq .L4
47
        mov r20,r22
48
        eor r20,r24
49
        st Z,r22
50
        ld r24,X
51
        eor r24,r20
52
        st X,r24
53
        mov r18,r22
54
        rjmp .L6
55
.L4:
56
        mov r22,r24
57
        com r22
58
        st Z,r20
59
        ld r24,X
60
        eor r24,r22
61
        st X,r24
62
.L6:
63
        subi r25,lo8(-(1))
64
        cpi r25,lo8(4)
65
        breq .L9
66
        adiw r26,1
67
        rjmp .L3
68
.L9:
69
/* epilogue: frame size=9 */
70
        adiw r28,9
71
        in __tmp_reg__,__SREG__
72
        cli
73
        out __SP_H__,r29
74
        out __SREG__,__tmp_reg__
75
        out __SP_L__,r28
76
        pop r29
77
        pop r28
78
        pop r17
79
        pop r16
80
        ret
81
/* epilogue end (size=11) */
82
/* function quisci size 71 (48) */
83
        .size   quisci, .-quisci
84
        .data
85
        .type   C.0.1477, @object
86
        .size   C.0.1477, 9
87
C.0.1477:
88
        .byte   27
89
        .byte   96
90
        .byte   -128
91
        .byte   4
92
        .byte   16
93
        .byte   -16
94
        .byte   23
95
        .byte   -89
96
        .byte   107

Deutlich erkennbar die Tabelle mit den Initialisierungsdaten am Ende
sowie deren Kopieren auf den Stack beim Funktionseintritt.

von Ralf (Gast)


Lesenswert?

meine compileroptionen:

-Wall -gdwarf-2 -std=gnu99 -mint8    -DF_CPU=16000000UL -Os 
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums 
-mtiny-stack

von Oliver (Gast)


Lesenswert?

Da fehlt mir mindestens ein -mmcu=attiny2313

Oliver

von I_ H. (i_h)


Lesenswert?

Mach mal aus -Os -O2. -Os ist nicht gerade zuverlässig, vor nicht langer 
Zeit ließ sich damit nichtmal der Linux Kernel compilieren.

von Oliver (Gast)


Lesenswert?

>Mach mal aus -Os -O2. -Os ist nicht gerade zuverlässig, vor nicht langer
>Zeit ließ sich damit nichtmal der Linux Kernel compilieren.

Na ja, der Linux-Kernel lässt sich für einen attiny2313 unter avr-gcc 
auch mit -O2 nicht kompilieren:-)

Am -Os liegt es bestimmt nicht.

Oliver

von I_ H. (i_h)


Lesenswert?

Vor kurzem hatte hier einer auch das Problem, dass -Os falschen Code 
produzierte. Schließ es lieber aus, bevor du stundenlang suchst und nix 
findest, weil du den Fehler von vornherein ausgeschlossen hast. Ist doch 
schnell gemacht.

von yalu (Gast)


Lesenswert?

> meine compileroptionen:
>
> -Wall -gdwarf-2 -std=gnu99 -mint8    -DF_CPU=16000000UL -Os
> -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
> -mtiny-stack

Zumindest beim zweiten Brocken Assemblercode in deinem Beitrag vom
20.05.2008 um 12:25 war -Os nicht angegeben. Was dort gezeigt wird,
ist völlig unoptimiert, aber deswegen nicht unbedingt falsch.

Der Unterschied zwischen beiden Varianten besteht darin, dass für
1
unsigned char SK[8]; SK[0] = 0x1B; SK[1] = 0x60; SK[2] = 0x80;
2
SK[3] = 0x04; SK[4] = 0x10; SK[5] = 0xF0; SK[6] = 0x17; SK[7] = 0xA7;

acht Einzelzuweisungen generiert werden, für
1
unsigned char SK[] = {0x1B, 0x60, 0x80, 0x04, 0x10, 0xF0, 0x17, 0xA7};

werden die Daten in die data-Section gepackt und beim Funktionsaufruf
per Schleife in das Array kopiert.

Deswegen sehen beide Varianten unterschiedlich aus, was aber kein
Fehler sein muss.

Ich würde spaßeshalber auch mal die nicht ganz ungefährlichen Optionen
-mint8 und -mtiny-stack weglassen.

von Ralf (Gast)


Lesenswert?

avr-gcc.exe  -mmcu=attiny85 -Wall -gdwarf-2 -std=gnu99 -mint8 
-mtiny-stack  -DF_CPU=16000000UL -Os -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT

mmcu fehlte nicht wirklich... steht beim avr studio nur woanders und 
deswegen hab ichs vorhin vergessen mit rauszuschreiben ... :-)

-O2 hilft leider nicht

von Oliver (Gast)


Lesenswert?

>Vor kurzem hatte hier einer auch das Problem, dass -Os falschen Code
>produzierte.

Bei einer vor-2008-avr-gcc-Version? Da hast du doch sicher einen link, 
oder?

Bei 2008er gabs mehrere Probleme, aber um den geht es hier ja nicht.

Oliver

von Ralf (Gast)


Lesenswert?

> Zumindest beim zweiten Brocken Assemblercode in deinem Beitrag vom
> 20.05.2008 um 12:25 war -Os nicht

das stimmt (auch wenn mir rätselhaft ist wie man soetwas an diesem code 
erkennen kann) ... hatte für die datei ein -O0 angegeben um 
auszuschließen das irgendetwas wegoptimiert wird.

> Ich würde spaßeshalber auch mal die nicht ganz ungefährlichen Optionen
> -mint8 und -mtiny-stack weglassen.

habe ich gemacht - selber fehler.

hier mal die data section:

00000034 <__do_copy_data>:
  34:  10 e0         ldi  r17, 0x00  ; 0
  36:  a0 e6         ldi  r26, 0x60  ; 96
  38:  b0 e0         ldi  r27, 0x00  ; 0
  3a:  ea e0         ldi  r30, 0x0A  ; 10
  3c:  f4 e0         ldi  r31, 0x04  ; 4
  3e:  02 c0         rjmp  .+4        ; 0x44 <.do_copy_data_start>

00000040 <.do_copy_data_loop>:
  40:  05 90         lpm  r0, Z+
  42:  0d 92         st  X+, r0

00000044 <.do_copy_data_start>:
  44:  aa 36         cpi  r26, 0x6A  ; 106
  46:  b1 07         cpc  r27, r17
  48:  d9 f7         brne  .-10       ; 0x40 <.do_copy_data_loop>

0000004a <__do_clear_bss>:
  4a:  10 e0         ldi  r17, 0x00  ; 0
  4c:  aa e6         ldi  r26, 0x6A  ; 106
  4e:  b0 e0         ldi  r27, 0x00  ; 0
  50:  01 c0         rjmp  .+2        ; 0x54 <.do_clear_bss_start>

00000052 <.do_clear_bss_loop>:
  52:  1d 92         st  X+, r1

00000054 <.do_clear_bss_start>:
  54:  a5 37         cpi  r26, 0x75  ; 117
  56:  b1 07         cpc  r27, r17
  58:  e1 f7         brne  .-8        ; 0x52 <.do_clear_bss_loop>
  5a:  8b d0         rcall  .+278      ; 0x172 <main>
  5c:  d5 c1         rjmp  .+938      ; 0x408 <_exit>

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


Lesenswert?

Ralf wrote:

>> Zumindest beim zweiten Brocken Assemblercode in deinem Beitrag vom
>> 20.05.2008 um 12:25 war -Os nicht
>
> das stimmt (auch wenn mir rätselhaft ist wie man soetwas an diesem code
> erkennen kann) ... hatte für die datei ein -O0 angegeben um
> auszuschließen das irgendetwas wegoptimiert wird.

...und hattest die Funktion auf ein Stück Code eingegrenzt, das
außer der Initialisierung des Arrays gar nichts gemacht hat.  Die
ganze Funktion wäre vom Optimizer durch einen einfachen RET ersetzt
worden, wenn du die Optimierung aktiviert gehabt hättest. ;-)

Da kein Schwein hier dein Problem nachvollziehen kann, bliebe es
höchstens, dass du das ganze Projekt mitsamt Makefile mal 1:1
zusammenwickelst und uns gibst.

von G. L. (sprintersb)


Lesenswert?

Ralf wrote:
> -mmcu=attiny85 -mtiny-stack

Du bist sicher, daß 8 Bit reichen für den StackPointer?
Du legst ja gerne lokale Arrays an...

von Ralf (Gast)


Lesenswert?

nö bin ich nicht :-) aber bisher reichts ja... und es ändert sich an 
meinem problem nix, wenn ich die option weglasse...

kann man hier eigentlich irgendwie die themenüberschrift ändern?!

von Oliver (Gast)


Lesenswert?

>kann man hier eigentlich irgendwie die themenüberschrift ändern?!

Das löst dein Problem auch nicht :-)

Wie Jörg schon sagte, zip mal alle Dateien des Projektes zusammen, und 
stell die hier rein. Sonst wird das nichts.

Oliver

von Ralf (Gast)


Lesenswert?

hmm.. habs gefunden (verstehs nur nicht - bzw. hab keine ahnung wie ichs 
lösen kann... )

ich habe eine Funktion
1
void init(void) __attribute__  ((section (".init0")));

wenn ich die wegnehme gehts... werd mir wohl die sectionengeschichte 
nochmal anschauen müssen...

vielen dank an alle für die hilfe :-)

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


Lesenswert?

.init0 ist keine sinnvolle section, in die man seine eigenen
Initialisierungsroutinen schreiben kann.  Erstens sind alle
geradzahligen für das System reserviert.  Zweitens wird in .init2
erst das _zero_reg_ initialisiert, und aller compiler-generierter
Code geht davon aus, dass dieses Register 0 ist.  Damit sollte man
mit eigenen Init-Routinen in der Regel bis .init3 warten.

Schließlich und endlich: .initN-Funktionen müssen immer auch `naked'
sein.  Die sollen nämlich nirgendwo hin "return"en.  Die Sprache C
benötigt allerdings syntaktisch eine Funktion als kleinste Einheit,
die ausführbaren Code generieren kann, insofern muss man diese
init-Codeschnipsel rein der Syntax wegen in eine Funktion verpacken.

von Ralf (Gast)


Lesenswert?

Jörg, vielen dank für diese erklärung... alles was ich bisher dazu 
gelesen hatte war 
http://www.roboternetz.de/wissen/index.php/Avr-gcc/Interna , wo steht

> .initn   Flash   Code   wird vor main ausgeführt, n = 0...9

also hatte ich einfach mal die 0 genommen....

habe dies jetzt geändert (die init0 funktion rausgenommen) und siehe da, 
alles funktioniert fast wie gewünscht - die ausführungszeit der funktion 
verlangsamt sich jedoch um etwa 4 µsekunden... ;-)

von Stefan E. (sternst)


Lesenswert?

Ralf wrote:
> Jörg, vielen dank für diese erklärung... alles was ich bisher dazu
> gelesen hatte war
> http://www.roboternetz.de/wissen/index.php/Avr-gcc/Interna , wo steht

Hier ist eine bessere Infoquelle:
http://www.nongnu.org/avr-libc/user-manual/mem_sections.html

von Ralf (Gast)


Lesenswert?

die ist auch englischer... :o)

von Simon K. (simon) Benutzerseite


Lesenswert?

und deswegen originaler ;)

von G. L. (sprintersb)


Lesenswert?

Ralf wrote:
> Jörg, vielen dank für diese erklärung... alles was ich bisher dazu
> gelesen hatte war
> http://www.roboternetz.de/wissen/index.php/Avr-gcc/Interna

Vielleich hilft es, alles zu lesen, etwa den Abschnitt " Frühe 
Codeausführung vor main()" darin...

http://www.roboternetz.de/wissen/index.php/Avr-gcc/Interna#Fr.C3.BChe_Codeausf.C3.BChrung_vor_main.28.29

von Oliver (Gast)


Lesenswert?

Wofür brauchst du denn überhaupt einen eigene Funktion in einer der 
init-sections?

Oliver

von Ralf (Gast)


Lesenswert?

> Vielleich hilft es, alles zu lesen, etwa den Abschnitt " Frühe
> Codeausführung vor main()" darin...

hätte sicherlich geholfen... aber ich hatte an der stelle weiter oben 
die benötigte Information (wie ich was vor der main ausführen kann) 
gefunden... :-)

@oliver: da wird über den speicherinhalt eine prüfsumme gebildet was 
sicherstellen soll, dass die anwendung nur bei korrektem flash 
ausgeführt wird. hab das jetzt an den anfang der main verschoben - geht 
genauso.

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.