background image

CALL—Call Procedure

INSTRUCTION SET REFERENCE, A-L

3-124 Vol. 2A

Near Call. 

When executing a near call, the processor pushes the value of the EIP register (which contains the offset 

of the instruction following the CALL instruction) on the stack (for use later as a return-instruction pointer). The 
processor then branches to the address in the current code segment specified by the target operand. The target 
operand specifies either an absolute offset in the code segment (an offset from the base of the code segment) or a 
relative offset (a signed displacement relative to the current value of the instruction pointer in the EIP register; this 
value points to the instruction following the CALL instruction). The CS register is not changed on near calls.
For a near call absolute, an absolute offset is specified indirectly in a general-purpose register or a memory location 
(r/m16r/m32, or r/m64). The operand-size attribute determines the size of the target operand (16, 32 or 64 bits). 
When in 64-bit mode, the operand size for near call (and all near branches) is forced to 64-bits. Absolute offsets 
are loaded directly into the EIP(RIP) register. If the operand size attribute is 16, the upper two bytes of the EIP 
register are cleared, resulting in a maximum instruction pointer size of 16 bits. When accessing an absolute offset 
indirectly using the stack pointer [ESP] as the base register, the base value used is the value of the ESP before the 
instruction executes.
A relative offset (rel16 or rel32) is generally specified as a label in assembly code. But at the machine code level, it 
is encoded as a signed, 16- or 32-bit immediate value. This value is added to the value in the EIP(RIP) register. In 
64-bit mode the relative offset is always a 32-bit immediate value which is sign extended to 64-bits before it is 
added to the value in the RIP register for the target calculation. As with absolute offsets, the operand-size attribute 
determines the size of the target operand (16, 32, or 64 bits). In 64-bit mode the target operand will always be 64-
bits because the operand size is forced to 64-bits for near branches.

Far Calls in Real-Address or Virtual-8086 Mode.

 When executing a far call in real- address or virtual-8086 mode, the 

processor pushes the current value of both the CS and EIP registers on the stack for use as a return-instruction 
pointer. The processor then performs a “far branch” to the code segment and offset specified with the target 
operand for the called procedure. The target operand specifies an absolute far address either directly with a pointer 
(ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). With the pointer method, the 
segment and offset of the called procedure is encoded in the instruction using a 4-byte (16-bit operand size) or 6-
byte (32-bit operand size) far address immediate. With the indirect method, the target operand specifies a memory 
location that contains a 4-byte (16-bit operand size) or 6-byte (32-bit operand size) far address. The operand-size 
attribute determines the size of the offset (16 or 32 bits) in the far address. The far address is loaded directly into 
the CS and EIP registers. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared.

Far Calls in Protected Mode.

 When the processor is operating in protected mode, the CALL instruction can be used to 

perform the following types of far calls:

Far call to the same privilege level

Far call to a different privilege level (inter-privilege level call)

Task switch (far call to another task)

In protected mode, the processor always uses the segment selector part of the far address to access the corre-
sponding descriptor in the GDT or LDT. The descriptor type (code segment, call gate, task gate, or TSS) and access 
rights determine the type of call operation to be performed.
If the selected descriptor is for a code segment, a far call to a code segment at the same privilege level is 
performed. (If the selected code segment is at a different privilege level and the code segment is non-conforming, 
a general-protection exception is generated.) A far call to the same privilege level in protected mode is very similar 
to one carried out in real-address or virtual-8086 mode. The target operand specifies an absolute far address either 
directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32). The 
operand- size attribute determines the size of the offset (16 or 32 bits) in the far address. The new code segment 
selector and its descriptor are loaded into CS register; the offset from the instruction is loaded into the EIP register. 
A call gate (described in the next paragraph) can also be used to perform a far call to a code segment at the same 
privilege level. Using this mechanism provides an extra level of indirection and is the preferred method of making 
calls between 16-bit and 32-bit code segments.
When executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed 
through a call gate. The segment selector specified by the target operand identifies the call gate. The target 
operand can specify the call gate segment selector either directly with a pointer (ptr16:16 or ptr16:32) or indirectly 
with a memory location (m16:16 or m16:32). The processor obtains the segment selector for the new code 
segment and the new instruction pointer (offset) from the call gate descriptor. (The offset from the target operand 
is ignored when a call gate is used.)