We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have several very long subroutines, 1500+ lines each, which consist of 20-50 discrete portions. For stack purposes, I don't wish to make subroutines out of each portion, but for clarity I wanted to separate the portions. I moved each portion, typically the body of an if or while loop, into its own .c file and #included them in place, changing if (a > 100) { statement1; statement2; ... statement 50; }; // if into if (a > 100) { ; main.c, line 30 #include body1.c ; main.c, line 31 }; // if ; main.c, line 32 with file "body1.c" containing the statements, without any subroutine syntax. statement1; ; body1.c, line 1 statement2; ; body1.c, line 2 ... statement 50; ; body1.c, line 50 The compiler does what it is supposed to do as far as the executable is concerned; it generates the correct opcodes as if it were all inline in a single file. The problem I have is with emulation, but the reason can be seen by looking at the generated list file. The line number information for the included .c files is inappropriately constructed. In the above example, the listing file attributes the HLL statements to main.c, lines 30, 1, 2, ..., 50, 32. What would be desired would be to attribute them to main.c line 30, body1.c lines 1, 2, ..., 50, and then main.c line 32. When enulating, the debug information for HLL presents lines from the parent file, instead of from the included file, making it difficult to debug within the included files. Has this been seen before? Is there anything that I can do? Is there anything that you can do?
I will try your suggestions. The overlaying process leaves me with mixed feelings. I have found that it is usually good at recognizing and overlapping temporary variables in small scopes inside a function. A large issue I do have with the overlay process can be summed up with this example: void main(void) { if (test) { unsigned char i; statements; sub1(); } else { unsigned long j; statements; sub2(); }; // if } void sub1(void) { unsigned long k; statements; } void sub2(void) { unsigned char l; statements; } The overlay process will overlay mutually exclusive variables within a subroutine, and will overlay mutually exclusive subroutine variables, but it will not overlay a subroutine with its parent if the subroutine call was made at a point that is not the maximum scope. i and j are mutually exclusive variabales within a subroutine. They are overlayed within the same 4 bytes. k and l are in mutually exclusive subroutines called by main. They are overlayed within the same 4 bytes. This stub uses 8 bytes, i and j overlain at offset 0 and k and l overlain at offset 4. However, sub1() uses k at a point when only 1 byte (i) is used, while sub2() uses l ata a point when 4 bytes (j) are used. The variables could be compacted as var offset length i 0 1 j 0 4 k 1 4 l 4 1 This would use a total of 5 bytes, compared to the 8 of above. A part of my issue with trying to accomplish what I am stems from my desire to minimize stack use (which uses internal memory) while overlaying temporary variable usage as best I can. Thus, I have several instances where multiple mutually exclusive scopes (if and switch statments) with at different levels of memory usage force me to have a single, subroutine, instead of multiple parallel and/or nested subroutines.
"The overlay process will overlay mutually exclusive variables within a subroutine" The overlaying works by block scope - which is not limited to just functions. eg,
int i,j : do stuff with i : do stuff with j :
{ int i; : do stuff with i : } { int j; : do stuff with j : }
I appologize for not being concise with my wording. Yes, that is how the overlay works. The point I was trying to bring up, however was in the use of functions in different blocks.
{ char i; long k; } { long j; char l; }
{ char i; Sub1(); } { long j; Sub2(); } void Sub1(void) { long k; } void Sub2(void) { char l; }