Is there a difference between the following two statements: 1.
char far SL811 _at_ 0x07F7FF; SL811 = 0x0D;
#define SL811 *((char far *)0x07F7FF) SL811 = 0x0D;
The main thing to keep in mind is that the bit pattern for a far pointer is not an absolute address in a large memory space. The 8051 actually has many independent memory address spaces (code, data, xdata, idata, pdata). The standard C language (along with many processor architectures) assumes there's only one address space. This causes a problem on the 8051. There's not just one "address 0"; you also have to know which memory space you're talking about. Pointers in C51 thus are either memory-specific that are declared to point to a particular kind of memory space and only that memory space, e.g. U8 xdata* px; // can only point to xdata U8 data* pd; // can only point to data px = pd; // error Or, the pointer is "generic": U8* pg; pg = pd; // ok pg = px; // ok px = pg; // maybe ok or not, depending on value of pg. The generic pointer format is 3 bytes, including a tag byte that indicates the memory space. The far pointer format is the same. There's some description in the manual, but my favorite documentation for this feature is the comments in the sample L51_BANK.A51 file (see the lib director in your installation).
; R3 Value | Memory Type | Memory Class | Address Range * ; -----------------------+--------------+-------------------------- * ; 00 | data/idata | DATA/IDATA | I:0x00 .. I:0xFF * ; 01 | xdata | XDATA | X:0x0000 .. X:0xFFFF * ; 02..7F | far | HDATA | X:0x010000 .. X:0x7E0000 * ; 80..FD | far const | HCONST | C:0x800000 .. C:0xFD0000 (see note) * ; FE | pdata | XDATA | one 256-byte page in XDATA memory * ; FF | code | CODE | C:0x0000 .. C:0xFFFF