Segmentation

Most of the 80286's protected-mode capabilities revolve around a change in the way memory is addressed. In real mode, the 80286 essentially emulates an 8088/86 processor, and the value in a segment register corresponds directly to a physical memory address. MS-DOS runs on the 80286 in real mode.

When an 80286 is running in protected mode, as it does under OS/2, an additional level of indirection is added to memory addressing. Although the 80386 has additional modes and addressing capabilities, current versions of OS/2 use the 80386 as though it were an 80286. A segment register holds a selector, which is an index to a table of descriptors. A descriptor defines the physical address and length of a memory segment, its characteristics (executable, read-only data, or read/write data) and access rights, and whether the segment is currently resident in RAM or has been swapped out to disk. Each time a program loads a segment register or accesses memory, the 80286 hardware checks the associated descriptor and the program's privilege level, generating a fault if the selector or memory operation is not valid. The fault acts like a hardware interrupt, allowing the operating system to regain control and take the appropriate action.

This scheme of memory addressing in protected mode has two immediate

consequences for application programs. The first is that application

programs can no longer perform arithmetic on the contents of segment

registers (because selectors are magic numbers and have no direct

relationship to physical memory addresses) or use segment registers for

storage of temporary values. A program must not load a segment register

with anything but a legitimate selector provided by the OS/2 loader or

resulting from an OS/2 memory allocation function call. The second

consequence is that a program must strictly segregate machine code

("text") from data, placing them in separate segments with distinct

selectors (because a selector that is executable is not writable, and vice

versa).

Accordingly, the first step in converting a program for OS/2 is to turn it

into a .EXE-type program that uses the Microsoft segment, class, and group

conventions described in Chapter 3. At minimum, the program must have one

code segment and one data segment, and should declare a group——with the

special name DGROUP——that contains the "near" data segment, stack, and

local heap (if any). At the same time, you should remove or rewrite any

code that performs direct manipulation of segment values.

After restructuring and segmentation, reassemble and link your program and check to be sure it still works as expected under MS-DOS. Changing or adding segmentation often uncovers hidden addressing assumptions in the code, so it is best to track these problems down before making other substantive changes to the program.