XC8 and Fixup Overflow Referencing Psect BssBANK1

For one PIC microcontroller program I had to use assembly code for some critical timing. Rest of code was just plain XC8 C code and everything compiled (and performed) without any issue. So I decided to share code with another project of mine.

Suddenly I got bunch of warnings all saying almost same thing: wait.h:19: error: fixup overflow referencing psect bssBANK1 (0xA2) into 1 byte at 0xB3E/0x2 -> 0x59F (dist/default/production\Source.production.obj 136/0x3E). Program did work (fixup did what its name says) but each compilation would pepper output with warnings - unacceptable.

It was easy to find a culprit:
[c highlight="5"]
unsigned char wait_asm_W; //copy of W
...
#asm
BANKSEL _wait_asm_W
MOVWF _wait_asm_W
...
#end asm
[/c]
Address of an variable was used inside assembly code. Original program had this variable in bank0 and thus no warning were issues. This project had slightly different allocations and variable ended up in bank1 (e.g. 0xA2). Since assembly instruction can only deal with 7-bit registers, address was outside of allowed range.

Once solution is forcing variable into bank0:
[c highlight="5"]
bank0 unsigned char wait_asm_W; //copy of W
...
#asm
BANKSEL _wait_asm_W
MOVWF _wait_asm_W
...
#end asm
[/c]
This works but only after change to project's compiler flags (Properties, XC8 global options, XC8 compiler, Option categories: Optimizations, Address qualifiers: Require). Just thought of having to remember to change project properties each time I reuse this code made me wince. Yes, it was a solution but not what I wanted.

What I wanted is way to transform offending value 0xA2 to non-problematic 0x22. Quick bit-masking solved that issue and warnings were gone:
[c highlight="5"]
unsigned char wait_asm_W; //copy of W
...
#asm
BANKSEL _wait_asm_W
MOVWF _wait_asm_W & 0x7F
...
#end asm
[/c]

2 thoughts to “XC8 and Fixup Overflow Referencing Psect BssBANK1”

Leave a Reply

Your email address will not be published. Required fields are marked *