Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum

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: