# Regarding Microchip XC8 compiler's registers and bits definitions

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;

• In this .h, it is completely different: ecse.rpi.edu/courses/CStudio/SDCC%20Compiler/sdcc-src-2.8.0/… – Swanand Jul 29 '14 at 11:23
• @Swanand Yeah, they use unions and structs to define the register's bits. The Microchip compilers do that as well, besides the definitions I mentioned.. – m.Alin Jul 29 '14 at 11:29

• I don't think I understand your explanation. Take the expression from the bit definition: @ (((unsigned) &PORTB)*8) + 1; Let's evaluate this expression: &PORTB = 0x06. 0x06 * 8 = 0x30 (0b00110000). 0x30 + 1 = 0x31 (0b00110001). How is 0x31 the address of bit 1 of PORTB? – m.Alin Jul 29 '14 at 8:42