1.6.7 Solidity汇编语言

Solidity定义了一套汇编语言,这套语言可以独立于Solidity单独使用。这套汇编语言可以嵌在Solidity的源代码内作为内联汇编语言使用。
在编写库时,为了更好的控制和提高语言的效率,可以用虚拟机很容易解析的内联汇编语言和Solidity一起使用。虽然以太坊虚拟机是基于堆栈的,但要正确地处理堆栈并给操作码输入合适的参数也不容易。Solidity的内联汇编语言就很好地处理了这些问题。它有下列这些特性:
- 类函数风格的操作码:mul(1, add(2, 3)) 而不是push1 3 push1 2 add push1 1 mul。
- 局部汇编变量:let x := add(2, 3) let y := mload(0x40) x := add(x, y)。
- 访问外部变量:function f(uint x) public { assembly { x := sub(x, 1) } }。
- 标签(label):let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0))。
- 循环:for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) }。
- if语句:if slt(x, 0) { x := sub(0, x) }。
- switch语句:switch x case 0 { y := mul(x, 2) } default { y := 0 }。
- 函数调用:function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } }。
注意:内联汇编语言是直接和以太坊虚拟机交互的低级语言,为了效率牺牲了部分安全性能。
实际上内联汇编语言也可以脱离Solidity单独作为Solidity编译器的汇编语言使用,而且这也是其原本的规划。这样做主要是希望达到下面三个目的:
- 用汇编语言写的程序要有可读性,甚至对由用Solidity编写而经过编译器产生的汇编码都是如此。
- 从汇编再转换为字节码(bytecode)的过程应该尽量平滑,变化尽量小。
- 汇编语言写的代码其控制流程应该容易检查和审阅,以便对代码进行验证和优化。
关于Solidity汇编语言的细节可参考https://solidity.readthedocs.io/en/v0.4.24/assembly.html#