### Create Code to Run at Ring Zero (OS/2)

Most object code runs at ring 3. However, some object code, such as that for virtual device drivers and operating systems, must run at ring 0. To generate code to run at ring 0, use the /Gr compiler option. To use this option, you must also specify the /Rn compiler option and use the subsystem libraries.

When you use the /Gr compiler option, the compiler keeps track of which storage references are to the stack segment and which references are to the data segment, and ensures that the generated code is correct for these operations. This tracking is necessary because at ring 0, the stack segment and data segment may not be the same. (At ring 3, they are the same.)

In some cases, the compiler cannot tell whether the reference is to the stack or data segment. Usually the reason is that the control flow of the program allows for either possibility, depending on which path through the program is taken at run time. For this reason, when you take the address of a stack-based variable (such as a local variable or parameter), you cannot safely pass the address to another function. In addition, you cannot safely store a stack address and a static or external address in the same variable and subsequently de-reference the pointer created by the operation.

Whenever you take the address of a stack-based variable, the compiler generates a warning message that the address might be used in an unsafe way. This message is not generated if you specify /Gr-.

If your VDD contains any functions that are called from 16-bit physical device drivers, you must compile them with the /Gv+ compiler option to ensure the DS and ES registers are handled correctly. These two registers contain the selector for a 16-bit data segment. Using /Gv+ ensures that DS and ES are saved on entry to an external function, set to the selector for DGROUP, and then restored on exit from the function.

Developing Virtual Device Drivers in OS/2
Calling between 32-bit and 16-bit code

Summary of Compiler Options