The <nostub.h> header file


  
This header file will be automatically included in the program if any other header file from this library is used, except if you define the global preprocessor symbol USE_KERNEL, or if you explicitely include doors.h header file before including any other header file. This header file provides the basic support for making a "nostub" (kernel-less) program, i.e. program which does not need any kernels like DoorsOS or Plusshell (note that this does not imply that they can not work under DoorsOS or PlusShell). The disadvantage of "nostub" programs is in fact that they are somewhat longer than "DoorsOS" programs if the program contains many ROM calls, and they can not call routines from external files (often called "libraries"). Any other features supported with this library of header files work in both "DoorsOS" and "nostub" mode, so if the difference in the program size is not enormous, and if no external libraries are needed, "nostub" mode is highly recommended. Note that routines defined in these header files contain the most of routines which are seen in various external libraries, sometimes maybe with different name and syntax.

Principally, this header file defines one global symbol named NOSTUB which is used in other header files to indicate "nostub" mode, and defines one essential ROM-calling macro named _rom_call, which is intensively used in all other header files. This macro implements calling of ROM routines using indirect calls through the jump table. This macro is smart, and constructs function calls on such way that the compiler may perform compile-time checking of number and type of arguments (it, in fact, performs a type-casting of the jump table entry to an adequate function type). More concretely,
_rom_call (return_type, argument_type_list, jump_table_index)
constructs indirect ROM call for function whose index in the jump table is jump_table_index (this must be a hexadecimal number without 0x prefix), whose return type is return_type, and which needs arguments described in argument_type_list. This list is a list of types separated by commas, and enclosed in small brackets. For example, look the function memcpy which has the following prototype:

void *memcpy (void *dest, const void *src, unsigned long size);

If you know that the index of function memcpy in the jump table is 26A (these indexes are documented by TI), you principally can make following (terrible) construction to call memcpy passing dest, src and len as arguments to it:
_rom_call (void *, (void *, const void *, unsigned long), 26A) (dest, src, len);
This is awkward, of course. Life may become better if you define
#define memcpy _rom_call (void *, (void *, const void *, unsigned long), 26A)
Then, you can simply use, as in each "normal" C dialect:
memcpy (dest, src, len);
Better, isn't it? This is, in fact, what the most of the header files in this library does. Definition of this function may be simplified further, because "const" means nothing for built-in assembly functions, and passing of unsigned and signed arguments are the same:
#define memcpy _rom_call (void *, (void *, void *, long), 26A)
If you need more info about _rom_call macro, inspect various header files to see how some functions are implemented. Note that _rom_call is redirected in DoorsOS mode to implement (shorter) DoorsOS calling method (see doors.h for more info).

What else does this header file? It is much more complex than in releases of TIGCCLIB prior to 2.0, but you need not to call directly anything from it (many tasks will be performed automatically). First, it contains one assembly instruction which solves completely one essential bug in TIGCC which appears only in "nostub" mode. Without this patch, any program which has any static data (including strings) will crash, and even if the program has not static data, the first function in the program will always be executed first regardless whether it is _main or not. It also plays some tricks with the machine stack, necessary for supporting exit and atexit functions without overloading the size of the generated code. Next, this header file implements the necessary protocol for returning values to the TI-Basic (either using the expressions stack or through a variable) if the preprocessor symbol RETURN_VALUE is defined before including this header file. Finally, this header file makes some plays with preprocessor to redefine the symbol _main on such way that global symbol _nostub will be automatically exported to the linker from any source file in which _main function is defined (such plays are necessary to avoid multiple defining of the same symbol, which would not be allowed by the linker). So, you don't need to put
int _nostub;
in your program to produce a "nostub" program. This header file will do this automatically for you.

See also doors.h header file.

Return to the main index