Wasm介绍之5:控制指令

Posted 时间杠杆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Wasm介绍之5:控制指令相关的知识,希望对你有一定的参考价值。


WebAssembly(简称Wasm)控制指令一共有11条,其中unreachable指令(操作码0x00)和nop指令(操作码0x01)比较简单,不介绍。call指令(操作码0x10)已经在上一篇文章里介绍,call_indirect指令(操作码0x11)将在下一篇文章里介绍。本文重点讨论block(操作码0x02)、loop(操作码0x03)、if(操作码0x04)、br(操作码0x0C)、br_if(操作码0x0D)、br_table(操作码0x0E)和return(操作码0x0F)这7条指令。

block

block指令相当于一个无参的内联(inline)函数调用。函数的返回值类型,也就是block指令的结果类型(Result Type,在后面的示意图中简称rt)编码后存储在指令的第一个立即数参数里。函数的指令(可能有很多条)编码后存储在第二个立即数参数里。block指令必须以end指令(操作码0x0B)结尾。由于end指令和后面将要介绍的else指令(操作码0x05)只起到标记作用,没有任何执行效果,所以没有把这两条指令计入控制指令。

Wasm1.0规范规定block指令的结果不能超过一个,所以rt可以用一个字节表示:0x40表示没有结果、0x7F表示i32类型、0x7E表示i64类型、0x7D表示f32类型、0x7C表示f64类型。根据讨论可知,block指令在执行时不会使用栈上已经存在的任何操作数,执行完毕后可能会在栈顶留下一个操作数,下面是它的示意图:

  • ][...                                               (   ;; ...         100)   ) )block ][rt ]...[ br ]...[ end ][...                        |        ↑                        └────────┘loop ][rt ]...[ br ]...[ end ][...      ↑               |      └───────────────┘

    if

    block指令类似,if指令也类似于一个内联函数。区别主要有两点。第一,if内联函数带一个i32类型的参数。第二,if内联函数带有两份代码(两条分支),中间用else指令隔开。if指令执行时,会先从栈顶弹出这个i32类型的参数,如果参数值不等于0,则执行分支1代码,否则执行分支2代码。下面是if指令的示意图:

  • ][ rt ][ instrs1 ][ ][ instrs2 ][ ][...                                              ][ ][ instrs1 ][ ][...                                               (func $max (param $a i32) (param $b i32) (result i32)   (i32.gt_s (local.get $a) (local.get $b))   ((result i32)     ((local.get $a))     ((local.get $b))   ) ) (func (export    (i32.     (i32.       (i32.         (i32.       ) (i32.     ) (i32.   ) (i32. )                        (before br)        n==          n==          n==          n==   

    br_if

    br_if指令从栈顶弹出一个i32类型的操作数,如果操作数的值为0,则不跳转,否则执行br逻辑。下面是br_if指令的示意图:

  •                                                (func (i32) (i32) (result i32)   (local i32)   (loop      ;; +=      (local.set (i32.add (local.get      ;;      (local.set (i32.add (local.get      ;; <=       (br_if (i32.le_s (local.get    )   ;;    (local.get  )                                               ($        (block       (block         (local.get $n)                )       (local.get 1))     )     (local.get 2))   )   (local.get 3)) )int32) int32  n    : a   : b    


    *本文由CoinEx Chain开发团队成员Chase撰写。CoinEx Chain是全球首条基于Tendermint共识协议和Cosmos SDK开发的DEX专用公链,借助IBC来实现DEX公链、智能合约链、隐私链三条链合一的方式去解决可扩展性(Scalability)、去中心化(Decentralization)、安全性(security)区块链不可能三角的问题,能够高性能的支持数字资产的交易以及基于智能合约的Defi应用。

    Blazor_WASM之2:Razor语法

    Blazor_WASM之2:Razor语法

    Razor 是一种标记语法,用于将基于 .NET 的代码嵌入网页中。 Razor 语法由 Razor 标记、C# 和 HTML 组成。 Razor 可在 Razor 组件 文件 (.razor) 中找到。 Razor 语法类似于各种 JavaScript 单页应用程序 (SPA) 框架(如 Angular、React、VueJs 和 Svelte)的模板化引擎,本文针对Razor文件介绍Razor常用语法。

    Razor 语法参考

    Razor语法

    @*直接输出变量*@
    <p> @Name</p>
    @*如果就像输出@,则使用另个@*@
    <p> @@Name</p>
    @*如果是明显的邮箱格式则按邮箱格式输出*@
    <p>123@Name.com</p>
    @*虽然是邮箱格式,但是两个@会重新将Name作为属性*@
    <p>123@@Name.com</p>
    @*如果是邮箱格式,但是想输出Name属性可以用括号*@
    <p>123@(Name).com</p>
    
    @*razor代码块*@
    @*代码块内的 C# 代码不会呈现*@
    @code 
      
        public string Name  set; get;  = "Test";
    
        public class Student
         
            public string Name  set; get;  
            public string School set; get; 
        
    
        string GenericMethod<T>()
        
            return typeof(T).Name;
        
    
        public Student stu = new Student()  Name = "Jerry" ,School = "yucai";
    
        public int value  set; get;  = 3903;
    
    
    

    Razor隐式表达式

    @*隐式 Razor 表达式,可以直接使用.*@
    @*但是隐式表达式不能使用泛型*@
    <p>@stu.Name</p>
    

    Razor显示表达式

    @*显式表达式*@
    <p>@(stu.Name)显式</p>
    <p>@(stu.Name + stu.School)显式</p>
    @*可以调用私有方法*@
    <p>@(GenericMethod<int>())泛型</p>
    

    循环

    @*for循环*@
    @for (int i = 0; i < 3; i++)
    
        <p>第@(i)个</p> 
        <p>@Name</p>
    
    

    控制结构

    @if (value % 2 == 0)
    
        <p>The value was even.</p>
    
    @*else 和 else if 不需要 @ 符号:*@
    
    @if (value % 2 == 0)
    
        <p>The value was even.</p>
    
    else if (value >= 1337)
    
        <p>The value is large.</p>
    
    else
    
        <p>The value is odd and small.</p>
    
    
    
    @switch (value)
    
        case 1:
            <p>The value is 1!</p>
            break;
        case 1337:
            <p>Your number is 1337!</p>
            break;
        default:
            <p>Your number wasnt 1 or 1337.</p>
            break;
    
    

    using语句块

    @*自动释放变量*@
    @*@using (FileStream fs = new FileStream(".",FileMode.OpenOrCreate))
    
    
    

    异常捕获块

    @try
    
        throw new InvalidOperationException("You did something invalid.");
    
    catch (Exception ex)
    
        <p>The exception message: @ex.Message</p>
    
    finally
    
    
    

    特性

    每个Razor会编译成一个类,可以给该类增加一个特性

    @attribute [Authorize]

    实现接口

    @implements IDisposable

    继承类

    @inherits CustomRazorPage<TModel>

    定义为泛型

    @typeparam TEntity where TEntity : class

    路由

    指定 Razor 组件应直接处理请求

    @page "/test"

    引用命名空间

    @using Microsoft.AspNetCore.Authorization

    定义命名空间

    命名空间首字母必须大写

    @namespace Mynamespace

    依赖注入

    @inject Logger<Test> logger
    等价于 private readonly Logger<Test> logger;
      public Test(Logger<Test> log)
      
          logger = log
      
    

    以上是关于Wasm介绍之5:控制指令的主要内容,如果未能解决你的问题,请参考以下文章

    基础为零?如何将 C++ 编译成 WebAssembly

    Vue学习之路8-v-on指令学习简单事件绑定之属性

    Emscripten教程之优化你的代码

    Emscripten教程之emcc编译命令

    如何逆向分析WebAssembly二进制代码

    硬件介绍之NT35510(80系列并口使用)