So, we have an older product whose firmware is written entirely in assembly language; it offers a very non-standard serial interface, and we thought it would be wise to broaden its appeal with a standardized communication protocol (Modbus RTU, in this case). I prototyped the Modbus interface in a C language project that of course had to talk to various timer and serial communication IO registers. All of this was working fine in the C-only project, and of course the legacy code was working fine with its assembly language references to the same IO resources when the legacy communication protocol was switched on.
The problem came when I added the C language modules to the assembly language project: both the C language and assembly language code compiles fine and links into an executable fine, BUT for some reason all the references to hardware registers like SCI0CR1 (serial communication chan 0 control register 1) and TIE (timer interrupt enable) end up as reads and writes to RAM variables! I'm using the same C header file "IO_Map.h" as before within the C-only demo project, which has entries like this:

Yet after linking the merged C/assembly language project, that TIE register ends up in the .bss RAM segment, as shown by the map file output under the C language module:

I've circled the TIE entry above, but note that all the other hardware registers like _TCNT, _TFLG1, etc are also being linked as RAM variables.
Just for completeness, here is the include file entry for TIE that the assembly language file is using:

Both the working C demonstration project and the merged C/assembly project have compiler options defined to specify the CPU variant and the small memory model. It acts like there is a collision of names in the linking operation, and as a result the linker puts the C "IO variables" in .bss RAM as the default. I would have thought that the "extern volatile" declaration in the IO_Map.h header file would be enough to cause the compiler/linker to look for an entry like TIE defined somewhere else (in the assembly language code), but apparently I'm missing some declaration or switch. Any ideas?
PS Another clue: when I right click on one of the IO register names in the C language module within the merged C/assembly project, I get options to "Go to macro declaration of TIE" or "Go to declaration of TIE". If I choose the second option it opens up the mc9s12xd64.inc file, the one used by the assembly modules; if I choose the macro declaration there is choice of opening either IO_Map.h or another file called mc9s12xd64.h (that second file is not referenced anywhere in my project, so far as I can tell). Here's the difference, though: if I right click on TIE in the C-only demonstration project there is only the option to "Go macro declaration of TIE".