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 /FARCALL option is on by default for overlaid DOS programs and programs created with the /TINY option. It is off by default for other programs. If an environment variable (such as LINK or CL) includes /FARCALL, you can use the /NOFARCALL option to override it. The /PACKC option is not recommended when linking Windows applications with /FARCALL.

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 because 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 segment, 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.