I've included a function below and the generated STM8 assembly-language. As it ends up (based on the assembly-language), the function is interrupt safe as intended.
My question is, let's assume I have this:
DI(); if (x) x--; EI();
where DI and EI just expand to the compiler's asm( ) feature to insert the right machine instruction to disable and enable interrupts, ...
Is there any reason that the compiler cannot delay writing "x" back so that I get effectively this:
DI(); cpu_register = x; if(cpu_register) cpu_register--; EI(); x = cpu_register;
???
It isn't clear to me if "volatile" is required on "x" or if there is any possibility of the write of the variable back to memory being delayed.
Thanks for any insight.
Function below.
The Lizard
----------
//-------------------------------------------------------------------------------- //DESCRIPTION // Decrements an array of zero or more 8-bit unsigned integers, but not // below zero. This function is intended for software timers, but may have // other applications as well. // //INPUTS // in_arg // Pointer to first element to be decremented. This pointer must // be valid if in_nelem > 0. // // in_nelem // Number of elements to be decremented. If this value is 0, in_nelem // will not be dereferenced and may be NULL or otherwise invalid. // //INTERRUPT CONSIDERATIONS // This function must be called only with interrupts enabled (it uses simple // DI/EI protocol). // // This function may be called from non-ISR software only. // // In the case of software timers, individual software timers may be safely // shared with interrupt service, due to the critical section protocol. So, // an ISR may safely set and test software timers. Note that the behavior // of individual software timers is guaranteed by DI/EI, but the relationship // between timers is not, as an interrupt may occur while an array or sets // of arrays are being decremented. // //MNEMONIC // "dec" : decrement. // "u8" : unsigned 8-bit. // "arr" : array. // "nbz" : not below zero. // //UNIT TEST HISTORY // // //-------------------------------------------------------------------------------- void MF_decu8arr_nbz(UINT8 *in_arg, UINT16 in_nelem) { while (in_nelem) { DI(); if (*in_arg) (*in_arg)--; EI(); in_nelem--; } }
700 ; 289 void MF_decu8arr_nbz(UINT8 *in_arg, UINT16 in_nelem) 700 ; 290 { 701 switch .text 702 00b4 f_MF_decu8arr_nbz: 704 00b4 89 pushw x 705 00000000 OFST: set 0 708 00b5 200d jra L552 709 00b7 L352: 710 ; 293 DI(); 713 00b7 9b sim 715 ; 294 if (*in_arg) 717 00b8 1e01 ldw x,(OFST+1,sp) 718 00ba f6 ld a,(x) 719 00bb 2701 jreq L162 720 ; 295 (*in_arg)--; 722 00bd 7a dec (x) 723 00be L162: 724 ; 296 EI(); 727 00be 9a rim 729 ; 297 in_nelem--; 731 00bf 1e06 ldw x,(OFST+6,sp) 732 00c1 5a decw x 733 00c2 1f06 ldw (OFST+6,sp),x 734 00c4 L552: 735 ; 291 while (in_nelem) 737 00c4 1e06 ldw x,(OFST+6,sp) 738 00c6 26ef jrne L352 739 ; 299 } 742 00c8 85 popw x 743 00c9 87 retf