【WebAssembly】 WebAssembly 指令集详解

发布时间:2026/6/28 5:33:50

【WebAssembly】 WebAssembly 指令集详解 WebAssembly 采用栈式虚拟机模型指令集设计紧凑、类型安全共约200 条指令。本文按功能分类详细介绍。一、数值操作指令数值操作指令涵盖整数和浮点数的算术运算、比较运算、类型转换等。1.1 整数算术运算i32 / i64指令操作码说明示例i32.add/i64.add0x6A / 0x7C加法(i32.add (i32.const 1) (i32.const 2))→ 3i32.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 → f32f64.convert_i64_s/_u0xBA / 0xBBi64 → f64f32.demote_f640xB6f64 → f32f64.promote_f320xBBf32 → f64i32.reinterpret_f320xBCf32 位模式 → i32i64.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跳转表实现 switchreturn0x0F从函数返回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 位到 i64i64.load16_s/i64.load16_u0x32 / 0x33加载 16 位到 i64i64.load32_s/i64.load32_u0x34 / 0x35加载 32 位到 i64i32.store80x3A存储 8 位i32.store160x3B存储 16 位i64.store80x3C存储 8 位i64.store160x3D存储 16 位i64.store320x3E存储 32 位4.3 内存管理指令指令操作码说明memory.size0x3F获取当前内存页数1页 64KBmemory.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)))(exportcall_dispatch(func$call_dispatch)))5.4 JavaScript 使用const{instance}awaitWebAssembly.instantiate(wasmBytes);// 间接调用op0 加法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_indirectSIMD~150并行向量运算原子操作~30多线程同步总计~200核心 扩展设计哲学栈式模型简化解码器和 JIT 实现类型安全每条指令都验证操作数类型结构化控制流block/loop 保证可验证性显式内存管理无 GC直接操作线性内存可扩展性SIMD、多线程等作为扩展渐进增强

相关新闻