rbpf虚拟机-码

本文涉及的产品
可观测可视化 Grafana 版,10个用户账号 1个月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
简介: 该篇文章是rbpf不同码之间关系和作用的整理。(学习该虚拟机的目的是为了搞懂solana合约的执行方式,solana使用的rbpf是在该虚拟机上进行扩展。)

✨重磅!盹猫的个人小站正式上线啦~诚邀各位技术大佬前来探秘!✨
—— 专为开发者打造的宝藏基地,等你来探索!
这里有:


🔥 硬核技术干货:编程技巧、开发经验、踩坑指南,带你解锁技术新姿势!
🎉 趣味开发日常:代码背后的脑洞故事、工具测评,让技术圈不再枯燥~
💎 独家资源分享:开源项目、学习资料包,助你打怪升级快人一步!


🚀 立即访问 → 盹猫猫的个人小站 ← 点击探索
🌟 说不定这里就有你寻找已久的技术秘籍哦~

Welcome to Code Block's blog

本篇文章主要介绍了
[rbpf虚拟机-码]
❤博主广交技术好友,喜欢我的文章的可以关注一下❤

一、概述

该篇文章是rbpf不同码之间关系和作用的整理。

(学习该虚拟机的目的是为了搞懂solana合约的执行方式,solana使用的rbpf是在该虚拟机上进行扩展。)

二、码的定义

2.1 汇编码

汇编码​(Assembly Code)是 ​汇编语言 的代码形式,它是低级语言的一种,介于高级语言(如 C、C++)和机器码之间。汇编码使用助记符和符号来表示机器指令,比直接使用二进制的机器码更易于人类阅读和编写,但仍然与特定的硬件架构密切相关。

2.2 字节码

字节码​(Bytecode)是一种中间表示形式(Intermediate Representation, IR),它是介于高级语言(如 Java、Python)和机器码之间的一种指令集。字节码通常由虚拟机(如 JVM、Python 解释器)解释执行,或者通过 ​JIT 编译器 动态编译为目标机器的机器码。

2.3 机器码

机器码​(Machine Code)是 ​CPU 直接执行的二进制指令,它是计算机硬件能够理解和执行的最低级语言形式。机器码是编译器或汇编器将高级语言(如 C、C++)或汇编语言翻译为的最终形式,直接在 CPU 上运行。

f68cb6eb673f4393846b79134f0d6333.png

汇编码是语言,字节码是过渡,机器码是最终执行。

三、码样式

3.1 汇编码

常用的x86 是一种变长指令集架构,汇编码通常以助记符表示,指令长度从 1 字节到 15 字节不等
示例 1:将立即数 42 加载到寄存器 eax

mov eax, 42

​解释:

  • mov 是操作码,表示“移动”。
  • eax 是目标寄存器。
  • 42 是立即数。

3.2 字节码

​eBPF 字节码 是 eBPF 程序的中间表示形式,例如下述样式:

let prog = &[
     0xb7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
];

不同语言的字节码不同,如java虚拟机(JVM),使用自己独有字节码格式:

Compiled from "Example.java"
public class Example {
     
  public Example();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10                 // 将常量 10 压入栈
       2: istore_1                         // 存储到局部变量表索引 1(a)
       3: bipush        20                 // 将常量 20 压入栈
       5: istore_2                         // 存储到局部变量表索引 2(b)
       6: iload_1                          // 加载局部变量表索引 1(a)
       7: iload_2                          // 加载局部变量表索引 2(b)
       8: iadd                             // 整数加法
       9: istore_3                         // 存储结果到局部变量表索引 3(c)
      10: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      13: iload_3                          // 加载局部变量表索引 3(c)
      14: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      17: return
}

3.3 机器码

eBPF 机器码是特定于硬件架构的二进制指令,可以直接在 CPU 上运行。
不同架构的机器码完全不同。例如:

  • x86_64 架构的机器码:B8 2A 00 00 00
  • ARM 架构的机器码:E3 A0 00 2A

四、转换代码

4.1 汇编码-字节码(汇编器)

pub fn assemble(src: &str) -> Result<Vec<u8>, String> {
     
    let parsed = (parse(src))?;
    //Ok([Instruction { name: "mov", operands: [Register(0), Integer(0)] }, Instruction { name: "add", operands: [Register(1), Integer(2)] }])
    let insns = (assemble_internal(&parsed))?;

    let mut result: Vec<u8> = vec![];
    for insn in insns {
     
        result.extend_from_slice(&insn.to_array());
    }
    Ok(result)
}

汇编器就要是通过assemble方法,先对指令进行割形成列表,然后通过对不同的op码进行分类后形成对应的字节码数据。

4.2 字节码->汇编码(反汇编器)

pub fn disassemble(prog: &[u8]) {
     
    #[cfg(feature = "std")]
    {
     
        for insn in to_insn_vec(prog) {
     
            println!("{}", insn.desc);
        }
    }

反汇编则通过循环的方式切割字节码指令信息,同样通过op码进行分类转换为对应的字符串信息.

详情请查看文章:rbpf虚拟机-编译与反编译器

4.3 字节码->机器码(JIT即时编译)

  • 设置函数入口,保存寄存器状态,初始化内存指针。
  • 根据 use_mbuff 和 update_data_ptr 的值,处理内存缓冲区(mbuff)和- 数据指针。
  • 分配栈空间,用于存储局部变量和临时数据。
  • 逐条翻译 eBPF 指令为目标机器码,支持多种指令类型(加载、存储、算术运算、跳转等)。
  • -修正跳转指令的目标地址,确保控制流的正确性。
  • -Epilogue(函数出口)​

    五、总结

    通过上述对不同码之间的区分,对各种格式码之间的关系认识更加清晰,同时对不同码之间的转换有了一定了解。

代码来源:rbpf虚拟机
鸣谢: qmonnet 提供的开源代码.

当然,我也会将带有中文注释和自己理解的一些代码上传的我的github页面,感兴趣的朋友可以进行clone查看.

我的GitHub:forked


感谢您的点赞、关注、收藏!

目录
相关文章
|
Android开发 Kotlin JavaScript
Compose 为什么可以跨平台?
Compose 为什么可以跨平台?
773 0
Compose 为什么可以跨平台?
|
5月前
|
人工智能 供应链 数据挖掘
瓴羊入选中国信通院《AI Agent智能体产业图谱》
2025数据智能大会在京召开,中国信通院发布《AI Agent智能体产业图谱1.0》,瓴羊Quick BI凭借智能数据分析能力入选。该图谱系统梳理AI Agent产业生态,涵盖基础底座、平台、通用与行业智能体四大领域。Quick BI通过融合大模型技术,重构企业数据分析方式,实现从“被动响应”到“主动服务”的升级,广泛应用于供应链、零售、财务等多个场景。此次入选标志着瓴羊在数据分析智能体领域的创新成果获高度认可。作为阿里巴巴旗下数智服务品牌,瓴羊将持续推动企业智能化转型,释放数据价值,助力“人工智能+”深度发展。
|
网络协议 ice
STUN, TURN, ICE介绍
STUN STUN协议为终端提供一种方式能够获知自己经过NAT映射后的地址,从而替代位于应用层中的私网地址,达到NAT穿透的目的。STUN协议是典型的Client-Server协议,各种具体应用通过嵌入STUN客户端与STUN Server端通讯来完成交互。
14468 1
|
5月前
|
Java Spring
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 &gt; Java系统属性 &gt; application.properties &gt; application.yml &gt; application.yaml。
963 0
|
5月前
|
Linux 开发者 Windows
告别手动上传!开源FTP批量同步工具(免费跨平台)​​
自己开发的一个简单实用的 FTP 文件夹同步工具,支持定时自动同步和系统托盘运行,免去繁琐的配置。
135 1
|
5月前
|
Python
小试牛刀-Python生成solana Wallet公私钥
在使用Python开发solana应用过程中,需要生成solana Wallet公私钥,以实现后续应用操作.这里将Python生成方法进行整理,方便日后的查阅,也能帮助到实现相关功能的朋友。
145 6
|
5月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习模型、算法与应用的全方位解析
深度学习,作为人工智能(AI)的一个重要分支,已经在多个领域产生了革命性的影响。从图像识别到自然语言处理,从语音识别到自动驾驶,深度学习无处不在。本篇博客将深入探讨深度学习的模型、算法及其在各个领域的应用。
936 3
|
5月前
|
存储 NoSQL 区块链
开源:LMDB 操作工具:lmcmd
本文介绍了 LMDB(一种高效的键值存储数据库)和基于 Python 开发的命令行工具 `lmcmd`。由于 LMDB 使用二进制文件存储,管理和调试不便,因此开发了 `lmcmd`,提供了类似 Redis 的命令行操作界面,支持数据库操作、数据导入导出和查找等功能。文章涵盖了 `lmcmd` 的安装、连接数据库和常用命令(如 `set`、`get`、`export` 等)示例。最后强调了开源工具的价值,鼓励用户反馈和改进。
155 1
|
5月前
|
算法 区块链 数据安全/隐私保护
加密算法:深度解析Ed25519原理
在 Solana 开发过程中,我一直对 Ed25519 加密算法 如何生成公钥、签名以及验证签名的机制感到困惑。为了弄清这一点,我查阅了大量相关资料,终于对其流程有了更清晰的理解。在此记录实现过程,方便日后查阅。
519 1