[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Coding for protected mode
------------------------------------------------------------------------------


 Converting your code

 The major point on converting your code is that the higher level the
 language, the easier it is to convert your code. High level languages such
 as CA-Clipper require no code changes whatsoever as the code actually
 executing is contained in the CLIPPER.LIB file itself. Medium level
 languages such as C, PASCAL, FORTRAN etc in their pure form also require no
 code changes. Almost the only time changes are needed is when the programmer
 has hard coded direct access to system resources, such as using an absolute
 pointer to a video buffer.

 This type of code needs to be adapted slightly to store and use the pointer
 in a variable which is set up at the beginning of the program. For example,
 in the case of video writes, a system call would be made at start up to set
 up a pointer to the video buffer. This would either be an absolute pointer
 if the program is in real mode, or a selector if the program is in protected
 mode. From then on, all video memory accesses are made using the same
 pointer, regardless of the processor mode, so there is no further overhead
 in code or execution time.

 Assembly code is the most likely to require conversion, as it provides
 direct access to system resources which may not be available in protected
 mode. The code requiring conversion is similar in nature to that previously
 described, it is simply more likely to be prevalent in assembly code.

 A final construct requiring conversion relates to segment addresses. In
 protected mode segments are not allocated sequentially and are not
 contiguous, thus comparison of segment addresses is invalid. For example,
 sequential allocation of segments from the DOS extender will at best produce
 selectors separated by an increment of 8, and at worst produce them in a
 seemingly random sequence. This is because the selectors are simply pointers
 into an array known as a descriptor table, and the low three bits of the
 selector are used to store control information. For more details see the
 DosGetHugeShift() function in Chapter 10.

 To put this conversion process in perspective, in case it sounds an enormous
 task, we recently converted Blinker to run in dual mode. Blinker currently
 consists of approximately 60,000 lines (4MB) of pure assembly code, which is
 the worst kind of code to convert. The whole conversion to run in dual mode,
 ie normal DOS mode OR protected mode under our own extender, took one
 programmer less than a day. The code is now totally compatible with both
 modes with no conditionally compiled code, and the extra overhead is less
 than 100 lines called at various initialisation points at the beginning of
 the program.

 Debugging under protected mode makes the detection of code to convert
 relatively simple, just run the code and see where it stops with a
 protection exception. Typically an error message will be displayed
 indicating the location and type of the error, and the program will return
 to DOS. When running under Windows 3.x or OS/2 2.x this can be done many
 times without requiring a reboot of the machine.

 Special considerations for protected mode code

 Incompatibilities with protected mode usually arise from certain
 restrictions which were designed into the processor to provide better
 protection and isolation between multiple programs running on the same
 processor. High level language compilers can often detect code which will
 break these restrictions, while other disallowed constructs will only become
 apparent when the code is actually executed at run time. Restrictions on
 coding techniques include :

    .  Attempts to access addresses outside (i.e. past the end of) valid
       segments will cause a protection exception.
    .  Attempts to directly modify code during execution, or to directly
       execute data, will cause a protection exception.
    .  Using segment registers for any other purpose than as segment
       registers. Some code uses the segment registers as a temporary store
       rather than writing it to memory. Whenever the value of a segment
       register is modified the value must be a valid selector or a
       protection exception will occur.
    .  Performing real mode address arithmetic e.g. pointer normalisation,
       since segments are no longer contiguous or even adjacent. This usually
       occurs when managing data items larger than 64kb, and must be
       re-programmed.
    .  All pointers to data buffers which will be passed to real mode code,
       such as when issuing a software interrupt or communicating with a TSR,
       must be valid real mode addresses, so the buffers must have been
       allocated from real memory below 1 MB. The only exceptions to this are
       the DOS INT 21 function calls which are handled transparently.

 It should be emphasised again that occurrences of these coding constructs
 are definitely the exception rather than the rule, and that the higher level
 the language, the less likely one of these constructs is to occur.

This page created by ng2html v1.05, the Norton guide to HTML conversion utility. Written by Dave Pearson