21.1.2 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.