Instruction
ENDBR64
Marks a valid target of an indirect call or jump in 64-bit code for CET indirect branch tracking; a NOP on other processors.
- Extensions
- Forms
- 1 (1 Legacy)
- Data
- Intel XED v2026.08.23
ENDBR64 marks an address as a valid target of an indirect CALL or JMP in 64-bit code. It belongs to the indirect branch tracking of Intel’s CET: while tracking is on, an indirect CALL or JMP must land on an ENDBR64, or the processor raises #CP at the target, before it runs the instruction there. ENDBR64 itself changes no register and no flag; it only returns the tracker to its idle state. Without tracking it is a NOP: on processors without CET, while tracking is off, and outside 64-bit mode, where ENDBR32 does its job.
Four bytes of NOP space
F3 0F 1E FA lies in the reserved hint space 0F 18 to 0F 1F that the NOP page describes, so the same binary runs everywhere: a CET-aware processor checks the marks, an older one skips them. Direct CALLs and JMPs, conditional jumps and RET are not tracked; RET is the shadow stack’s business. AMD’s manuals describe CET’s shadow stacks but not this tracking, and list no ENDBR64. This Zen 5 reported no indirect branch tracking in CPUID and ran both recorded cases as a NOP.
Where compilers put it
GCC 14 and Clang 23 emit ENDBR64 only when asked, with
-fcf-protection=branch or =full. Then at -O2:
- every function that can be reached indirectly begins with it: every
function with external linkage, and a
staticone whose address is taken. Astaticfunction only called directly gets none; - it follows each call to
setjmp, aslongjmpcomes back to that point with an indirect jump; - the jump through a
switchtable carries a 3E prefix,notrack jmp, which exempts it where the OS allows, so the case labels need no ENDBR64; __attribute__((nocf_check))leaves it out of a function.
Things to know
- What it checks. Only that the target is some ENDBR64: a corrupted function pointer can still reach the start of any marked function, but not the middle of one.
- Separate trackers. User and supervisor mode each have their own state, enabled by IA32_U_CET and IA32_S_CET.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
ENDBR64
ENDBR64 | F3 0F 1E FA | CET |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
if cr4 >> 23 & 1: # CR4.CET; a processor without CET
# has it clear: then a NOP
if CPL == 3:
if u_cet >> 2 & 1: # ENDBR_EN: tracking on
u_cet = u_cet & ~0xC00
# TRACKER back to IDLE, SUPPRESS
# cleared, whatever they were
elif s_cet >> 2 & 1:
s_cet = s_cet & ~0xC00
# outside 64-bit mode a NOP that ends no branch: ENDBR32 does there.
# AMD's manuals describe CET's shadow stacks only, not this tracking,
# and list no ENDBR64, whose bytes are a hint NOP there as on older
# processorsRun on AMD Zen 5 (EPYC 9645): 2 cases. Its cases ran where CPUID reported no CET.
Operands
None: XED lists no operands for this form.
Flags
None: XED records no flag that the forms test or change.
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
| ISA set | CPUID | Processors |
|---|---|---|
CET | CET | Tiger Lake, Alder Lake, Arrow Lake, Panther Lake, Nova Lake, Sapphire Rapids, Emerald Rapids, Granite Rapids, Diamond Rapids, Sierra Forest, Clearwater Forest, Zen 3, Zen 4, Zen 5, Zen 6 Note: Zen 3 to Zen 6 have the shadow stacks of CET but not its indirect branch tracking, so ENDBR32 and ENDBR64 run on them as hint NOPs. AMD's references for Zen 3, Zen 4 and Zen 5 (55898, 55901, 57238) set CPUID_Fn00000007_ECX_x00[CET_SS] (bit 7) and leave bit 20 of CPUID_Fn00000007_EDX_x00, which Intel gives to indirect branch tracking, reserved and clear. Note: Zen 6 is listed because Zen 5 has these instructions. GCC's -march sets, which give the other features of Zen 6, leave them out, and AMD has not yet published a Processor Programming Reference for Zen 6. |
More CET instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2A, page 3-288 (ENDBR64)
- Linux kernel documentation: Control-flow Enforcement Technology (CET) Shadow Stack
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
- AMD64 Architecture Programmer's Manual, Volume 2: System Programming (24593, rev. 3.42, March 2024), Wayback Machine copy of AMD's PDF
- AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.36, March 2024), Wayback Machine copy of AMD's PDF
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The text is our own.