# [译]Solidity中的内联汇编Inline Assembly介绍

By [DeFi Simon](https://paragraph.com/@defi-simon) · 2022-09-29

---

> 原文: [Solidity Tutorial : all about Assembly](https://jeancvllr.medium.com/solidity-tutorial-all-about-assembly-5acdfefde05c)

什么是汇编？
======

任何以高级语言（例如C，Go或Java）编写的程序，在执行之前都将先编译为“汇编语言”。

汇编（又称汇编语言）是指可使用[汇编器](https://techterms.com/definition/assembler)转换为机器代码的低级编程语言。汇编语言与物理机或虚拟机绑定，因为它们实现了指令集。一条指令告诉CPU执行一些基本任务，例如将两个数字相加。

为什么Solidity中需要汇编？
=================

### 1\. 细粒度控制

你可以使用操作码直接与EVM进行交互。 这使的可以对程序（=智能合约）要执行的操作进行更精细控制。

汇编提供了更多控制权来执行某些仅靠Solidity不可能实现的逻辑。 例如，指向特定的内存插槽。

当编写库时，细粒度控制特别有用，因为这些将被开发人员重用。

### 2\. 更少的Gas消耗

让我们通过创建简单的函数来比较Solidity和Assembly之间的Gas成本：1）简单地将两个数字（x + y）相加，然后2）返回结果。

    function addAssembly(uint x, uint y) public pure returns (uint) {
         assembly {
             // Add some code here
             let result := add(x, y)
             mstore(0x0, result)
             return(0x0, 32)
         }
     }
     
     function addSolidity(uint x, uint y) public pure returns (uint) {
         return x + y;
     }
    

![](https://storage.googleapis.com/papyrus_images/7796e827581d6f8559022938d6b654593834335ed58f46216e30d16c8fc8c24c.png)

从上面的示例中可以看到，使用内联汇编可以节省86的gas。 对于此示例来说，这并不是很多，但这粗略地了解了我们可以为更复杂的合约节省多少gas。

### 3\. 增强功能

有一些事情在EVM汇编中可以做，而没法在Solidity中实现。[例子](https://ethereum.stackexchange.com/questions/3157/what-are-some-examples-of-how-inline-assembly-benefits-smart-contract-developmen)

Solidity中的两种类型的汇编
=================

1.  **内联汇编（Inline Assembly）**：可以再内部Solidity源代码中使用；
    
2.  **独立汇编（Standalone Assembly）**：可以直接使用，无需Solidity.
    

基本汇编语法
======

可以在Solidity中使用`assembly{}` 来嵌入汇编代码，这就是内联汇编：

    contract Assembler { 
     function do_something_cpu() public {
       assembly {
         // start writing evm assembler language
       }
     }
    }
    

> 在`assembly` 块内的代码开发语言被称为Yul。
> 
> 汇编代码块之间不能通信，也就是说在 一个汇编代码块里定义的变量，在另一个汇编代码块中不可以访问。

简单汇编示例
------

下面的代码使用内联汇编代码计算函数的两个参数的和并返回结果：

    function addition(uint x, uint y) public pure returns (uint) { 
     assembly { 
         // 创建一个新的变量result
         //     -> 使用add操作码计算x+y
         //     -> 将计算结果赋值给变量result 
         let result := add(x, y)   // x + y 
          
         // 使用mstore操作码
         //     -> 将result变量的值存入内存
         //     -> 指定内存地址 0x0 
         mstore(0x0, result)       // 将结果存入内存
          
         // 从内存地址0x返回32字节
         return(0x0, 32) 
     }
    }
    

更多技术细节请参阅原文。

编写汇编的缺点
=======

Solidity文档指出以下内容：

> 内联汇编是一种以较低级别访问以太坊虚拟机的方法。 这绕过了几个重要的安全功能和Solidity的检查。 仅当您有信心及必需时才使用它。

### **汇编中都是uint**

EVM汇编中的算术运算忽略了某些类型可以小于256位的（例如：uint64）。

例如，一个地址长20个字节。 你还可以在Solidity中指定较小的类型，例如`bytes10`或`uint128`。

为了提高效率，EVM汇编将每个值都视为256位数字。高阶位仅在必要时才清除（例如：执行比较或写入内存之前）

这意味着，如果您从内联汇编中访问此类变量，则可能必须先手动清除高阶位。编写汇编代码会很快成为负担。

参考
==

[https://ethereum.stackexchange.com/questions/54733/compile-standalone-assembly](https://ethereum.stackexchange.com/questions/54733/compile-standalone-assembly)

[https://docs.soliditylang.org/en/v0.6.2/yul.html#evm-dialect](https://docs.soliditylang.org/en/v0.6.2/yul.html#evm-dialect)

[https://solidity-cn.readthedocs.io/zh/develop/assembly.html#inline-assembly](https://solidity-cn.readthedocs.io/zh/develop/assembly.html#inline-assembly)

* * *

我的推特：

[https://twitter.com/LuSicong](https://twitter.com/LuSicong)

---

*Originally published on [DeFi Simon](https://paragraph.com/@defi-simon/solidity-inline-assembly)*
