Here's a tiny fragment of an 8051 Assembler-program witch does a calculated Jump:
* MOV A,Menue ADD A,Menue ADD A,Menue ;LJMP xyz => 3Bytes MOV DPTR,#Jump_tab_menue JMP @A+DPTR Jump_tab_menue: LJMP Screen_toggle LJMP Brightness LJMP Bargraph LJMP Yt_writer LJMP Temperatur_100 LJMP Temperatur_120 LJMP Speaker_on_off LJMP Calibrate LJMP ...
Can anybody give me a concrete example how this could be look like in C?
Thank's in advice
The compiler can automatically handle the case of a constant table of function pointers.
void Screen_toggle () { } // Screen_toggle void Brightness () ... // table of functions with signature void f(void); // stored in code memory code void (code* MenuRoutines[]) (void) = { Screen_toggle, Brightness, Bargraph, Yt_writer, Temperatur_100, Temperatur_120, Speaker_on_off, Calibrate }; void Menu () { choice = ShowMenu(); MenuRoutines[choice](); }
Function pointers start to become problematic when the compiler cannot construct the call tree by examining the code. Calling a function pointer that's passed in as a parameter from a separate module, for example, makes it hard for the compiler to tell what's part of the call tree below that point of call.
This is the point where you have to start giving the compiler some more information as described in the manual and tech notes: make all the called routines reentrant so that they use the dynamic run-time stack, or use the linker OVERLAY directive to instruct the compiler of the correct call tree (which is a lot of manual work).
http://www.keil.com/appnotes/docs/apnt_129.asp