cgccbare-metalstack-frame

Use of Stack-Local Variables in Naked Function


While browsing some vendor-supplied startup code for a commodity MCU and reading this excellent SO post about GCC's naked attribute, I seem to have come to a contradiction. The linked GCC documentation states (emphasis mine):

All other statements, including declarations of local variables, if statements, and so forth, should be avoided.

However, the code clearly seems to violate that:

  __attribute__ ((naked, section(".after_vectors.reset")))
  void ResetISR(void) {

     // ...  

      // Set timeout value
      *((volatile unsigned int *)0x40052008) = 0xFFFF;                 // OK, direct memory access
      // Now disable watchdog via control register
      volatile unsigned int *WDOG_CS = (unsigned int *) 0x40052000;    // OK, literal address
      *WDOG_CS = (*WDOG_CS & ~(1 << 7)) | (1 << 5);                    // literal doesn't need mem for ptr itself
  #endif // (__USE_CMSIS)
  
      //
      // Copy the data sections from flash to SRAM.
      //
      unsigned int LoadAddr, ExeAddr, SectionLen;                      // <---- HOW IS THIS POSSIBLE?
      unsigned int *SectionTableAddr;
  
      // Load base address of Global Section Table
      SectionTableAddr = &__data_section_table;
  
      // Copy the data sections from flash to SRAM.
      while (SectionTableAddr < &__data_section_table_end) {
          LoadAddr = *SectionTableAddr++;                              // Variables accessed here
          ExeAddr = *SectionTableAddr++;
          SectionLen = *SectionTableAddr++;
          data_init(LoadAddr, ExeAddr, SectionLen);
      }

That SO post does go on to mention that the stack is fully set up. Are these locals safe because we are in the special condition of being just out of reset and so there is nothing to clobber? If that is the case, what is the address of these locals as there is no stack frame, per se?

What am I missing?


Solution

  • The reset ISR and a general hand-crafted function with inline assembler are different things.

    That SO post does go on to mention that the stack is fully set up.

    They are not referring to the specific case of a reset ISR. In the reset ISR on a traditional MCU, the stack does not "exist" - or rather the SP has not yet been initialized. Everywhere else in the program, the stack will be available however.

    In general terms: