<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/an-ebpf-overview-part-2-machine-bytecode-kkxdulzw0" -->

---
title: An eBPF overview, part 2: Machine & bytecode | daily.dev
description: A deep dive into the eBPF virtual machine architecture, covering its 11 64-bit registers, 512-byte fixed stack, and fixed-size 64-bit instruction encoding....
canonical: https://daily.dev/posts/an-ebpf-overview-part-2-machine-bytecode-kkxdulzw0
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: An eBPF overview, part 2: Machine & bytecode | daily.dev
og:description: A deep dive into the eBPF virtual machine architecture, covering its 11 64-bit registers, 512-byte fixed stack, and fixed-size 64-bit instruction encoding....
og:url: https://daily.dev/posts/an-ebpf-overview-part-2-machine-bytecode-kkxdulzw0
og:image: https://api.daily.dev/og/posts/kKxDULZW0.png
og:image:alt: An eBPF overview, part 2: Machine & bytecode
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# An eBPF overview, part 2: Machine & bytecode

**[Collabora Blog](https://daily.dev/sources/collabora)** · 8 min read · 0 upvotes · 0 comments

## Summary

A deep dive into the eBPF virtual machine architecture, covering its 11 64-bit registers, 512-byte fixed stack, and fixed-size 64-bit instruction encoding. Explains register roles (r0 for return values, r1-r5 for function arguments, r6-r9 preserved across calls, r10 as read-only stack pointer), how kernel helper functions are defined and called, and the memory access model. Walks through a concrete bytecode example from sock_example.c that counts TCP/UDP/ICMP packets on the loopback interface, explaining each instruction including BPF_JMP_IMM, BPF_LD_ABS, BPF_STX_MEM, and atomic increments. Concludes that raw bytecode is impractical for complex tasks, setting up part 3 which covers higher-level language compilation to eBPF.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.collabora.com/news-and-blog/blog/2019/04/15/an-ebpf-overview-part-2-machine-and-bytecode>

## Questions this post answers

### How many registers does the eBPF VM have and what are they used for?

The eBPF VM has 11 64-bit registers. r0 stores return values and program exit codes; r1-r5 are function call arguments (r1 holds the context pointer at program start); r6-r9 are callee-saved across kernel function calls; r10 is a read-only pointer to the 512-byte per-program stack. All registers are always 64-bit wide, even on 32-bit ARM kernels.

_Engineers writing eBPF programs track register conventions and kernel ABI details like these on daily.dev._

### Why can eBPF registers r1-r5 only hold numbers or stack pointers, not arbitrary memory pointers?

Restricting r1-r5 to numbers or pointers to the eBPF stack (never direct pointers to arbitrary memory) simplifies the memory model for the eBPF verifier. All memory accesses must first load data onto the eBPF stack before use. This constraint makes correctness checking tractable, allowing the verifier to safely validate programs before they run in the kernel.

_Developers navigating eBPF verifier constraints find relevant kernel internals discussions on daily.dev._

### What does the eBPF bytecode 0x020015 do?

The bytecode 0x020015 encodes BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), a conditional jump that skips the next 2 instructions if register r0 equals zero. It is commonly used immediately after a kernel helper call to check whether the call succeeded, since r0 holds the return value and a zero typically indicates failure (e.g., a failed map_lookup_elem).

_Systems programmers debugging eBPF programs keep up with low-level kernel details on daily.dev._

## Similar posts on daily.dev

- [eBPF on Hard Mode](https://daily.dev/posts/ebpf-on-hard-mode-xc9nqtwhy) · Lobsters · 0 upvotes · 0 comments
- [eBPF the Hard Way](https://daily.dev/posts/ebpf-the-hard-way-ru1cateai) · Lobsters · 1 upvotes · 0 comments
- [The RISC architecture frontier: Is eBPF ready for ARM64 and RISC-V?](https://daily.dev/posts/the-risc-architecture-frontier-is-ebpf-ready-for-arm64-and-risc-v--vejmyrq34) · The New Stack · 0 upvotes · 0 comments
- [Cloudflare’s eBPF Replatforming Part 4: Observability, Operations, and Reliability Improvements from eBPF](https://daily.dev/posts/cloudflare-s-ebpf-replatforming-part-4-observability-operations-and-reliability-improvements-from-k5xeelty4) · eBPF · 3 upvotes · 1 comments
- [What Is eBPF? Use Cases, Benefits, and Key Differences](https://daily.dev/posts/what-is-ebpf-use-cases-benefits-and-key-differences-5dgqadloo) · Isovalent · 3 upvotes · 0 comments

---

Tags: [#linux](https://daily.dev/tags/linux), [#virtual-machine](https://daily.dev/tags/virtual-machine)

[View this post on daily.dev](https://daily.dev/posts/an-ebpf-overview-part-2-machine-bytecode-kkxdulzw0)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"An eBPF overview, part 2: Machine & bytecode","url":"https://daily.dev/posts/an-ebpf-overview-part-2-machine-bytecode-kkxdulzw0","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/an-ebpf-overview-part-2-machine-bytecode-kkxdulzw0"},"datePublished":"2026-08-11T08:57:20.722Z","dateModified":"2026-08-11T09:44:23.579Z","description":"A deep dive into the eBPF virtual machine architecture, covering its 11 64-bit registers, 512-byte fixed stack, and fixed-size 64-bit instruction encoding....","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8ceea2aa15dc113a23a22b700ed9e34c?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8ceea2aa15dc113a23a22b700ed9e34c?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Collabora Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Collabora Blog","logo":"https://media.daily.dev/image/upload/s--ZGZ0FjqS--/f_auto,q_auto/v1786438306/logos/collabora?_a=BAMAMicg0","url":"https://daily.dev/sources/collabora"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/an-ebpf-overview-part-2-machine-bytecode-kkxdulzw0","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"linux,virtual-machine","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Collabora Blog","item":"https://daily.dev/sources/collabora"},{"@type":"ListItem","position":3,"name":"An eBPF overview, part 2: Machine & bytecode"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/an-ebpf-overview-part-2-machine-bytecode-kkxdulzw0#faq","mainEntity":[{"@type":"Question","name":"How many registers does the eBPF VM have and what are they used for?","acceptedAnswer":{"@type":"Answer","text":"The eBPF VM has 11 64-bit registers. r0 stores return values and program exit codes; r1-r5 are function call arguments (r1 holds the context pointer at program start); r6-r9 are callee-saved across kernel function calls; r10 is a read-only pointer to the 512-byte per-program stack. All registers are always 64-bit wide, even on 32-bit ARM kernels. Engineers writing eBPF programs track register conventions and kernel ABI details like these on daily.dev."}},{"@type":"Question","name":"Why can eBPF registers r1-r5 only hold numbers or stack pointers, not arbitrary memory pointers?","acceptedAnswer":{"@type":"Answer","text":"Restricting r1-r5 to numbers or pointers to the eBPF stack (never direct pointers to arbitrary memory) simplifies the memory model for the eBPF verifier. All memory accesses must first load data onto the eBPF stack before use. This constraint makes correctness checking tractable, allowing the verifier to safely validate programs before they run in the kernel. Developers navigating eBPF verifier constraints find relevant kernel internals discussions on daily.dev."}},{"@type":"Question","name":"What does the eBPF bytecode 0x020015 do?","acceptedAnswer":{"@type":"Answer","text":"The bytecode 0x020015 encodes BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), a conditional jump that skips the next 2 instructions if register r0 equals zero. It is commonly used immediately after a kernel helper call to check whether the call succeeded, since r0 holds the return value and a zero typically indicates failure (e.g., a failed map_lookup_elem). Systems programmers debugging eBPF programs keep up with low-level kernel details on daily.dev."}}]}
```

