Using and Preserving Registers

In general, you should not assume that a register will have a given value when an __asm block begins. An __asm block inherits whatever register values happen to result from the normal flow of control.

As you may have noticed in the POWER2.C example in the previous section, the power2 function doesn't preserve the value in the AX register. When you write a function in assembly language, you don't need to preserve the AX, BX, CX, DX, ES, and flags registers. However, you should preserve any other registers you use (DI, SI, DS, SS, SP, and BP).

WARNING:

If your inline assembly code changes the direction flag using the STD or CLD instructions, you must restore the flag to its original value.

The POWER2.C example in the previous section also shows that functions return values in registers. This is true whether the function is written in assembly language or in C.

Summary: Functions return values in the AX and DX registers.

If the return value is short (a char, int, or near pointer), it is stored in AX. The POWER2.C example returned a value by terminating with the desired value in AX.

If the return value is long, store the high word in DX and the low word in AX. To return a longer value (such as a floating-point value), store the value in memory and return a pointer to the value (in AX if near or in DX:AX if far).

Assembly instructions that appear inline with C statements are free to alter the AX, BX, CX, and DX registers. C doesn't expect these registers to be maintained between statements, so you don't need to preserve them. The same is true of the SI and DI registers, with some exceptions. For more information, see “Optimizing,”. You should preserve the SP and BP registers unless you have some reason to change them—to switch stacks, for instance.