Hallo, ich habe eine 16-Bit-Variable, die zufällig an der Adresse 0x01FF/0x0200, also an einer Seitengrenze liegt. Wenn ich diese Variable dekrementiere, wird 0x01FF dekrementiert. Bei einem Underflow des Low Byte (256 => 255) wird aber nicht 0x0200, sondern 0x0100 mit dekrementiert. Ist das ein Bug im Compiler? Wie bekomme ich den Compiler dazu, 16-Bit-Variablen an gerade Adressen zu legen? Habe keine Direktive dazu gefunden. Oder ist das gar ein Problem des Controllers? Ich habe mir erst mal mit einer 8-Bit-Dummy-Variablen geholfen, die den 16-Bit-Wert auf eine gerade Adresse schiebt. Geht, aber jetzt muss ich jedes Mal die Symboltabelle durchsehen, ob dieser Fall wieder aufgetreten ist... Compiler: PCWH V3.215 (!) Controller: PIC18C252
Ich habe bislang noch keinen Compiler gesehen, bei dem man nicht einstellen kann, dass eine 16-Bit-Variable auf einer geraden Adresse anfängt. Das ist auch sinnvoll, weil sonst meistens mehrere Assemblerbefehle notwendig sind um die Variable zu dekrementieren. Also such einfach nochmal bei Deinem Compiler nach dieser Einstellung.
tja, ich denke auch, dass es so eine Option geben müßte. Aber trotz intensiver Suche und Internetrecherche habe ich nichts Passendes gefunden. Kann mir bitte jemand einen Tip geben, wie ich den Compiler dazu zwingen kann, 16-Bit-Variablen an gerade Adressen zu legen?
Joachim schrieb: > Ich habe bislang noch keinen Compiler gesehen, bei dem man nicht > einstellen kann, dass eine 16-Bit-Variable auf einer geraden Adresse > anfängt. > > Das ist auch sinnvoll, weil sonst meistens mehrere Assemblerbefehle > notwendig sind um die Variable zu dekrementieren. Das ist Quatsch, der 8-Bitter braucht in jedem Fall 2 einzelne Zugriffe für ne 16-Bit Variable. Bei 8-Bittern ist daher die Plazierung von Variablen nur an geraden Adressen oft nicht vorgesehen. Ob das ein Compilerbug oder ein Hardwarebug ist, muß man sich mal im Assemblerlisting ansehen. Oder die Errata lesen. Der PIC18C252 ist ja eh nicht mehr für Neuentwicklungen empfohlen (Status: Mature Product) und durch den PIC18F2520 abgelöst. Peter
alternativ sollte es möglich sein alle 16bit Variablen in ein eigenes Segment zu legen. Damit kann sich kein Byte mehr dazwischenschmuggeln. Kenn zwar den PIC und den Compiler nicht aber so lassen sich genutzte Variablen strukturiert ablegen. Bedeutet aber auch vor der Deklaration der Variable den entsprechenden Compilerschalter zu setzen und wieder zurückzunehmen. Bsp von meinem S12X: #pragma DATA_SEG RAM_ZERO_WORD unsigned int xyz; #pragma DATA_SEG default JL
JL schrieb: > alternativ sollte es möglich sein alle 16bit Variablen in ein eigenes > Segment zu legen. Damit kann sich kein Byte mehr dazwischenschmuggeln. ... > Bsp von meinem S12X: Du weißt aber schon, daß der S12X im Gegensatz zum PIC ein 16-Bitter ist? Peter
Ok, also hier das Listing der fraglichen Stelle: .................... int16 *pulTimer ; // Temporary pointer to timer element. .................... (*pulTimer)-- ; 0CA0: MOVFF 30C,03 0CA4: MOVFF 30B,FE9 0CA8: MOVFF 30C,FEA 0CAC: MOVLW FF 0CAE: ADDWF FEF,F 0CB0: BC 0CB6 0CB2: INCF FE9,F 0CB4: DECF FED,F Wenn der Pointer auf 0x01FF zeigt, geht das Dekrementieren bei den oberen 8 Bit schief, es geht dann auf die Adresse 0x0100. Bei jeder geraden Adresse und bei Adressen, die nicht am Ende eines 256-Byte-Blocks liegen, geht es. Ich kenne den Assembler-Code dieses Prozessors nicht und bitte um Info, ob der Fehler schon im Code steckt oder ob der Microcontroller etwas falsch macht.
Günter Nowinski schrieb: > 0CA4: MOVFF 30B,FE9 ptr(lo) = ... > 0CA8: MOVFF 30C,FEA ptr(hi) = ... > 0CAC: MOVLW FF W = -1 > 0CAE: ADDWF FEF,F *ptr += W > 0CB0: BC 0CB6 if (!carry) > 0CB2: INCF FE9,F ptr(lo) += 1 > 0CB4: DECF FED,F *ptr-- -= 1 Könnte ein Compilerbug sein. Könnte aber auch sein, dass der Zugriff auf eine ungerade Adresse eines 16bit Werts beim Compiler als unzulässig definiert ist.
Danke, dann muss ich wohl die Variablen von Hand plazieren. Ich habe die gleiche Frage auch im Forum des Compiler-Herstellers gepostet. Dort wurde geantwortet, dass es außer #locate (variable) (adresse) keine Möglichkeit gibt, Variablen an bestimmte Positionen zu legen. Es handelt sich wohl um einen Compiler-Fehler, der Operationen am Ende von 256-Byte-Blöcken betrifft. Irgendwie macht mir das etwas Angst. Schließlich habe ich den Fehler erst nach mehreren Jahren Arbeit mit diesem Controller bemerkt. Wo der sonst noch überall so drinsteckt...
A. K. schrieb: >> 0CB0: BC 0CB6 > > if (!carry) > >> 0CB2: INCF FE9,F ;<- Fehler, richtig: MOVF FEE (increment data pointer 0) > > ptr(lo) += 1 > >> 0CB4: DECF FED,F > > *ptr-- -= 1 > Jau, das ist ein astreiner Compilerfehler. Daß beim PIC zusätzliche Befehle als Memory-Zugriffe getarnt werden, ist aber schon ziemlich strange. Peter
> Du weißt aber schon, daß der S12X im Gegensatz zum PIC ein 16-Bitter > ist? ja ist mir klar, mir ging es nur um die Möglichkeit dem Linker Segmente vorzugeben in die die Variablen gelegt werden. Wenn dann alle 16bit Variablen ab einer geraden Adresse gelinkt werden kann dein Problem nicht mehr vorkommen. Das gleiche gilt dann auch für long, die auf 4byte allign gelinkt werden sollten. JL
such mal nach #TYPE in der Dokumentation dort kannst du beeinflussen wohin deine Variablen gelinkt werden.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.