当前位置: 首页 > news >正文

【WebAssembly】 WebAssembly 指令集详解

WebAssembly 采用栈式虚拟机模型,指令集设计紧凑、类型安全,共约200 条指令。本文按功能分类详细介绍。

一、数值操作指令

数值操作指令涵盖整数和浮点数的算术运算、比较运算、类型转换等。

1.1 整数算术运算(i32 / i64)

指令操作码说明示例
i32.add/i64.add0x6A / 0x7C加法(i32.add (i32.const 1) (i32.const 2))→ 3
i32.sub/i64.sub0x6B / 0x7D减法
i32.mul/i64.mul0x6C / 0x7E乘法
i32.div_s/i32.div_u0x6D / 0x6E有符号/无符号除法
i32.rem_s/i32.rem_u0x6F / 0x70有符号/无符号取余

1.2 整数位运算

指令操作码说明
i32.and/i64.and0x71 / 0x83按位与
i32.or/i64.or0x72 / 0x84按位或
i32.xor/i64.xor0x73 / 0x85按位异或
i32.shl/i64.shl0x74 / 0x86左移
i32.shr_s/i32.shr_u0x75 / 0x76有符号/无符号右移
i32.clz/i64.clz0x67 / 0x79前导零计数
i32.ctz/i64.ctz0x68 / 0x7A尾随零计数
i32.popcnt/i64.popcnt0x69 / 0x7B1的个数

1.3 浮点算术运算(f32 / f64)

指令操作码说明
f32.add/f64.add0x92 / 0xA0加法
f32.sub/f64.sub0x93 / 0xA1减法
f32.mul/f64.mul0x94 / 0xA2乘法
f32.div/f64.div0x95 / 0xA3除法
f32.sqrt/f64.sqrt0x8B / 0x99平方根
f32.ceil/f64.ceil0x8C / 0x9A向上取整
f32.floor/f64.floor0x8D / 0x9B向下取整
f32.trunc/f64.trunc0x8E / 0x9C向零取整
f32.nearest/f64.nearest0x8F / 0x9D四舍五入
f32.abs/f64.abs0x88 / 0x96绝对值
f32.neg/f64.neg0x89 / 0x97取反
f32.copysign/f64.copysign0x90 / 0x9E符号复制
f32.min/f64.min0x91 / 0x9F最小值
f32.max/f64.max0x8A / 0x98最大值

1.4 比较运算

指令操作码说明
i32.eq/i64.eq0x46 / 0x51等于
i32.ne/i64.ne0x47 / 0x52不等于
i32.lt_s/i32.lt_u0x48 / 0x49有符号/无符号小于
i32.gt_s/i32.gt_u0x4A / 0x4B有符号/无符号大于
i32.le_s/i32.le_u0x4C / 0x4D有符号/无符号小于等于
i32.ge_s/i32.ge_u0x4E / 0x4F有符号/无符号大于等于
f32.eq/f64.eq0x5B / 0x61浮点等于
f32.lt/f64.lt0x5C / 0x62浮点小于
f32.gt/f64.gt0x5D / 0x63浮点大于
f32.le/f64.le0x5E / 0x64浮点小于等于
f32.ge/f64.ge0x5F / 0x65浮点大于等于

1.5 类型转换

指令操作码说明
i32.wrap_i640xA7i64 → i32(截断)
i64.extend_i32_s/_u0xAC / 0xADi32 → i64(符号/零扩展)
i32.trunc_f32_s/_u0xA8 / 0xA9f32 → i32(截断)
i64.trunc_f64_s/_u0xAE / 0xAFf64 → i64(截断)
f32.convert_i32_s/_u0xB2 / 0xB3i32 → f32
f64.convert_i64_s/_u0xBA / 0xBBi64 → f64
f32.demote_f640xB6f64 → f32
f64.promote_f320xBBf32 → f64
i32.reinterpret_f320xBCf32 位模式 → i32
i64.reinterpret_f640xBDf64 位模式 → i64

二、变量操作指令

变量包括局部变量(local)全局变量(global)

2.1 局部变量指令

指令操作码说明WAT 示例
local.get0x20获取局部变量的值(local.get $x)
local.set0x21设置局部变量的值(local.set $x (i32.const 10))
local.tee0x22设置并返回值(类似 set + get)(local.tee $x (i32.const 10))

WAT 示例:

(func$sum(param$a i32)(param$b i32)(resulti32)(local$temp i32)(local.set $temp(i32.add(local.get $a)(local.get $b)))(local.get $temp))

2.2 全局变量指令

指令操作码说明WAT 示例
global.get0x23获取全局变量的值(global.get $counter)
global.set0x24设置全局变量的值(global.set $counter (i32.const 1))

WAT 示例:

(module(global$counter(muti32)(i32.const0))(func$increment(global.set $counter(i32.add(global.get $counter)(i32.const1)))))

三、控制操作指令

控制流指令实现分支、循环、跳转和函数调用。

3.1 基本控制流

指令操作码说明
nop0x01无操作
unreachable0x00触发陷阱(程序崩溃)
block0x02代码块(不循环)
loop0x03循环块(可跳回开头)
if0x04条件分支
end0x0B块结束标记

3.2 跳转指令

指令操作码说明
br0x0C无条件跳转到标签
br_if0x0D条件跳转
br_table0x0E跳转表(实现 switch)
return0x0F从函数返回

WAT 示例:if-else

(if(resulti32)(local.get $condition)(then(i32.const1))(else(i32.const0)))

WAT 示例:loop 循环

;; 计算 1 到 10 的和(func$sum_to_10(resulti32)(local$i i32)(local$sum i32)(local.set $i(i32.const0))(local.set $sum(i32.const0))(loop$continue(local.set $i(i32.add(local.get $i)(i32.const1)))(local.set $sum(i32.add(local.get $sum)(local.get $i)))(br_if$continue(i32.lt_s(local.get $i)(i32.const10))))(local.get $sum))

WAT 示例:br_table 实现 switch

(func$switch(param$n i32)(resulti32)(block$default(block$case2(block$case1(block$case0(br_table$case0 $case1 $case2 $default(local.get $n)))(return(i32.const100));; case 0)(return(i32.const101));; case 1)(return(i32.const102));; case 2)(i32.const-1);; default)

3.3 函数调用

指令操作码说明
call0x10直接调用函数(通过函数索引)
call_indirect0x11间接调用(通过函数表)

WAT 示例:

(module(func$add(parami32 i32)(resulti32)(i32.add(local.get0)(local.get1)))(func$main(resulti32)(call$add(i32.const10)(i32.const20));; 直接调用))

四、内存操作指令

WASM 通过线性内存(Linear Memory)访问数据,支持 load/store 操作。

4.1 基本内存访问

指令操作码说明
i32.load0x28从内存加载 32 位整数
i64.load0x29加载 64 位整数
f32.load0x2A加载 32 位浮点
f64.load0x2B加载 64 位浮点
i32.store0x36存储 32 位整数
i64.store0x37存储 64 位整数
f32.store0x38存储 32 位浮点
f64.store0x39存储 64 位浮点

4.2 扩展内存访问

指令操作码说明
i32.load8_s/i32.load8_u0x2C / 0x2D加载 8 位(符号/零扩展)
i32.load16_s/i32.load16_u0x2E / 0x2F加载 16 位
i64.load8_s/i64.load8_u0x30 / 0x31加载 8 位到 i64
i64.load16_s/i64.load16_u0x32 / 0x33加载 16 位到 i64
i64.load32_s/i64.load32_u0x34 / 0x35加载 32 位到 i64
i32.store80x3A存储 8 位
i32.store160x3B存储 16 位
i64.store80x3C存储 8 位
i64.store160x3D存储 16 位
i64.store320x3E存储 32 位

4.3 内存管理指令

指令操作码说明
memory.size0x3F获取当前内存页数(1页 = 64KB)
memory.grow0x40增加内存页数,返回旧页数

4.4 批量内存操作(MVP 后扩展)

指令操作码说明
memory.fill0xFC 0x0B填充内存区域
memory.copy0xFC 0x0A复制内存区域
memory.init0xFC 0x08初始化内存(从数据段)
data.drop0xFC 0x09丢弃数据段

WAT 示例:

(module(memory1)(data(i32.const0)"Hello, World!")(func$print_string(local$i i32)(local.set $i(i32.const0))(loop$loop(i32.load8_u(local.get $i));; 读取字符(br_if$loop(i32.ne(i32.const0));; 非空继续))))

五、表格操作指令

表格(Table)存储函数引用,实现间接调用和动态分发。

5.1 表格类型

类型说明
funcref函数引用(可调用)
externref外部引用(JS 对象等)

5.2 表格指令

指令操作码说明
table.get0x23(扩展)获取表格中的元素
table.set0x24(扩展)设置表格中的元素
table.size0xFC 0x10获取表格大小
table.grow0xFC 0x0F增长表格
table.fill0xFC 0x11填充表格区域
table.copy0xFC 0x0E复制表格区域
table.init0xFC 0x0C初始化表格(从元素段)
elem.drop0xFC 0x0D丢弃元素段

5.3 完整示例:间接调用

(module;; 定义表格:存储 10 个函数引用(table$dispatch10funcref);; 定义三个函数(func$add(parami32 i32)(resulti32)(i32.add(local.get0)(local.get1)))(func$sub(parami32 i32)(resulti32)(i32.sub(local.get0)(local.get1)))(func$mul(parami32 i32)(resulti32)(i32.mul(local.get0)(local.get1)));; 初始化表格(elem(i32.const0)$add $sub $mul);; 间接调用函数(func$call_dispatch(param$op i32)(param$x i32)(param$y i32)(resulti32)(call_indirect(type$func_type)(local.get $x)(local.get $y)(local.get $op)))(type$func_type(func(parami32 i32)(resulti32)))(export"call_dispatch"(func$call_dispatch)))

5.4 JavaScript 使用

const{instance}=awaitWebAssembly.instantiate(wasmBytes);// 间接调用:op=0 加法,1 减法,2 乘法console.log(instance.exports.call_dispatch(0,10,20));// 30console.log(instance.exports.call_dispatch(1,20,10));// 10console.log(instance.exports.call_dispatch(2,10,20));// 200

六、SIMD 指令(扩展)

SIMD(单指令多数据流)通过v128类型实现并行计算,操作码前缀为0xFD

6.1 加载/存储

指令说明
v128.load加载 128 位数据
v128.store存储 128 位数据
v128.load8x8_s/_u加载 8 个 8 位值并扩展

6.2 整数 SIMD

指令说明
i8x16.add16 个 8 位整数并行相加
i16x8.mul8 个 16 位整数并行相乘
i32x4.dot_i16x8点积运算

6.3 浮点 SIMD

指令说明
f32x4.mul4 个 32 位浮点并行相乘
f64x2.add2 个 64 位浮点并行相加

WAT 示例:向量加法

(func$vector_add(param$a v128)(param$b v128)(resultv128)(f32x4.add(local.get $a)(local.get $b)))

七、原子操作指令(多线程扩展)

原子操作实现共享内存的线程安全访问,前缀为0xFE

指令说明
i32.atomic.load原子加载
i32.atomic.store原子存储
i32.atomic.rmw.add原子读-改-写(加法)
i32.atomic.rmw.xchg原子交换
i32.atomic.rmw.cmpxchg原子比较并交换
memory.atomic.wait32等待内存位置变化
memory.atomic.notify唤醒等待线程

八、指令集总结

分类统计

类别指令数说明
数值操作~80整数/浮点运算、转换、比较
变量操作6local.get/set/tee, global.get/set
控制操作~15block, loop, if, br, call
内存操作~30load, store, memory.grow
表格操作~10table.get/set, call_indirect
SIMD~150并行向量运算
原子操作~30多线程同步
总计~200核心 + 扩展

设计哲学

  1. 栈式模型:简化解码器和 JIT 实现
  2. 类型安全:每条指令都验证操作数类型
  3. 结构化控制流:block/loop 保证可验证性
  4. 显式内存管理:无 GC,直接操作线性内存
  5. 可扩展性:SIMD、多线程等作为扩展渐进增强
http://www.jsqmd.com/news/526055/

相关文章:

  • MongoDB数据迁移全攻略:从导出到导入的完整流程解析
  • 文件加密工具横向评测:OEMexe与主流方案的全面对比分析
  • 零基础5分钟部署Kotaemon:小白也能搭建智能客服机器人
  • EVA-01‘暴走白昼’UI体验:亮色机甲风界面,长时间使用不累眼
  • 【最新版】OpenClaw云上/MacOS/Linux/Windows本地5分钟部署及使用超简单步骤
  • Continue AI编程助手自定义API实战:SiliconFlow与DeepSeek的完美搭配
  • 从算盘到CPU:补码加减法器的迭代电路,是如何成为现代计算基石的?
  • 别再踩坑了!Windows 10 + RTX 1080Ti 保姆级 Mamba-SSM 2.2.2 环境搭建实录
  • PMSM与BLDCM傻傻分不清?一文搞懂永磁电机的控制方式差异
  • WPF与Python强强联合:教你如何用C#调用Python脚本实现高效上位机开发
  • Phi-3-Mini-128K前端应用:Vue3项目集成AI对话组件全指南
  • 从基模到Ince高斯光束:MATLAB仿真中的模式演化与参数调控
  • Qwen3-VL-2B部署避坑指南:CPU优化版快速搭建与问题解决
  • 告别旧Input!Unity跨平台游戏开发必备:Input System实战指南(2024最新版)
  • 手把手教你用Simulink搭建永磁同步电机SPWM控制系统(含死区补偿技巧)
  • 实战指南:从零构建高效多智能体金融分析系统
  • 别再手动调API了!用Langchain+PGVector+OpenAI快速搭建你的本地知识库(保姆级避坑指南)
  • ThinkPHP8.0安装避坑指南:从Composer配置到Apache环境搭建(附常见错误解决方案)
  • CentOS 7内核升级实战:从ELRepo安装到GRUB2配置全流程
  • python+flask+vue3的电影订票购票系统的设计与实现
  • 《QGIS快速入门与应用基础》235:比例尺样式选择(数字/线段/复合)
  • Wan2.1 VAE生成中国风水墨画与书法作品艺术展
  • 从ICU监护数据到基因组序列:Python差分隐私处理全场景覆盖(含时序数据自适应ΔS计算、高维稀疏特征扰动等6类独家技巧)
  • 仅限首批认证机构解密:MCP 2.0 v2.0.3新增“动态信任锚”机制配置要点(含CA策略迁移checklist)
  • 通义千问1.5-1.8B-Chat-GPTQ-Int4在AIGC内容创作中的应用:辅助撰写技术博客与文档
  • 高级定时器死区时间优化指南:STM32中TIM_ClockDivision的隐藏作用
  • OpenClaw问卷分析:Qwen3-VL:30B处理Excel与图片反馈生成报告
  • 深度解析AI智能体在金融交易中的创新应用:TradingAgents-CN实战指南
  • 3步快速上手KH Coder:让文本分析变得像用Word一样简单
  • 嵌入式开发必知:从校验和到CRC,5种数据校验算法在STM32上的C语言实现对比