home *** CD-ROM | disk | FTP | other *** search
-
- Data-Segment Initialization
-
- The Windows prolog and epilog contain instructions that
- initialize the DS register, setting the register to the
- segment address of the application or DLL. Windows requires
- callback functions, such as window, dialog box, and
- enumeration procedures, to initialize the DS register
- whenever they are called by Windows or an application. This
- guarantees that the function accesses its own data segment
- rather than the data segment of the caller.
-
- Exported Far Functions
-
- The Windows prolog used with exported far functions, such as
- dialog box and enumeration procedures, ensures that the DS
- register receives the data segment address for the
- application when Windows or an application calls the exported
- function. In Windows version 3.0 and earlier, the prolog and
- epilog for exported far functions have the following form:
- push ds ; put DS in AX, take 3 bytes to do it,
- pop ax ; so the code can be rewritten as
- nop ; MOV AX, IMM when appropriate
- inc bp ; push odd BP to indicate this stack
- push bp ; frame corresponds to a far CALL
- mov bp, sp ; set up BP to access arguments and
- ; local variables
- push ds ; save DS
- mov ds, ax ; set DS to proper data segment
- sub sp, const ; allocate local storage (optional)
- ...
- sub bp, 2 ; restore registers
- mov sp, bp
- pop ds
- pop bp
- dec bp
- retf
- Because Windows 3.1 does not support real mode, the inc bp and
- dec bp instructions are not required. Also, a variety of other
- changes can be made to the prolog and epilog to improve speed
- and reduce the size of the code. If a far function is part of
- an application (not part of a DLL), the SS register is already
- the proper value for the DS register, so calling the
- ________________
- MakeProcInstance function is not necessary. The prolog and
- epilog can be modified as follows:
- push bp ; set up stack frame (optional)
- mov bp, sp
- push ds ; save calling function's DS
- push ss ; move SS to DS
- pop ds
- ...
- pop ds ; restore registers
- pop bp
- retf
- An alternative form of the prolog and epilog for far functions
- follows:
- push bp ; set up stack frame (optional)
- mov bp, sp
- push ds ; save calling function's DS
- mov ax, ss ; move SS to DS
- mov ds, ax
- sub sp, const ; (optional) allocate local storage
- ...
- mov ds, [bp-2] ; restore registers
- leave
- retf
- Each of the variations of prolog and epilog code discussed
- previously works whether or not a far function is exported.
- The code can be called by an application or DLL as well as by
- the system.
- If an application copies the contents of the SS register to
- the DS register, it doesn't need to call the ________________
- MakeProcInstance
- function to obtain a procedure-instance address before calling
- an exported far function. Similarly, if a DLL moves the DGROUP
- data segment to the DS register through the AX register, the
- DLL doesn't need to call MakeProcInstance before calling an
- exported far function.
- Although window procedures for an application require this
- same prolog, Windows loads the AX register before calling
- these procedures. An application, therefore, never needs to
- create a procedure-instance address for its window procedures.
-
- Nonexported Far Functions
-
- Although not required, nonexported far functions can also
- include prolog code that initializes the DS register. In this
- case, it is assumed that the function is never called by
- Windows or an application and that the DS register contains
- the correct segment address when the function is called. The
- prolog for a nonexported function has the following form:
- mov ax, ds ; copy DS to AX
- nop
- push bp ; set up stack frame (optional)
- mov bp, sp
- push ds ; save calling function's DS
- mov ds, ax ; move same value back to DS
- ...
- pop ds ; pop same value back to DS
- pop bp
- retf
- An alternative form of the prolog for a nonexported function
- follows:
- push ds ; copy DS to AX
- pop ax
- nop
- push bp ; set up stack frame (optional)
- mov bp, sp
- push ds ; save calling function's DS
- mov ds, ax ; move same value back to DS
- ...
- pop ds ; pop same value back to DS
- pop bp
- retf
- A compiler should not generate the preceding code by default
- because it reloads the DS register with the same value two
- times per far call. Loading segment registers is a slow
- operation in protected mode and should be avoided as much as
- possible.
-
- Exported Far Functions in a Dynamic-Link Library
-
- Exported far functions in DLLs also require a prolog. The
- prolog code in a DLL must generate a reference to the DGROUP
- data segment. The SS register cannot be used because
- execution occurs on the calling function's stack. Exported
- far functions cannot use this method because fixups to DGROUP
- are illegal for a multiple instance application.
- The prolog and epilog for exported far functions in a DLL has
- the following form:
- mov ax, DGROUP ; get DGROUP value
- push bp ; set up stack frame (optional)
- mov bp, sp
- push ds ; save calling function's DS
- mov ds, ax ; move DGROUP to DS
- ...
- pop ds ; restore registers
- pop bp
- retf
- Following is an alternative form of the prolog for exported
- far functions in a DLL:
- mov ax, DGROUP ; get DGROUP value
- push bp ; set up stack frame (optional)
- mov bp, sp
- push ds ; save calling function's DS
- mov ds, ax ; move DGROUP to DS
- sub sp, const ; allocate local storage (optional)
- ...
- mov ds, [bp-2] ; restore registers
- leave
- Windows inserts the current data segment address as the second
- operand (DGROUP) of the initial mov instruction.
-
- Prologs in Real Mode
-
- When Windows 3.0 and earlier is running in real mode, Windows
- must walk each application stack whenever it moves or
- discards segments. In particular, it must check each stack
- for any segment addresses that may have been affected by the
- segment operations.
- To help Windows locate segment addresses associated with the
- stack frames of far functions, the Windows prolog increments
- the old frame pointer, contained in the BP register, before
- saving it on the stack. Because all stack offsets, including
- frame pointers, are expected to be word-aligned, incrementing
- the BP register gives Windows a quick way to locate all far
- function stack frames.
- Windows only walks the stack in real mode. In protected mode,
- selector values do not change even though Windows may move
- and discard segments. Therefore, functions in protected mode
- do not need to increment the BP register when they save it.
-
- Prologs in Protected Mode
-
- Although exported functions in protected-mode,
- single-instance applications need to set the DS register,
- these functions do not require the exported prolog described
- in the previous section. Instead, they can use code similar
- to that generated by the _loadds keyword of Borland C++.
- The code generated by __loadds copies the data segment
- selector to the DS register whenever the function is called.
- Because a selector does not change value when the
- corresponding segment is moved, there is no need to set the AX
- register to the appropriate data segment address before
- calling the function (or to mark the stack frame).
-
- Functions
- that use the _loadds code can be used as callback functions.
- Because no prolog code is required, the functions do not need
- to be exported when used in an application. Functions in DLLs
- can also use the _loadds code. However, the functions must be
- exported to ensure that other applications can link
- dynamically to them.
- In multiple-instance applications, the Windows prolog is
- needed only for far functions called by Windows. For these
- functions, procedure-instance addresses are required. The _
- _loadds code cannot be used in multiple-instance applications.
- Instead, applications should copy the SS register to the DS
- register.
-