12.5.9 The /FARCALL Option

Option

/F[[ARCALLTRANSLATION]]

The /FARCALL option directs the linker to optimize far calls to procedures that lie in the same segment as the caller. This can result in slightly faster code; the gain in speed is most apparent on 80286-based machines and later. The /PACKC option can be used with /FARCALL when linking for OS/2. /PACKC is not recommended when linking Windows applications with /FARCALL.

The /FARCALL option is off by default. If an environment variable (such as LINK or FL) includes /FARCALL, you can use the /NOFARCALL option to override it.

Summary: FARCALL optimizes by creating more efficient code.

A program that has multiple code segments may make a far call to a procedure in the same segment. Since the segment address is the same (for both the code and the procedure it calls), only a near call is necessary. Far calls appear in the relocation table; a near call does not require a table entry. By converting far calls to near calls in the same segment, the /FARCALL option both reduces the size of the relocation table and increases execution speed, since only the offset needs to be loaded, not a new segment. The /FARCALL option has no effect on programs that make only near calls, since there are no far calls to convert.

When /FARCALL is specified, the linker optimizes code by removing the instruction call FAR label and substituting the following sequence:

nop

push cs

call NEAR label

During execution, the called procedure still returns with a far-return instruction. However, because both the code segment and the near address are on the stack, the far return is executed correctly. The nop (no-op) instruction is added so that exactly five bytes replace the five-byte far-call instruction.

Summary: In rare cases, /FARCALL should be used with caution.

There is a small risk with the /FARCALL option. If LINK sees the far-call opcode (9A hexadecimal) followed by a far pointer to the current statement, and that segment has a class name ending in CODE, it interprets that as a far call. This problem can occur when using _based (segname ("CODE")) in a C program. If a program linked with /FARCALL fails for no apparent reason, try using /NOFARCALL.

Object modules produced by Microsoft high-level languages are safe from this problem because little immediate data is stored in code segments. Assembly-language programs are generally safe for use with the /FARCALL option if they do not involve advanced system-level code, such as might be found in operating systems or interrupt handlers.