CPU: 8051 based
The following lines of code will set 0xaa
value at 0x0aaa
address in external flash memory.
mov a,#0aah
mov dptr,#X0aaa
movx @dptr,a
The following is mov
The MOV instruction allows data to be transferred between any internal I-RAM spaces or SFR locations and between accumulator to internal I-RAM spaces or SFR locations.
and and movx instruction descriptions from CPU datasheet
MOVX instruction is used to access the internal X-RAM and e-FLASH area. Only indirect addressing can be used. The choice whether to use a one-byte address, @Ri, where Ri can be either R0 or R1 of the selected register bank, or a two-byte address, @DPTR.
Some code that I've seen in examples:
xdata UCHAR * data ecFlashaaa = (xdata UCHAR *)(0xaaa);
*ecFlashaaa = 0xaa;
the code doesn't compile because it doesn't know what is xdata
and also confused on data
. So somehow I need to explain linker that ecFlashaaa is pointing to e-Flash...
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)