以太坊虚拟机介绍3-算术运算指令

以太坊虚拟机算术运算指令
EVM总共定义了11条算术运算指令,见下表:

这些指令从栈顶弹出两到三个元素,进行相应计算,然后把结果推入栈顶。参与计算的元素和结果均被解释为按二的补码编码的整数。如果计算结果(假设为x)溢出(超出2^256),则最终的结果x’取值x % 2^256(%表示取模运算,^表示指数运算)。

下面是算术运算指令的操作码分布图:

ADD、MUL、SUB、DIV、SDIV、MOD、SMOD、EXP
这8条指令操作方式比较类似,从栈顶弹出两个元素,进行计算,然后把计算结果推入栈顶。由于采用二的补码表示整数时,加法、减法和乘法运算不用考虑符号位,所以加法、减法和乘法运算都只有一条指令。整除和取模运算需要考虑符号位,所以各有两条指令。指数运算只操作无符号整数。以ADD指令为例,下面是它的操作示意图:

ADDMOD和MULMOD
MULMOD指令依次从栈顶弹出x、y、z三个数,先计算x和y的乘积(不受溢出限制),再计算乘积和z的模,最后把结果推入栈顶。假定乘积不会溢出,那么MULMOD(x, y, z)等价于x * y % z,下面是MULMOD指令的操作示意图:

ADDMOD指令和MULMOD指令类似,只不过把乘法换成了加法。下面是ADDMOD指令的操作示意图:

SIGNEXTEND
SIGNEXTEND指令从栈顶依次弹出k和x,并把x解释为k+1(0 <= k <= 31)字节有符号整数,然后把x符号扩展至32字节。比如x是二进制10000000,k是0,则符号扩展之后,结果为二进制1111…10000000(共249个1)。下面是SIGNEXTEND指令的操作示意图:

实例分析
ADD、MUL、SUB、DIV、SDIV、MOD、SMOD、EXP指令与Solidity语言里的+、*、-、/、%、** 运算符直接对应。ADDMOD指令对应addmod()函数,MULMOD指令对应mulmod()函数。暂时还没有搞清楚SIGNEXTEND指令的用法,等以后再补充。下面的Solidity代码演示了EVM算术运算指令的具体应用:

// arith_demo.sol
pragma solidity ^0.4.24;

contract C {

function test() public view {
int s1; int s2; int s3;
uint u1; uint u2; uint u3;
uint k;

u3 = u1 + u2; // ADD
u3 = u1 * u2; // MUL
u3 = u1 - u2; // SUB
u3 = u1 / u2; // DIV
s3 = s1 / s2; // SDIV
u3 = u1 % u2; // MOD
s3 = s1 % s2; // SMOD
u3 = u1 ** u2; // EXP
u3 = addmod(u1, u2, k); // ADDMOD
u3 = mulmod(u1, u2, k); // MULMOD
}

}
读者可以运行solc --asm --opcodes arith_demo.sol命令观察编译器生成的字节码。

总结
本文介绍了EVM算术运算指令,下一篇文章将介绍EVM按位运算指令。

原文地址:https://www.cnblogs.com/405845829qq/p/9998226.html

时间: 2024-11-06 03:40:29

以太坊虚拟机介绍3-算术运算指令的相关文章

以太坊虚拟机介绍4-按位运算指令

以太坊虚拟机按位运算指令 EVM定义了8条按位运算指令,见下表: 下面是按位运算指令的操作码分布图: AND.OR.XOR.NOT AND.OR.XOR指令从栈顶弹出两个元素,进行按位运算,然后把结果推入栈顶.以AND指令为例,下面是它的操作示意图: NOT指令将栈元素按位取反,下面是它的操作示意图: 这四条指令分别与Solidity语言里的&.|.^和~运算符直接对应,下面的Solidity代码演示了这四条指令的具体应用(读者可以运行solc --asm --opcodes bitwise_d

以太坊虚拟机介绍

近期打算写一些关于以太坊虚拟机(后面简称EVM)的文章,这是其中的第一篇.这一系列文章想站在EVM指令集的角度,带领读者逐步理解EVM工作原理,进而理解以太坊区块链技术细节.由于网上介绍以太坊的文章也比较多,所以这一系列文章将最大程度减少不必要的废话,直接提供文章想要表达的信息. EVM基本信息编程语言虚拟机一般有两种类型,基于栈,或者基于寄存器.大部分我们所熟知的语言都采用基于栈的虚拟机,比如最著名的Java虚拟机.在游戏领域非常流行的Lua语言则采用了基于寄存器的虚拟机.和JVM一样,EVM

以太坊虚拟机介绍5-比较操作指令

以太坊虚拟机比较操作指令 EVM定义了6条比较操作指令,见下表: 下面是比较操作指令的操作码分布图: LT.GT.SLT.SGT.EQ这5条指令都是从栈顶弹出两个元素,进行比较,然后把结果(1表示true,0表示false)推入栈顶.其中LT和GT把弹出的元素解释为无符号整数进行比较,SLT和SGT把弹出的元素解释为有符号数进行比较,EQ不关心符号.以LT指令为例,下面是它的操作示意图: ISZERO ISZERO指令从栈顶弹出一个元素,判断它是否为0,如果是,则把1推入栈顶,否则把0推入栈顶.

以太坊虚拟机介绍2-栈操作指令

上一篇文章对EVM和它的指令集进行了简单介绍,本文将介绍POP指令.PUSHx系列指令.DUPx系列指令.SWAPx系列指令.这些指令只对EVM栈进行单纯的操作,它们的操作码分布如下图所示: POP指令POP指令(操作码0x50)从栈顶弹出一个元素.下面是POP指令的操作示意图(白色表示元素即将发生变动): PUSHx指令PUSH系列指令把紧跟在指令后面的N(1 - 32)字节元素推入栈顶.PUSH系列指令一共有32条,从PUSH1(操作码0x60)一直到PUSH32(操作码0x7A).EVM是

深入了解以太坊虚拟机第5部分——一个新合约被创建后会发生什么

在该系列文章的前部分,我们学了EVM汇编基础,也学了ABI编码是如何允许外部程序与合约进行通信的.在本文中,我们将会学习一个合约是如何从零创建的. 本系列的相关文章(按照顺序): EVM汇编代码的介绍(第1部分) 固定长度数据类型的表示方法(第2部分) 动态数据类型的表示方法(第3部分) ABI编码外部方法调用的方式(第4部分) 我们目前所见的EVM字节码都是比较清晰明朗的,就是EVM从上往下的执行指令,没有什么隐藏的魔法.合约创建的过程更有意思一些,它将数据和代码之间的界限模糊化. 在学习合约

深入了解以太坊虚拟机第4部分——ABI编码外部方法调用的方式

在本系列的上一篇文章中我们看到了Solidity是如何在EVM存储器中表示复杂数据结构的.但是如果无法交互,数据就是没有意义的.智能合约就是数据和外界的中间体. 在这篇文章中我们将会看到Solidity和EVM可以让外部程序来调用合约的方法并改变它的状态. "外部程序"不限于DApp/JavaScript.任何可以使用HTTP RPC与以太坊节点通信的程序,都可以通过创建一个交易与部署在区块链上的任何合约进行交互. 创建一个交易就像发送一个HTTP请求.Web的服务器会接收你的HTTP

谈一谈以太坊虚拟机EVM的缺陷与不足

首先,EVM的设计初衷是什么?它为什么被设计成目前我们看的样子呢?根据以太坊官方提供的设计原理说明,EVM的设计目标主要针对以下方面: 简单性(Simplicity) 确定性(Determinism) 节省空间的bytecode 专为区块链设计 更加简单的安全性保证 容易优化 如果读者浏览一下这个文档,会发现EVM的设计看上去都非常的合理.那么问题在哪里呢?问题就出在它和目前主流的技术以及设计范例都格格不入.EVM如果作为一个毫无限制的非现实世界中的设计确实很不错.接下来笔者会围绕EVM各个方面

以太坊Go、Java、Python、Ruby、JS客户端介绍

作者:HPB_汪晓明(HPB Team) Go Ethereum 简介 go-ethereum客户端通常被称为geth,它是个命令行界面,执行在Go上实现的完整以太坊节点.通过安装和运行geth,可以参与到以太坊前台实时网络并进行以下操作: 挖掘真的以太币 在不同地址间转移资金 创建合约,发送交易 探索区块历史 及很多其他 Go Ethereum 链接: 网站: http://ethereum.github.io/go-ethereum/ Github: https://github.com/e

solidity编程开发语言——以太坊智能合约利器

这篇关于Solidity教程的博客展示了很多Solidity特性.本教程假定你对以太坊虚拟机和编程有一定的了解. 以太坊,"世界计算机"提供了一个非常强大的全球共享基础设施,使用名为Solidity的编程语言构建去中心化应用程序. 让我们开始我们的Solidity教程,介绍Solidity. 什么是Solidity? 以太坊Solidity是一种面向智能合约的高级语言,其语法与JavaScript类似.solidity是用于生成在EVM上执行的机器级代码的工具.solidity编译器获