CALL: Call Procedure

This page is a work in progress. It is incomplete, and may not be completely accurate or up to date.
For information about interpreting this page, see the help page.
Opcode and MnemonicEncoding16 bit Mode32 bit Mode64 bit ModeDescription
E8 cw
CALL rel16
DValidValidNot SupportedCall a near procedure with a relative offset stored in rel16.
E8 cd
CALL rel32
DValidValidValidCall a near procedure with a relative offset stored in rel32.
FF /2
CALL r/m16
MValidValidNot EncodableCall a near procedure with an absolute address stored in r/m16.
FF /2
CALL r/m32
MValidValidNot EncodableCall a near procedure with an absolute address stored in r/m32.
FF /2
CALL r/m64
MNot EncodableNot EncodableValidCall a near procedure with an absolute address stored in r/m64.
9A cww
CALL ptr16:16
DValidValidInvalidCall a far procedure with an absolute address stored in ptr16:16.
9A cwd
CALL ptr16:32
DValidValidInvalidCall a far procedure with an absolute address stored in ptr16:32.
FF /3
CALL m16:16
MValidValidValidCall a far procedure with an absolute indirect address stored in m16:16. In 32 bit mode, if the selector points to a gate, then RIP is set to the zero extended 32 bit displacement taken from the gate. If not, then RIP is set to the zero extended 16 bit offset from the far pointer in the instruction.
FF /3
CALL m16:32
MValidValidValidCall a far procedure with an absolute indirect address stored in m16:32. In 64 bit mode, if the selector points to a gate, then RIP is set to the 64 bit displacement taken from the gate. If not, then RIP is set to the zero extended 32 bit offset from the far pointer in the instruction.
REX.W FF /3
CALL m16:64
MNot EncodableNot EncodableValidCall a far procedure with an absolute indirect address stored in m16:64. If the selector points to a gate, then RIP is set to the 64 bit displacement taken from the gate. If not, then RIP is set to the 64 bit offset from the far pointer in the instruction.

Encoding

EncodingOperand
DOffset[r]
MModRM.r/m[r]

Description

The CALL instruction saves a return address on the stack before jumping to the called procedure whose address is specified in the operand.

Operation

This pseudo-code uses C# syntax. A list of the types used is available here.
// TODO

Flags Affected

CF (carry flag)
Affected only if a task switch occurs.
PF (parity flag)
Affected only if a task switch occurs.
AF (auxiliary flag)
Affected only if a task switch occurs.
ZF (zero flag)
Affected only if a task switch occurs.
SF (sign flag)
Affected only if a task switch occurs.
OF (overflow flag)
Affected only if a task switch occurs.

Exceptions

Protected Mode

#GP(0)
If the target offset in the operand is beyond the new code segment limit.
If the segment selector in the operand is NULL.
If the code segment selector in the gate is NULL.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the DS, ES, FS, or GS segment register is used to access memory and it contains a NULL segment selector.
If the target mode is compatibility mode and SSP is not in the low 4 GiB.
If SSP in IA32_PLi_SSP (where i is the new CPL) is not 8 byte aligned.
If "supervisor shadow stack" token on the new shadow stack is marked busy.
If the destination mode is protected or compatibility mode, but SSP in "supervisor shadow stack" token is beyond 4 GiB.
If SSP in "supervisor shadow stack" token does not match SSP address in IA32_PLi_SSP (where i is the new CPL).
#GP(selector)
If a code segment or gate or TSS selector index is outside descriptor table limits.
If the segment descriptor pointed to by the segment selector in the destination operand is not for a conforming-code segment, nonconforming-code segment, call gate, task gate, or task state segment.
If the DPL for a nonconforming-code segment is not equal to the CPL or the RPL for the segment's segment selector is greater than the CPL.
If the DPL for a conforming-code segment is greater than the CPL.
If the DPL from a call-gate, task-gate, or TSS segment descriptor is less than the CPL or than the RPL of the call-gate, task-gate, or TSS's segment selector.
If the segment descriptor for a segment selector from a call gate does not indicate it is a code segment.
If the segment selector from a call gate is beyond the descriptor table limits.
If the DPL for a code-segment obtained from a call gate is greater than the CPL.
If the segment selector for a TSS has its local/global bit set for local.
If a TSS segment descriptor specifies that the TSS is busy or not available.
#SS(0)
If pushing the return address, parameters, or stack segment pointer onto the stack exceeds the bounds of the stack segment (if no stack switch occurs).
If a memory operand effective address is outside the SS segment limit.
#SS(selector)
If pushing the return address, parameters, or stack segment pointer onto the stack exceeds the bounds of the stack segment (when a stack switch occurs).
If the SS segment register is being loaded as part of a stack switch and the segment pointed to is marked not present.
#NP(selector)
If a code segment, data segment, call gate, task gate, or TSS is not present.
#TS(selector)
If the new stack segment selector and ESP are beyond the end of the TSS.
If the new stack segment selector is NULL.
If the RPL of the new stack segment selector in the TSS is not equal to the DPL of the code segment being accessed.
If the new stack segment is not a writable data segment.
If the segment-selector index for a stack segment is outside the descriptor table limits.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.
#UD
If the LOCK prefix is used.

Real-Address Mode

#GP
If a memory effective address is outside the CS, DS, ES, FS, or GS segment limit.
#UD
If the LOCK prefix is used.

Virtual-8086 Mode

#GP(0)
If a memory effective address is outside the CS, DS, ES, FS, or GS segment limit.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.
#UD
If the LOCK prefix is used.

Compatibility Mode

#GP(0)
If the target offset in the operand is beyond the new code segment limit.
If the segment selector in the operand is NULL.
If the code segment selector in the gate is NULL.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the DS, ES, FS, or GS segment register is used to access memory and it contains a NULL segment selector.
If the target mode is compatibility mode and SSP is not in the low 4 GiB.
If SSP in IA32_PLi_SSP (where i is the new CPL) is not 8 byte aligned.
If "supervisor shadow stack" token on the new shadow stack is marked busy.
If the destination mode is protected or compatibility mode, but SSP in "supervisor shadow stack" token is beyond 4 GiB.
If SSP in "supervisor shadow stack" token does not match SSP address in IA32_PLi_SSP (where i is the new CPL).
If the target offset in the operand is in non-canonical form.
#GP(selector)
If a code segment or gate or TSS selector index is outside descriptor table limits.
If the segment descriptor pointed to by the segment selector in the destination operand is not for a conforming-code segment, nonconforming-code segment, call gate, task gate, or task state segment.
If the DPL for a nonconforming-code segment is not equal to the CPL or the RPL for the segment's segment selector is greater than the CPL.
If the DPL for a conforming-code segment is greater than the CPL.
If the DPL from a call-gate, task-gate, or TSS segment descriptor is less than the CPL or than the RPL of the call-gate, task-gate, or TSS's segment selector.
If the segment descriptor for a segment selector from a call gate does not indicate it is a code segment.
If the segment selector from a call gate is beyond the descriptor table limits.
If the DPL for a code-segment obtained from a call gate is greater than the CPL.
If the segment selector for a TSS has its local/global bit set for local.
If a TSS segment descriptor specifies that the TSS is busy or not available.
If a memory addressed accessed by the selector is is non-canonical form.
#SS(0)
If pushing the return address, parameters, or stack segment pointer onto the stack exceeds the bounds of the stack segment (if no stack switch occurs).
If a memory operand effective address is outside the SS segment limit.
#SS(selector)
If pushing the return address, parameters, or stack segment pointer onto the stack exceeds the bounds of the stack segment (when a stack switch occurs).
If the SS segment register is being loaded as part of a stack switch and the segment pointed to is marked not present.
#NP(selector)
If a code segment, data segment, call gate, task gate, or TSS is not present.
#TS(selector)
If the new stack segment selector and ESP are beyond the end of the TSS.
If the new stack segment selector is NULL.
If the RPL of the new stack segment selector in the TSS is not equal to the DPL of the code segment being accessed.
If the new stack segment is not a writable data segment.
If the segment-selector index for a stack segment is outside the descriptor table limits.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.
#UD
If the LOCK prefix is used.

Long Mode

TODO