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 (
extern volatile unsigned char PORTB @ 0x006;
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?
When defining absolute bit variables (see Section 22.214.171.124 “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;