6.4 集 (Assembly)

While many users will never have to touch assembly language while writing sway code, it is a powerful tool that enables many advanced use-cases (ie: optimizations, building libraries, etc).

虽然许多用户在编写 sway 代码时永远不必接触汇编语言,但它是一个支持许多高级用例(即:优化、构建库等)的强大工具。

ASM块 (ASM Block)

In Sway, the way we use assembly inline is to declare an asm block like this:

在 Sway 中,我们使用内联汇编的方式是像这样声明一个 asm 块:

asm() {...}

Declaring an asm block is similar to declaring a function. We can specify register names to operate on as arguments, we can perform operations within the block, and we can return a value. Here's an example showing what this might look like:

声明一个 asm 块类似于声明一个函数。我们可以指定要操作的注册器名称作为参数,我们可以在块内执行操作,我们可以返回一个值。这是一个示例,显示了其外观:

pub fn add_1(num: u32) -> u32 {
    asm(r1: num, r2) {
        add r2 r1 one;
        r2: u32
    }
}

An asm block can only return a single register. If you really need to return more than one value, you can modify a tuple. Here's an example showing how can implement this (u64, u64):

一个 asm 块只能返回一个注册器。如果你真的需要返回多个值,你可以修改一个元组。下面是一个示例,展示了如何实现这个(u64, u64)

script;

fn adder(a: u64, b: u64, c: u64) -> (u64, u64) {
    let empty_tuple = (0u64, 0u64);
    asm(output: empty_tuple, r1: a, r2: b, r3: c, r4, r5) {
        add  r4 r1 r2; // add a & b and put the result in r4
        add  r5 r2 r3; // add b & c and put the result in r5
        sw   output r4 i0; // store the word in r4 in output + 0 words
        sw   output r5 i1; // store the word in r5 in output + 1 word
        output: (u64, u64) // return both values
    }
}

fn main() -> bool {
    let (first, second) = adder(1, 2, 3);
    assert(first == 3);
    assert(second == 5);
    true
}

Note that this is contrived example meant to demonstrate the syntax; there's absolutely no need to use assembly to add integers!

请注意,这是人为设计的示例,旨在演示语法;绝对不需要使用汇编来添加整数!

Note that in the above example:

请注意,在上面的示例中:

  • we initialized the register r1 with the value of num. 我们用 num 的值初始化了注册器 r1

  • we declared a second register r2 (you may choose any register names you want). 我们声明了第二个注册器 r2(您可以选择任何您想要的注册器名称)

  • we use the add opcode to add one to the value of r1 and store it in r2. 我们使用 add 操作码将 one 添加到 r1 的值并将其存储在 r2

  • one is an example of a "reserved register", of which there are 16 in total. Further reading on this is linked below under "Semantics". one 是“保留注册器”的示例,总共有 16 个。关于此的进一步阅读链接在下面的“语义”下

  • we return r2 & specify the return type as being u32 (the return type is u64 by default). 我们返回 r2 并将返回类型指定为 u32(返回类型默认为 u64)。

An important note is that the ji and jnei opcodes are not available within an asm block. For those looking to introduce control flow to asm blocks, it is recommended to surround smaller chunks of asm with control flow (if, else, and while).

需要注意的是,jijnei 操作码在 asm 块中不可用。对于那些希望将控制流引入 asm 块的人,建议用控制流(ifelsewhile)包围较小的 asm 块。

For examples of assembly in action, check out the Sway standard library. 有关运行中的程序集示例,请查看 Sway 标准库

For a complete list of all instructions supported in the FuelVM: Instructions. 如需 FuelVM 支持的所有指令的完整列表:说明

And to learn more about the FuelVM semantics: Semantics. 并了解有关 FuelVM 语义的更多信息:语义

Last updated