|
|
View previous topic :: View next topic |
Author |
Message |
loupan
Joined: 22 Oct 2007 Posts: 21
|
two addresses for same function?? |
Posted: Mon Jan 25, 2010 5:42 pm |
|
|
In tracking down unexpected program behavior, it appears that the compiler is generating two different addresses for the same function.
I am not that familiar with assembly language. Perhaps someone who is can take a look at the excerpts from the symbol table and LST file and confirm or dispell my suspicion.
The function in question is load_sim
From the symbol table, the adrs is show as 007FFA
Below are the excerpts from the LST file that show the assembly language being generated for each of the 4 calls:
Code: |
.................... load_sim(G_MAST_NUM);
087B4: MOVFF 688,B59
087B8: MOVLB 0
087BA: RCALL 7FFA
087BC: MOVLB 6
.
.
.
.................... load_sim(G_MAST_NUM);
1BDEC: MOVFF 688,B59
1BDF0: MOVLB 0
1BDF2: CALL 1B956
.
.
.
.................... load_sim(i+1);
15604: MOVLW 01
15606: ADDWF x04,W
15608: MOVWF x84
1560A: MOVFF FE8,B59
1560E: MOVLB 0
15610: CALL 1B956
.
.
.
.................... load_sim(G_MAST_NUM);
158D2: MOVFF 688,B59
158D6: MOVLB 0
158D8: CALL 1B956
.
.
. |
It looks to me like the correct adrs (7FFA) is called once and another adrs (1B956) is called 3 times. I note that RCALL is being used once and CALL is being used 3 times, but aren't they suppose to resolve to the same adrs?
I got to this point by single stepping at the point where load_sim is called, and the next instruction indeed executes at adrs 1B956, right in the middle of a totally different routine. Obviously the program behavior is nonsensical beyond that point.
The listing for the actual definition of the function shows that it indeed starts at 7FAA as shown below:
Code: | .................... void load_sim(int sim_val) {
.................... int i, num_pwr_pts;
.................... int16 max_pwr, adc_at_pwr_n;
.................... float start, delta;
.................... int band_to_load;
....................
.................... val_to_load = G_VALS[band_num -1];
*
07FFA: MOVLW 01
07FFC: MOVLB B
07FFE: SUBWF x59,W
08000: CLRF 03
08002: ADDLW 89
08004: MOVWF FE9
08006: MOVLW 06
08008: ADDWFC 03,W
0800A: MOVWF FEA
0800C: MOVFF FEF,B68
.................... |
This is happening on 4.100 but it also happens on 4.104 and I backtracked to 4.100 to see if I still had the problem.
The processor is a PIC18F8722 with 128K of adrs space, about 90% used.
Shifting/adding code around sometimes moves this behavior to a different routine.
Thanks for any suggestions.
Regards,
loupan |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
loupan
Joined: 22 Oct 2007 Posts: 21
|
|
Posted: Mon Jan 25, 2010 7:11 pm |
|
|
Thanks PCM programmer. I know there were some major changes introduced in 4.100.
Tried it on 4.099 - same problem.
Based on the LST info that I posted, does my analysis seem to be correct? Two different addresses for the same function?
Thanks
loupan |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 26, 2010 2:57 am |
|
|
Are you doing anything unusual in your code ? Are you using #build,
#separate, #org, #opt, etc., in your program ? Are you using "multiple
compilation units" ? |
|
|
loupan
Joined: 22 Oct 2007 Posts: 21
|
|
Posted: Tue Jan 26, 2010 3:44 am |
|
|
No - not using anything special that relocates code, blocks out address ranges, etc. I did not see this behavior when the code occupied a smaller percentage of the total rom space. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 26, 2010 1:41 pm |
|
|
Quote: | .................... void load_sim(int sim_val) {
.................... int i, num_pwr_pts;
.................... int16 max_pwr, adc_at_pwr_n;
.................... float start, delta;
.................... int band_to_load;
....................
.................... val_to_load = G_VALS[band_num -1];
*
07FFA: MOVLW 01
07FFC: MOVLB B
07FFE: SUBWF x59,W
08000: CLRF 03
08002: ADDLW 89
08004: MOVWF FE9
08006: MOVLW 06
08008: ADDWFC 03,W
0800A: MOVWF FEA
0800C: MOVFF FEF,B68 |
I noticed that the load_sim() function is crossing a 32K boundary.
What if the compiler has problems with functions that do this ?
Try an experiment. Use an #org statement to prevent the
compiler from using the last 2 bytes in the first 32K block.
Then look in the .LST file to see where it places the load_sim()
function. Also look at the ASM code that calls it. See if this
fixes the problem. Example:
Code: |
#include <18F8722.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
// Reserve the last 2 bytes in the first 32K block.
// This should prevent the CCS compiler from placing
// code that crosses the 0x7FFF-0x8000 boundary.
#org 0x7FFE, 0x7FFF {}
//===========================================
void main()
{
while(1);
} |
Also, it just occurred to me that this PIC has 128 KB of ROM space.
You might want to put similar #org statements at all 32K boundaries
in the PIC. So in addition to the #org statement above, add these:
Code: |
#org 0xFFFE, 0xFFFF {} // Last 2 bytes in 2nd 32K block
#org 0x17FFE, 0x17FFF {} // Last 2 bytes in 3rd 32K block
|
|
|
|
loupan
Joined: 22 Oct 2007 Posts: 21
|
|
Posted: Tue Jan 26, 2010 6:02 pm |
|
|
Thanks.
With the three org statements, the function in question now resolves to the same adrs in all 4 calls. As I mentioned earlier, shifting things around sometimes eliminates the problem or moves it to another function. So I can't be sure if the problem did not occur as a result of preventing routines from crossing 32k boundaries, or simply from the shifting that took place as a result of the org statements. I will try this work-around and if I do not see this problem over the next few days as the code is modified, I would say your hunch is correct.
In any case, it would behoove CCS to add a sanity check to make sure all args of CALLs and RCALLs map to a valid adrs in the symbol table.
Thanks again PCM programmer. I'll respond again if the problem resurfaces with the org statements, or if I do not see the problem in a few days as the code continues to churn.
Regards,
loupan |
|
|
loupan
Joined: 22 Oct 2007 Posts: 21
|
|
Posted: Fri Jan 29, 2010 8:51 am |
|
|
PCM programmer.
even with the three org statements you recommended to prevent functions spanning 32K boundaries, the problem still happens.
The excerpts below show another example that I captured with two of the 4 calls to a function resolving to the correct address, and the other 2 calls mapping to an address in the middle of another function. The latter two calls do indeed cause execution to jump to the incorrect address as I confirmed with breakpoints and single stepping.
Interestingly, if I swap the declaration of the affected function with an adjacent declaration in the application header file and recompile, the compiler generates the same (correct) address for all 4 calls, but of course, the problem may very well have moved to another function.
I will refer this to CCS and let you know how things turn out.
Thanks again.
loupan
Code: |
// Excerpts from lst file, function definition and 4 calls
.................... void update_use_trim_flag () {
.................... if (G_FWD_RATIO == 1.0)
*
06F38: MOVFF 6D4,BCF
06F3C: MOVFF 6D3,BCE
06F40: MOVFF 6D2,BCD
.
.
.
.................... update_use_trim_flag();
07EB8: MOVLB 0
07EBA: CALL 6F38
.................... update_use_trim_flag();
06F92: RCALL 6F38
.................... update_use_trim_flag ();
1C566: CALL 1AD2E
.................... update_use_trim_flag ();
1CF72: CALL 1AD2E |
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|