I am using the following compiler directives for C51.exe CFLAGS = DB OE LARGE $(INCDIR) CODE RET_XSTK WL(1)
It looks like the generated code is incorrect. I have a TSK_create function with the following prototype
TSK_hndl_t TSK_create ( void *stack_ptr, uint16 stack_size, uint8 thread_priority, void (func)(void *), void *thread_arg ) reentrant;
because of the RET_XSTK directive the return address in SP is pushed into virtual stack ?C_XBP using ?C?CALL_XBP function and then when the function is about to exit, the return address from virtual address is retreived using ?C?RET_XBP function. Below I am listing the decompiled code. ?C?CALL_XBP: MOV DPTR, #2 POP B POP ACC MOV R0, A LCALL ?C?ADDXBP POP ACC MOVX @DPTR, A INC DPTR POP ACC MOVX @DPTR, A INC DPTR MOV A, R0 PUSH ACC PUSH B RET
?C?RET_XBP: MOV DPL, ?C_XBP + 1 MOV DPH, ?C_XBP MOVX A, @DPTR PUSH ACC INC DPTR MOVX A, @DPTR PUSH ACC MOV DPTR, #2 LJMP ?C?ADDXBP
It looks like there is a leakage in ?C_XBP and the return address are not retreived in the correct order. I had to modify the ?C?RET_XBP function as follows ?C?RET_XBP: MOV DPL, ?C_XBP + 1 MOV DPH, ?C_XBP MOVX A, @DPTR MOV B, A INC DPTR MOVX A, @DPTR PUSH ACC PUSH B MOV DPTR, #0FFFEH LJMP ?C?ADDXBP
My version of C51.exe is 6.02. Is this problem fixed in newer versions of the compiler or am I doing something stupid?