The difference between your sample code:
xdata UCHAR * data ecFlashaaa = (xdata UCHAR *)(0xaaa);
*ecFlashaaa = 0xaa;
And the accepted answer is that with xdata
the compiler will generate code very similar to your assembly snipet. The literal value 0xaa
will be written to location 0xaaa
in external RAM (or, in your case, what appears to be a memory mapped EEPROM in the external RAM space) in a few instructions.
The accepted answer with a generic pointer declared unsigned char *flashptr
will use a 3-byte type for flashptr
where the upper byte will indicate which memory space the address is in. So instead of being declared as a pointer to xdata
it is declared as a generic pointer and then assigned a value like {XDATA, 0x0AAA}
. Access to generic pointers is by calling a library routine which uses the correct instruction (mov
, movc
, or movx
) to access the memory.
The cost isn't too bad if you use a utility function (e.g. memcpy
) which is smart enough to determine the memory type once and then use an optimized copy loop. If you write your own copy loop the performance will be significantly worse if you use a generic pointer unnecessarily.
(The sample code you found that I quoted was probably written for Keil's C51 compiler)