Lakshman Rao

Function Pointers and FCALL - Stack memory issues

Discussion created by Lakshman Rao on May 10, 2008
Latest reply on May 13, 2008 by Lakshman Rao
Hi all,
 
I had been debugging on an ILLEGAL_BP  hit on my EVB9S12XEP100 using codewarrior 4.6 for the past few days. My code is built on a LARGE MEMORY MODEL and and has a number of function pointer tables which is fetched by a small OS and run on timely manner.
 
I did observe that the illegal bp occurs very consistently when my interrupts are enabled and as an example, tried sending some serial data through SCI1 which was configured to receive interrupt.
Always, the stack used to get corrupted and hence not finding a valid return address, the code would crash.
 
Further debugging, the interesting thing is whenever the function pointers are accessed, the FCALL is fetched which expects a pre-aligned stack as shown below containing the function pointer address and the return address.
Before FCALL is called, there are some 10 assembly instructions generated which will arrange the addresses in the stack as expected by the FCALL.
 
/*----------------- FAR FUNCTION PTR Call ------------------------------------------------
  Parameters:
  - the normal function parameters according
  - on the stack: address of function to be called
  Result :
  - Function is called with unchanged D & X register
  - Y is changed
  - the function address is removed from the stack before the function call

  Stack layout (in):
    5, SP  : page of function to be called
  3-4, SP  : offset of function to be called
  1-2, SP  : offset of return address
    0, SP  : page of return address
       function ptr to be called (3 bytes)
       return address caller     (3 bytes)
  Idea:
       exchanging function ptr and return address
       because function ptr and return address have the page at different offset a
       complicated transformation must be done
              before        after
      0,SP    page ret  A    page fkt  F
      1,SP    high ret  B    high fkt  D
      2,SP    low  ret  C    low fkt   E
      3,SP    high fkt  D    page ret  A
      4,SP    low fkt   E    high ret  B
      5,SP    page fkt  F    low  ret  C
*/
void __far _FCALL(void)
{
  __asm {
                          
    LDY   1, SP                    ; A B C D E F    Y = B C   ; 2 bytes
    MOVW  3, SP,  1, SP            ; A D E D E F    Y = B C   ; 4 bytes
    MOVB  0, SP,  3, SP            ; A D E A E F    Y = B C   ; 4 bytes
    MOVB  5, SP,  0, SP            ; F D E A E F    Y = B C   ; 4 bytes
    STY   4, SP                    ; F D E D B C    Y = B C   ; 2 bytes
                                   ; F D E A B C              ;16 bytes
    RTC                            ; call function pointer
  }
}
 
 
So, what I strongly suspect is during a call through Function ptr and an interrupt occurs, the micro would jump to the isr and before it does, it would stack the present address and when returns back to the FCALL, the FCALL routine computes a wrong return address based on the modified stack by the interrupt.
 
I tried two methods to validate my observation.
First, I verfied this by replacing the function pointers with a direct call to the function and all is fine over here.
Second, I tried by disabling the interrupts before function pointer call and re-enabling the interrupts back after return from the function pointer. This also works fine.
 
Hence, I need some advice on how to go about this(unless my above observation is illogical??)
 
I can't adopt the second method since I need interrupts to be active as the functions could be large nor the first one as the OS needs them.
 
Would modifiying the FCALL method with instructions to disable and enable the interrrupts at the begining and end  a good idea?
Or is there any other alternative.  please advice..
 
with regards,
Lak
 
 

Outcomes