Electronic – Regarding Microchip XC8 compiler’s registers and bits definitions

ccompilermicrochippicxc8

I'm going to take a random 8-bit Microchip microcontroller: PIC16F887.

Let's have a look at how the XC8 compiler (and the HI-TECH PICC, for that matter) is defining a register (SFR) and its coresponding bits in the header file of the device (/opt/microchip/xc8/v1.31/include/pic16f887.h):

extern volatile unsigned char           PORTB               @ 0x006;

So PORTB SFR is defined as an 8-bit volatile variable with the absolute address 0x006, as per the datasheet.

I'm having problems understanding the definition of a single bit (bit 1, for example) corresponding to PORTB:

extern volatile __bit                   RB1                 @ (((unsigned) &PORTB)*8) + 1;

Why do they multiply the PORTB address by 8?

EDIT:

I also looked for an explanation in the compiler's manual and found pretty much the same answers that Spehro gave me. I should have consulted the manual before asking here:

When defining absolute bit variables (see Section 5.4.2.1 “Bit Data
Types and Variables”), the address specified must be a bit address.
A bit address is obtained by mul- tiplying the desired byte address by
8, then adding the bit offset within that bit.

So, for example, to
place a bit variable called mode at bit position #2 at byte address
0x50, use the following: bit mode @ 0x282; If you wish to place a bit
variable over an existing object (typically this will be an SFR
variable or another absolute variable) then you can use the symbol of
that object, as in the following example which places flag at bit
position #3 in the char variable MOT_STATUS:

bit flag @ ((unsigned) &MOT_STATUS)*8 + 3;

Best Answer

Bit addressing uses the lower 3 bits of the address to point to the bit within a byte.

So the bit is number (RB1 & 0x07) or 1 in your example, the byte address is (RB1 >> 3), or 0x06 in your example.