call

Call procedure

Calls a subroutine by pushing the return address onto the stack (with cs for a far call), then jumps to the given address.

8086 and later

Intel's reference: CALL

CFPFAFZFSFDFOF –––––––
  • Changes no flag

Forms

  • call near
  • call near

Operands

imm64
A branch target, written as a label or address. NASM calculates the displacement from the end of the instruction. In 64-bit mode the encoded displacement is signed 32-bit, -2147483648 to 2147483647, even though the target address is 64-bit.
r/m64
A 64-bit general-purpose register or quadword in memory, for example rax or qword [rsi].
mem
A memory location addressed with square brackets, for example [rbx+8] or [label].

An ordinary near call in 64-bit code pushes an 8-byte return address using rsp; ret returns to that address.

call routine names a target address or label. NASM calculates a signed 32-bit displacement from the end of the call, so the target must be within that range (about ±2 GiB). The source operand is the target, not a displacement to add yourself. There is no direct near call with an embedded absolute 64-bit target.

call rax takes the full target address from rax. call [pointer] reads an 8-byte target address from memory. These indirect near calls can reach targets beyond the relative displacement range.

A far call also changes cs. Its memory pointer stores an offset followed by a 16-bit segment selector: word, dword and qword far pointers have 16-, 32- and 64-bit offsets, for totals of 4, 6 and 10 bytes. Immediate segment:offset calls are unavailable in 64-bit mode. Far transfers depend on valid operating-system segment descriptors and are not ordinary Linux function calls.

global _start

section .text
_start:
        mov rax, 12
        call double         ; pushes the return address and jumps
        jmp done

double:
        add rax, rax
        ret                 ; pops it and comes back

done:

        mov rax, 60         ; syscall 60: exit
        xor rdi, rdi
        syscall