rbpf虚拟机-opcode码

简介: 该篇文章是rbpf虚拟机opcode码作用和使用的整理。(学习该虚拟机的目的是为了搞懂solana合约的执行方式,solana使用的rbpf是在该虚拟机上进行扩展。)

@[toc]

Welcome to Code Block's blog

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

一、概述

该篇文章是rbpf虚拟机opcode码作用和使用的整理。

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

经过验证器后在rbpf虚拟机需要知道每条指令是用来做什么的,就需要用到opcode码,opcode码中由8种操作码、5种访问模式、4种数据大小进行组合获得,其结构如下图:

  7   6   5   4   |  3   2   |  1   0  
+---------------+--------+--------+
|     操作码    |  访问模式  |  大小   |
+---------------+--------+--------+

二、eBPF 的指令格式

完整的 eBPF 指令通常是 8 字节(64 位),其中 opcode 仅占 低 8 位,其余部分包含寄存器编号、立即数等。

  31      24 23     16 15      8 7       0
+--------+--------+--------+--------+
|    dst  |    src  |  offset  |  opcode |
+--------+--------+--------+--------+
|           immediate / address          |
+----------------------------------------+

字段说明:
| 字段 | 位数 | 说明 |
|-------------|--------|---------|
| opcode | 8-bit | 操作码,包括 OP、MODE 和 SIZE |
| dst | 4-bit | 目标寄存器编号 |
| src | 4-bit | 源寄存器编号(用于二元运算) |
| offset | 16-bit | 偏移量(用于内存访问或跳转) |
| immediate | 32-bit | 立即数(用于算术或跳转指令) |


三、Opcode 具体字段解释

1. 操作码(OP,7~4位)4位

Opcode 值 名称 说明
0x00 BPF_LD 立即数/内存加载指令
0x40 BPF_LDX 从内存加载到寄存器
0x60 BPF_ST 存储指令(寄存器 → 内存)
0x61 BPF_STX 存储指令(寄存器 → 内存,带索引)
0x80 BPF_ALU 算术运算(立即数模式)
0xc0 BPF_ALU64 64 位算术运算
0xa0 BPF_JMP 跳转指令
0xe0 BPF_JMP32 32 位跳转指令

2. 访问模式(MODE,3~2位)2位

Mode 值 名称 说明
0x00 BPF_IMM 立即数模式(直接使用值)
0x10 BPF_ABS 绝对地址模式(用于 BPF_LD
0x20 BPF_IND 间接地址模式(用于 BPF_LD
0x60 BPF_MEM 内存模式(从内存读取/写入)
0x70 BPF_LEN 报文长度(仅在 BPF_LD 使用)

3. 数据大小(SIZE,1~0位) 2位

Size 值 名称 说明
0x00 BPF_W 4 字节(32 位)
0x08 BPF_H 2 字节(16 位)
0x10 BPF_B 1 字节(8 位)
0x18 BPF_DW 8 字节(64 位)

三、具体使用

opcode码有很多种,如果直接使用如:0x71表示从内存加载 1 字节到寄存器,在定义时如果使用:

LD_B_REG = 0x71

这读起来有点费力,不利于维护操作。为了解决这一问题,可以直接将上述的操作码、访问模式、数据大小进行预先定义,然后使用以下方式进行定义:

LD_B_REG = BPF_LDX | BPF_MEM | BPF_B

BPF_LDX表示从内存加载到寄存器,BPF_MEM表示内存模式,BPF_B表示1个字节。这时我们就可以清楚的知晓LD_B_REG为从内存加载 1 字节到寄存器。这样,哪怕不知道是什么值,也可以通过按位或计算得到
opcode(操作码).

LD_B_REG = BPF_LDX | BPF_MEM | BPF_B
         = 0x61 | 0x00 | 0x10
         = 0b0110 0001 | 0b0000 0000 | 0b0001 0000
         ------------------------------------------
         = 0b0111 0001   // 结果 = 0x71(十六进制)

四、总结

通过上述对opcode码结构进行解读,对opcode码有了更深刻的理解,同时这种结构组合按位或处理可以产生很多组合结果,该方法可以很好的运用到日常的其它语言项目中。

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

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

我的GitHub:forked


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

目录
相关文章
|
9月前
|
人工智能 数据挖掘 Linux
Centos安装Python3.7(亲测可用)
本指南详细介绍了在基于Linux(以CentOS系统为例,使用yum包管理器)的系统上安装Python 3.7版本的完整流程。Python是一种广泛使用的高级编程语言,在各种领域如软件开发、数据分析、人工智能和区块链开发等都有着重要的应用。
739 2
|
5G 数据安全/隐私保护
5G终端标识SUPI,SUCI及IMSI解析
IMSI,SUPI,SUCI均为UE终端标识,区别在于IMSI为LTE终端标识,SUPI为5G非加密终端标识,一般等同于IMSI,SUCI为5G加密终端标识,需要解密后才能得到SUPI。
3693 0
5G终端标识SUPI,SUCI及IMSI解析
|
数据库
阿里云DTS数据迁移和数据同步的差异性分析
阿里云DTS作为一款常用的数据库表迁移工具,提供了功能非常类似的两个功能:数据迁移、数据同步。阿里云DTS产品官网对这两个功能模块进行了简单的区分: 场景1:存量数据批量迁移,建议使用数据迁移功能。 场景2:增量数据实时同步,建议使用数据同步功能。 实际上,无论是数据迁移还是数据同步,都可以做 “结构初始化”+“全量数据迁移”+“增量迁移”,因此两者功能差异并不明显。笔者在多个项目实践DTS数据迁移,在简单需求场景下,将DTS的数据迁移、数据同步进行对比和总结。
|
9月前
|
存储 Java API
小试牛刀-SpringBoot集成SOL链
java工程师:如何在java/springboot中使用solana区块链呢?不用担心,现在solanaj来了!
339 1
|
9月前
|
缓存 监控 Linux
Linux系统性能调优技巧和相关工具
Linux 作为一种应用应展和系统服务的优选操作系统,在处理性能和端到端点评估上持有出色表现。但是,在处理进程或系统处于低效状态时,性能调优就显得十分重要。本文将探讨一些 Linux 系统性能调优的常用技巧,并介绍相关工具
241 0
Linux系统性能调优技巧和相关工具
|
9月前
|
Python
小试牛刀-Python生成solana Wallet公私钥
在使用Python开发solana应用过程中,需要生成solana Wallet公私钥,以实现后续应用操作.这里将Python生成方法进行整理,方便日后的查阅,也能帮助到实现相关功能的朋友。
232 5
|
9月前
|
存储 JavaScript 区块链
小试牛刀-SOL链创建Token
最近需要编写SOL合约进行SPL Token的转移,因为在测试网上需要自己部署测试Token,同时为了更加美观,Token需携带metadata数据(对名称、头像等)进行定义.在此对创建过程进行记录,希望帮助到有需要实现相关功能的朋友.
176 1
|
9月前
|
Rust 安全 区块链
Rust-引用借用规则
Rust为确保程序在运行时不会出现数据竞争和其他内存安全,在使用引用时有很多规则,我在第一眼看到这些规则时也是有些头大,看了一段时间后才有了一些自己的一些理解。在这里对一些官方的术语和借用规则进行解释和记录。
157 1
|
9月前
|
安全 算法 区块链
openssl生成证书
本文章是记录openssl命令生成私钥、证书签名请求、CA证书的命令和相关参数的解释。其中包含了各参数的名称、作用、技术细节和安全建议。
220 1
|
9月前
|
人工智能 JavaScript 机器人
小试牛刀-Telebot区块链游戏机器人(TS升级)
​本篇文章是小试牛刀-Telebot区块链游戏机器人(python版本)的typescript版本开发记录,实现该版本的主要目的是为了集成walletconnect,以实现用户wallet的无存储公私钥的交互功能.
207 1