Hey all,
I have a program that I have been developing for 6 months or so and suddenly, while debugging, the program counter ends up off in never-never land. On closer inspection I see that a function is being called with JSR ( in the same page so this is ok) but the assembly being generated tries to return using RTC instead of RTS.
I have looked for this issue on the forum and learned that I should make sure my function prototype is correct with no implicit parameter declarations. Check. The other possible explanation did not make any sense to me, it was something about there being two returns in the same subroutine?
Help would be appreciated.
-shawn
已解决! 转到解答。
Things to check:
- the c file containing the function definition should include the header file containing the declaration, otherwise the compiler cannot verify the compatibility of the signatures.
- check also for warnings regarding inconsistent segment qualifiers.
- How is the function declared? How is it defined? Which memory model?
- out of stack? Enough stack space?
- any local buffers overwritten?
- is the SP at function entry the same as the SP when the RTC is executed?
- is the callee/caller or any code used written in assembly (including inline assembly)?
- what is the expected calling convention, far or near? Is the caller's JSR or the callee's RTC incorrect?
The two returns in one subroutine comment may have been about the "-of", common subroutine optimization which builds up subfunctions inside of a function. Those subfunctions are using JSR/RTS, therefore those RTS may be confused with the final return. So banked/far functions can end (legally) with an RTS, while the actual RTC is somewhere in the middle of the function. But as your function ends with an RTC, that is not the issue here.
Daniel
Daniel
Things to check:
- the c file containing the function definition should include the header file containing the declaration, otherwise the compiler cannot verify the compatibility of the signatures.
- check also for warnings regarding inconsistent segment qualifiers.
- How is the function declared? How is it defined? Which memory model?
- out of stack? Enough stack space?
- any local buffers overwritten?
- is the SP at function entry the same as the SP when the RTC is executed?
- is the callee/caller or any code used written in assembly (including inline assembly)?
- what is the expected calling convention, far or near? Is the caller's JSR or the callee's RTC incorrect?
The two returns in one subroutine comment may have been about the "-of", common subroutine optimization which builds up subfunctions inside of a function. Those subfunctions are using JSR/RTS, therefore those RTS may be confused with the final return. So banked/far functions can end (legally) with an RTS, while the actual RTC is somewhere in the middle of the function. But as your function ends with an RTC, that is not the issue here.
Daniel
Daniel
- c file includes the header file
- will check for warnings
- memory model is banked (was) I changed to small as I only have ~30k code
- the stack is the same as entry on RTC. How could stack size account for RTC instead of RTS?
- no local buffers overwritten
- no assembly
- should be a near call. If I called the same function from code in a different page it would force the compiler to generate CALL and RTC, correct?
I noticed that the bean code uses CODE_SEG pragmas, do I need to do that as well? I thought that was only if I cared which page the code ended up in. Also, when I added a pragma to put the callee function in a different page, I fixed this one problem but ran into the exact same thing further along.
Since I switched to a small memory model and time is limited I don't know when I can investigate further.
Thank you very much for the prompt reply.
>- should be a near call. If I called the same function from code in a different page it would force the
>compiler to generate CALL and RTC, correct?
No.
The compiler only considers which qualifiers a function was declared/defined with and in which section the function is placed.
The compiler has no glue about actual addresses, therefore he cannot generate different code whether two functions end up in the same page or not.
>I noticed that the bean code uses CODE_SEG pragmas, do I need to do that as well?
Depends on your code I would think....
In the banked memory model, interrupt handlers must be allocated non banked. Other than that, there is little need for a
#pragma CODE_SEG in plain C code.
It is important that function declarations (in header files) and the function definition are defined in the same segment.
E.g. Typical setup of a function in a non default segment looks like this:
/* File.h */#ifndef FILE_H_#define FILE_H_#pragma push#pragma CODE_SEG /* qualifiers, if any. */ MY_FILE_SEGvoid fileFunc1(void);void fileFunc2(void);#pragma pop#endif /* FILE_H_ */
/* File1.c */#include "file.h" /* include important for compiler warnings! */#pragma CODE_SEG /* qualifiers, if any. (same as in file.h!) */ MY_FILE_SEGvoid fileFunc1(void){ /* Whatever */}void fileFunc2(void){ /* Whatever */}
Note:
- The pragma must be present for the declaration also.
- Using __far/__near qualifiers is only necessary (I would say reasonable) in few cases,
and only when code gets placed in user defined sections.
Daniel