This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

autobanking jump to XBP address instead of caller function during function return (large model)

Hi Keil,

i'm currently working on project involving large memory model, reentrant function with auto-banking. i've met this unresolved bug involving keil stack frame causing my program flow generate an error.

the error generated when a callee function return to it's caller, instead of returning to it's caller address my program jump to current XBP value (lets say current XBP value at X:0xD00), then my program jump to that address (C:0xD00), that address already occupied by other piece of code, and execute that code causing my program running indeterminately. i've debugged the code and the returning address should be passed on to DPTR by ADDXBP function before calling SWITCH_BANK, the DPTR contain 0xD00 by the time SWITCH_BANK is called.

here's several questions regarding C51 that would help the debugging process:
1. i want to know where do keil save it's caller program counter for large reentrant model? my program might overwrite that area (in my case all function always set as reentrant).
2. what happened to stack frame when reentrant function called? program counter and local reentrant variable/argument is on different stack or same stack? stack frame structure if available would help a lot.
3. beside during function return when will XBP accessed? i believe my error caused by wrong access of XBP.

i use c51 compiler and lx51 linker, uVision3

Sincerely,
Agus Purwanto

Parents
  • thanks so much for your advice, well my project involved about 10-15 cent C51 so it's about ten times cost, oh btw i've finally solve the problem (likely for now)

    the problem arose when calling a reentrant function at the last operation on a function, keil likely to replace LCALL with LJMP for the last function

    ex (perhaps reproduce the bug, haven't tested yet):

    void caller() reentrant {
      char number;
      callee();  //by keil will be replaced with LJMP callee
    }
    
    void callee() reentrant {
      void * ptr;
      //any operations here
      return;
    }
    

    solution :

    void caller() reentrant {
      char dummy;  //use dummy variable
      callee();  //it stays with LCALL callee
      dummy = 0;  //dummy operation
    }
    
    void callee() reentrant {
      void * ptr;
      //any operations here
      return;
    }
    


    perhaps replacing with LJMP causing unreleased variable in caller stack, supposed keil optimization for unreleased stack failed, it then producing my bug, still didn't confirmed it yet.

Reply
  • thanks so much for your advice, well my project involved about 10-15 cent C51 so it's about ten times cost, oh btw i've finally solve the problem (likely for now)

    the problem arose when calling a reentrant function at the last operation on a function, keil likely to replace LCALL with LJMP for the last function

    ex (perhaps reproduce the bug, haven't tested yet):

    void caller() reentrant {
      char number;
      callee();  //by keil will be replaced with LJMP callee
    }
    
    void callee() reentrant {
      void * ptr;
      //any operations here
      return;
    }
    

    solution :

    void caller() reentrant {
      char dummy;  //use dummy variable
      callee();  //it stays with LCALL callee
      dummy = 0;  //dummy operation
    }
    
    void callee() reentrant {
      void * ptr;
      //any operations here
      return;
    }
    


    perhaps replacing with LJMP causing unreleased variable in caller stack, supposed keil optimization for unreleased stack failed, it then producing my bug, still didn't confirmed it yet.

Children