上一篇文章介绍了WebAssembly(后文简称Wasm)二进制格式,这一篇文章将介绍Wasm指令集、操作数栈和部分指令。

Wasm指令集

和真实的机器码一样,Wasm二进制文件中的代码也由一条一条的指令构成。同样,Wasm指令也包含两部分信息:操作码(Opcode)和操作数 (Operands)。Wasm操作码固定为一个字节,因此最多能表示256条指令,这一点和Java字节码一样。Wasm1.0规范一共定义了172条指令,这些指令按功能可以分为5大类,分别是:

控制指令(Control Instructions),共13条。

参数指令(Parametric Instructions),共2条。

变量指令(Variable Instructions),共5条。

内存指令(Memory Instructions),共25条。

数值指令(Numeric Instructions),共127条。

可以看到,已经定义的指令中,有超过2/3属于数值指令。为了方便人类书写和理解,Wasm规范给也给每个操作码定义了助记符(Mnemonic),比如说操作码0x41的助记符是i32.const。下面是已定义指令的操作码分布示意图:

有一部分指令需要携带一些信息,这些信息编码后紧跟在指令操作数的后面,叫做静态立即参数(Static Immediate Arguments,后文简称立即数)。 以i32.const指令为例,操作码0x41后面要跟一个编码后的32位整数。在后面的例子中,我们将用类似下面这样的示意图来表示编码后的指令:

bytecode:

...][ i32.const ][ 123 ][...

复制代码

和JVM等栈式虚拟机一样,大部分Wasm指令也会用到操作数栈(Operand Stack,后文简称栈)。这些指令从栈顶弹出一个或多个数,进行计算,然后把结果推入栈顶。被指令操作的这些栈顶元素叫做指令的动态操作数(Dynamic Operands,后文简称操作数)。在后面的例子中,我们将用类似下面这样的示意图来表示指令执行前后栈的状态(小箭头表示弹出或推入操作):

stack:

| | | |

| e |➚ | |

| d |➚ ➘| d+e |

| c | | c |

| b | | b |

| a | | a |

└───────────┘ └───────────┘

before after

复制代码

参数指令和数值指令仅仅对栈进行操作,行为比较简单,由本文进行介绍。其他指令将在后续文章中介绍。

参数指令

参数指令有两条:drop(操作码是0x1A)和select(操作码是0x1B)。

drop

drop指令,从栈顶弹出一个任意类型的操作数。drop指令没有立即数,下面是它的示意图:

bytecode:

...][ drop ][...

stack:

| | | |

| | | |

| d |➚ | |

| c | | c |

| b | | b |

| a | | a |

└───────────┘ └───────────┘

复制代码

select

select指令先后从栈顶弹出3个操作数,如果最先弹出的操作数等于0则将第二个弹出的操作数推入栈,否则将第三个弹出的操作数推入栈。select指令也没有立即数,下面是它的示意图:

bytecode:

...][ select ][...

stack:

| | | |

| e(i32) |➚ | |

| d |➚ | |

| c |➚ ➘| e!=0?c:d |

| b | | b |

| a | | a |

└───────────┘ └───────────┘

复制代码

注意位于栈顶的操作数必须是i32类型,其余两个操作数必须有相同类型。当需要强调操作数的具体类型时,我们会在示意图中用圆括号标出类型。drop和select是比较特殊的两条指令,因为只有这两条指令没有将操作数的类型完全限定。对于其他的指令,所有操作数的类型都是完全限定的。

数值指令

数值指令可以按操作数类型分成i32、i64、f32、f64四组,每一组指令又可以按照操作进一步分为:

常量指令(Constant Instructions)

测试指令(Test Instructions)

比较指令(Comparison Instructions)

算术指令(Arithmetic Instructions)

一元(Unary)算术指令

二元(Binary)算术指令

转换指令(Conversion Instructions)

除常量指令外,其余数值指令都没有立即数。

常量指令

常量指令将立即数推入栈顶,以i32.const指令(操作码0x41)为例,下面是它的示意图:

bytecode:

...][ i32.const ][ 123 ][...

stack:

| | | |

| | ➘| 123(i32) |

| d | | d |

| c | | c |

| b | | b |

| a | | a |

└───────────┘ └───────────┘

复制代码

常量指令一共有四条,另外三条是: i64.const(操作码0x42)、 f32.const(操作码0x43)、 f64.const(操作码0x44)。不难发现,Wasm操作码助记符的命名规则是:如果指令执行后栈顶元素的类型是t,那么助记符就以t.开头。

测试指令

测试指令从栈顶弹出一个操作数,测试它是否是0,如果是则将i32类型1推入栈,否则将i32类型0推入栈。测试指令只有两条:i32.eqz(操作码0x45)和 i64.eqz(操作码0x50)。以i64.eqz指令为例,下面是它的示意图:

bytecode:

...][ i64.eqz ][...

stack:

| | | |

| | | |

| d(i64) |➚ ➘| d==0(i32) |

| c | | c |

| b | | b |

| a | | a |

└───────────┘ └───────────┘

复制代码

可以看到,测试指令的结果其实是布尔值,只不过Wasm没有定义bool类型,而是用i32类型来表示(1表示ture,0表示false)。

比较指令

比较指令从栈顶弹出两个相同类型的操作数,进行比较,然后将结果压栈。和测试指令一样,比较指令的结果也是布尔值(也就是i32 类型)。以i64.lt_s指令(操作码0x53)为例,下面是它的示意图:

bytecode:

...][ i64.lt_s ][...

stack:

| | | |

| e(i64) |➚ | |

| d(i64) |➚ ➘| d

| c | | c |

| b | | b |

| a | | a |

└───────────┘ └───────────┘

复制代码

除了等于(eq),还有进行不等于(ne)、小于(le)、大于(gt)、小于等于(le)、大于等于(ge)比较的指令,这里就不一一介绍了。需要说明的是,对于有些整数类型的指令,需要明确指出如何解释操作数:将其当成有符号数(Signed,助记符带_s后缀)还是无符号数(Unsigned,助记符带_u后缀)。这类指令一般是成对儿出现,比如上面例子中的i64.lt_s指令,与之对应的还有i64.lt_u指令(操作码0x54)。

一元算术运算

一元算术指令从栈顶弹出一个操作数,进行计算,然后把结果推入栈顶。以f32.neg(操作码0x8C)指令为例,下面是它的示意图:

bytecode:

...][ f32.neg ][...

stack:

| | | |

| | | |

| d(f32) |➚ ➘| -d(f32) |

| c | | c |

| b | | b |

| a | | a |

└───────────┘ └───────────┘

复制代码

二元算术运算

二元算术指令从栈顶弹出两个操作数,进行计算,然后将结果推入栈顶。以f32.sub指令(操作码0x93)为例,下面是它的示意图:

bytecode:

...][ f32.sub ][...

stack:

| | | |

| e(i64) |➚ | |

| d(i64) |➚ ➘| d-e(i64) |

| c | | c |

| b | | b |

| a | | a |

└───────────┘ └───────────┘

复制代码

类型转换

类型转换指令从栈顶弹出一个操作数,进行类型转换,然后把结果推入栈顶。如果操作数在类型转换之前的类型是t,之后的类型是t',转换操作是conv,则指令的助记符是t'.conv_t。以i32.wrap_i64(操作码0xA7)指令为例,下面是它的示意图:

bytecode:

...][ i32.wrap_i64 ][...

stack:

| | | |

| | | |

| d(i64) |➚ ➘| d'(i32) |

| c | | c |

| b | | b |

| a | | a |

└───────────┘ └───────────┘复制代码

比较、算 术、转换指令数量比较多,本文无法一一介绍,请读者参考Wasm规范。

java wasm_Wasm介绍之2:指令集和栈相关推荐

  1. java虚拟机基于栈,深入理解java虚拟机(11):基于栈的字节码解释执行引擎

    1.解释执行 编译过程如下 2.基于栈的指令集和基于寄存器的指令集 java编译器输出的指令流,基本是一种基于栈的指令集架构,指令流中的大部分指令都是零地址,依赖于操作数工作.与之相对的是基于寄存器的 ...

  2. 【JVM】运行时数据区介绍,程序计数器和虚拟机栈详解

    JVM越来越是Java面试中的重头戏,今天来总结一下JVM运行时数据区的相关内容. 文章目录 JVM运行时数据区 JVM运行时数据区内部结构 程序计数器(PC寄存器) 程序计数器的介绍 PC寄存器的实 ...

  3. Java编程语言-介绍

    Java编程语言-介绍 Java是一种编程语言,被特意设计用于互联网的分布式环境.Java具有类似于C++语言的"形式和感觉",但它要比C++语言更易于使用,而且在编程时彻底采用了 ...

  4. java 怎么向串口发送指令_idea ssm项目java程序使用十六进制rxtx包向串口发送指令的方法...

    1.前提 idea ssm项目环境要配好,这里就不多赘述了,自己配好 2.下载配置rxtx包 官网下载:http://rxtx.qbang.org/wiki/index.php/Download 根据 ...

  5. Java命令学习系列(零)——常见命令及Java Dump介绍

    Java命令学习系列(零)--常见命令及Java Dump介绍 一.常用命令: 在JDK的bin目彔下,包含了java命令及其他实用工具.  jps:查看本机的Java中进程信息.  jstack ...

  6. JVM笔记:Java虚拟机的字节码指令详解

    1.字节码 Java能发展到现在,其"一次编译,多处运行"的功能功不可没,这里最主要的功劳就是JVM和字节码了,在不同平台和操作系统上根据JVM规范的定制JVM可以运行相同字节码( ...

  7. SGX-用于独立执行的创新指令集和软件模型(翻译)

    用于独立执行的创新指令集和软件模型 本文译自"Innovative Instructions and Software Model for Isolated Execution", ...

  8. MIPS指令集和汇编

    MIPS指令集和汇编 一.寄存器与内存 1.1 字节与字 ​ 关于对字(word)的理解,我又有了新的认识,word是一种操作单位,而且是最常见的操作单位(不是最小的),内存的地址是用一个字(32位二 ...

  9. dalvik指令集和smali文件

    dalvik指令集和smali文件 参开地址:https://blog.csdn.net/dd864140130/article/details/52076515 https://blog.csdn. ...

最新文章

  1. httpd默认配置文件详解
  2. Mac笔记本中是用Idea开发工具在Java项目中调用python脚本遇到的环境变量问题解决...
  3. 今天来说一下我的SAMC
  4. python类修饰器_《Python有什么好学的》之修饰器
  5. mastercam2017安装教程
  6. Oracle Spatial-元数据及SDO_GEOMETRY
  7. Oracle与mongodb的区别
  8. JVM内存结构|程序计数器
  9. Bash Shell学习笔记五
  10. yum安装Docker失败No package docker available
  11. 大数据之-Hadoop之HDFS_hadoop集群中的安全模式_操作案例---大数据之hadoop工作笔记0075
  12. 数据结构作业——ギリギリ eye(贪心+优先队列/贪心+并查集)
  13. 美国数据科学家:重视非结构化数据分析 走出两大“经典”误区
  14. 计算机系统结构与组成原理
  15. 分享不可不知的CAD经典技巧
  16. jsp写的简单购书网站
  17. MATLAB安装错误:Check your internet connection and proxy settings in MATLAB Web preferences
  18. 【速记】英语多个形容词(定语)搭配规则
  19. 计算几何摸黑(2)-点和直线
  20. 派森python_派森(Python)

热门文章

  1. UG NX 8.5-12.0安装说明
  2. Linux 学习笔记 (6) —— source命令
  3. C++文件流fstream详细说明
  4. 践行物联网低代码平台多场景应用,从这里开始!
  5. python怎么实现直播_做直播能有多赚钱,Python告诉你
  6. TWaver可视化软件(三)数据中心可视化 下
  7. 低价就是好吗?抖音电商低价现象何去何从
  8. 训练仿真系统软件开发公司有哪些呢
  9. CAD转换器中怎么将图纸的版本进行转换
  10. 关于 Excel 制作报表