This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Absolute addressing question

Is there a difference between the following two statements:

1.

char far SL811 _at_ 0x07F7FF;
       SL811 = 0x0D;
  

2.
#define SL811 *((char far *)0x07F7FF)
       SL811 = 0x0D;
  

I've been having trouble with pointers and this will help me understand a little better.

Thanks!

  • 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
    

    Note that 0 is the tag byte for data, while 1 is the tag value for xdata. This means that the 3-byte pointer value for xdata offset 0 is actually 01 00 00, or 0x10000. The first "far" segment starts at tag value 2, or 0x20000, which corresponds to address 0x10000 (if you imagine that far is the same address space as xdata).

    In short, if you start directly manipulating far pointer values as integers, you have to be aware that "the address" of far data is 0x10000 different than what you might expect.