Re: Preprocessor Kategorie: Programmierung C (von PeterS - 12.01.2010 8:31) | |
Als Antwort auf Preprocessor von Friedhelm Michel - 11.01.2010 14:27
| |
Hallo Friedhelm, ich schau mir das an. Wenn Du mir helfen willst, dann schick mir doch das ganze Projekt an ccpro@gmx.de, und kommentiere doch bitte die Teile des Source aus, die nicht nötig sind um den Bug zu produzieren. Danke! Gruss Peter > Hallo, > Ich glaube, dass ich einem unschönen Verhalten des C-Preprocessors auf die Spur gekommen bin. > Mit einer bestimmten Definitionsform einer Konstanten kann der Programm Stack während der > Laufzeit zerstört werden. Im nachfolgenden Quelltext wird die Konstannte 'DIMENSION' aus > TEST_CONST_A + TEST_CONST_B vom Preprocessor errechnet und ein Array damit dimensioniert. > > Wird DIMENSION mit > > #define DIMENSION TEST_CONST_A + TEST_CONST_B > > definiert dann läuft alles normal. > > Wird aber folgende geklammerte Form verwendet: > > #define DIMENSION (TEST_CONST_A + TEST_CONST_B) > > dann wächst der Programmstack mit jedem Unterprogrammaufruf unaufhörlich bis zum Absturz. > Das Programm verwendet ein kleines Assemblermodul um den Programm Stack und den Parameter > Stack nach jedem Unterprogrammaufruf auszulesen und anzuzeigen. Ich glaube, dass ein > Zusammenhang zwischen Konstantendefinition, Array und Unterprogrammaufruf besteht. Da mir der > Aufbau des Byteinterprteters nicht bekannt ist, kann ich leider nur das Symptom beschreiben. > Allerdings liegt die Vermutung nahe, dass die geklammerte Version als Prozedurkopf interpretiert wird. > Vielleicht kann sich einer der C-Interpreter Autoren des Fehlers annehmen. Die nicht zu verwendende > Klammerung birgt Gefahren bei der Verwendung von Preprocessor Artithmetik (Operatoren Priorität). > Das Programm erzeugt im Loop einen Unterprogrammaufruf sobald SW1 auf dem Experimentierboard > gedrückt wird. Die Stackadressen werden dazu im Output Window angezeigt. > > Mit freundlichem Gruss, > Friedhelm Michel > > void getCriticalSection $asm("tag1")(void); // the assembler module declaration > > unsigned int StackPointer; // this will contain the stack addresses after each subroutine call > unsigned int ParameterStack; > > #define TEST_CONST_A 8 > #define TEST_CONST_B 9 > #define DIMENSION TEST_CONST_A + TEST_CONST_B // the critical definition if defined in brackets > > byte TestArray[DIMENSION]; > > > void Outs(void) // the test subroutine > { > ; > } > > void main(void) > { > unsigned int dimension; // used to show the calculated array dimension > int flag; // used for the current key status > byte key; // the port result from SW1 > char Report[100]; // this will be the report message > > flag = 0; // initiate the key flag > Port_DataDirBit(PORT_SW1,0); // we will use SW1 to trigger one loop > Port_DataDirBit(PORT_LED1,PORT_OUT); // the LED will be used as feedback for a pressed key > > getCriticalSection(); // (ASM) get the stack pointer and the parameter stack > // to the global variables > Str_Printf(Report, > "normal Stack Pointer: %drnormal Parameter Stack: %dr", > StackPointer, > ParameterStack); > Msg_WriteText(Report); // and show it > > dimension = DIMENSION; // store, what the pre processor has calculated > Str_Printf(Report,"Array Dimension: %dr",dimension); > Msg_WriteText(Report); // and show it > > while(true) > { > key = Port_ReadBit(PORT_SW1); // check the switch position of SW1 > if(key) // if it is hold down > { > Port_WriteBit(PORT_LED1,PORT_ON); // indicate it with the LED off > if(flag == 0) // if the flag was zero then we observe a key state change > { // to 'down' > > Outs(); // this call becomes critical if the constant DIMENSION > // is defined with brackets > getCriticalSection(); // (ASM get the stack pointer and the parameter stack > // to the global variables > Str_Printf(Report, > "Stack Pointer: %drParameter Stack: %dr", > StackPointer, > ParameterStack); > Msg_WriteText(Report); // and show it > } > flag = 1; // status is 'key down' now > } > else // do nothing > { > flag = 0; // but store the status > Port_WriteBit(PORT_LED1,PORT_OFF); > } > } > } > > ; Assembler Source > > .ifdef tag1 > > getCriticalSection: > MOVW R26,R8 ; get Ram Top from register 8,9 > SUBI R26,LOW(StackPointer) ; subtract index from StackPointer to get the address > SBCI R27,HIGH(StackPointer) > MOVW R30,R6 ; copy stack pointer from R6 to Z > ST X+,R30 ; and store it into StackPointer > ST X,R31 > MOVW R26,R8 ; get Ram Top from register 8,9 again > SUBI R26,LOW(ParameterStack) ; subtract index from ParameterStack to get the address > SBCI R27,HIGH(ParameterStack) > MOVW R30,R10 ; copy parameter stack pointer to Z > ST X+,R30 ; and store it into StackPointer > ST X,R31 > ret > > .endif | |
Antwort schreiben Antworten: |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum