My nearly microscopic 8051-based embedded system has a serial debug port, and I wrote a simple serial port output function that worked fine until I made a couple of small changes to it to reduce memory. Then the next line, which works fine (and was not part of the changes) ...
dbg_TxBuf[(dbg_TxBufProduceCount++) & (sizeof(dbg_TxBuf) - 1)] = ch;
... stopped working correctly. Variables dbg_TxBufand dbg_TxBufProduceCountare global variables used only by the output function and serial port ISR (which has not been changed at all):
#define DBG_TX_BUFFER_SIZE 16
volatile uint8_t xdata dbg_TxBuf[DBG_TX_BUFFER_SIZE];
volatile uint8_t xdata dbg_TxBufProduceCount;
volatile uint8_t xdata dbg_TxBufConsumeCount;
In particular, what happens is that the way the compiler now optimizes the line of code is that it dbg_TxBufProduceCountgrows (in memory) to the point at which it is chwritten to dbg_TxBuf. Then the ISR serial port “sometimes” (actually quite often) sees dbg_TxBufConsumeCount != dbg_TxBufProduceCountand reads dbg_TxBuf[(dbg_TxBufConsumeCount++) & (sizeof(dbg_TxBuf) - 1)]until the output function writes chto it. This way I get corrupted output on my serial port.
Here's the parsing 8051 of this line:
935> dbg_TxBuf[(dbg_TxBufProduceCount++) & (sizeof(dbg_TxBuf) - 1)] = ch;
DC84: 9006D6 MOV DPTR,
DC87: E0 MOVX A,@DPTR <--- loads the value in dbg_TxBufProduceCount into the A register
DC88: FE MOV R6,A <--- saves a copy of it in R6
DC89: 04 INC A <--- increments it
DC8A: F0 MOVX @DPTR,A <--- writes the incremented value
DC8B: EE MOV A,R6 <--- gets the original copy of ProduceCount back in A
DC8C: 7C00 MOV R4,
DC8E: 540F ANL A,
DC90: 24D8 ADD A,
DC92: F582 MOV DPL,A <--- put that in DPL
DC94: EC MOV A,R4 <--- (an inefficient way of loading the...
DC95: 3406 ADDC A,
DC97: F583 MOV DPH,A <--- DPTR now points to dbg_TxBuf[~]
DC99: EF MOV A,R7 <--- load 'ch' into A
DC9A: F0 MOVX @DPTR,A <--- write 'ch' to *DPTR
"" post-increment, dbg_TxBufProduceCount dbg_TxBuf, "" " , , , , dbg_TxBuf[], dbg_TxBufProduceCount volatile. dbg_TxBufProduceCount , ch ?
BTW Keil 8051 C, v7.10. , v7.10, , 2005 .