22.1 Startup Requirements

When Windows starts an application, it calls a startup routine supplied with the application rather than the application's WinMain function. The startup routine is responsible for initializing the application, calling WinMain, and exiting the application when WinMain returns control.

When Windows first calls the startup routine, the processor registers have the following values:

Register Value

AX Contains zero.
BX Specifies the size, in bytes, of the stack.
CX Specifies the size, in bytes, of the heap.
DI Contains a handle identifying the new application instance.
SI Contains a handle identifying the previous application instance.
BP Contains zero.
ES Contains the segment address of the program segment prefix (PSP).
DS Contains the segment address of the automatic data segment for the application.
SS Same as the DS register.
SP Contains the offset to the first byte of the application stack.

To initialize and exit a Windows application, the startup routine must follow these steps:

1.Initialize the task by using the InitTask function. InitTask also returns values that the startup routine passes to the WinMain function.

2.Clear the event that started the task by calling the WaitEvent function.

3.Initialize the queue and support routines for the application by calling the InitApp function with the instance handle returned by the InitTask function.

4.Call the entry point for the application, the WinMain function.

5.Exit the application by calling the MS-DOS End Program function (Interrupt 21h Function 4Ch) when WinMain returns.

Although the startup routine is essentially the same for all Windows applications, a variety of startup routines may need to be developed to accommodate the different memory models and high-level language run-time libraries used by Windows applications. If a Windows application uses functions and variables provided by run-time libraries, the startup routine may need to be customized to initialize the library at the same time as the application. Customizing the startup routine for run-time library initialization is entirely dependent on the library and is, therefore, beyond the scope of this chapter.