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

以太坊虚拟机按位运算指令

EVM定义了8条按位运算指令,见下表:

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

AND、OR、XOR、NOT

AND、OR、XOR指令从栈顶弹出两个元素,进行按位运算,然后把结果推入栈顶。以AND指令为例,下面是它的操作示意图:

NOT指令将栈元素按位取反,下面是它的操作示意图:

这四条指令分别与Solidity语言里的&、|、^和~运算符直接对应,下面的Solidity代码演示了这四条指令的具体应用(读者可以运行solc --asm --opcodes bitwise_demo1.sol命令观察编译器生成的字节码):

// bitwise_demo1.sol
pragma solidity ^0.4.24;

contract C {

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

s3 = s1 & s2; // ADD
s3 = s1 | s2; // OR
s3 = s1 ^ s2; // XOR
s3 = ~ s1; // NOT

u3 = u1 & u2; // ADD
u3 = u1 | u2; // OR
u3 = u1 ^ u2; // XOR
u3 = ~ u1; // NOT
}

}
BYTE
BYTE指令先后从栈顶弹出n和x,取x的第n个字节并推入栈顶。由于EVM的字长是32个字节,所以n在[0, 31]区间内才有意义,否则BYTE的运算结果就是0。另外,字节是从左到右数的,因此第0个字节占据字的最高位8个比特。以n=1为例,下面是BYTE指令操作示意图:

读者可以通过下面的Solidity代码观察BYTE指令的用法:

// byte_demo2.sol
pragma solidity ^0.4.24;

contract C {

function test() public pure {
bytes32 a;
bytes1 b = a[31]; // ... BYTE ...
}

}

SHL、SHR、SAR

这三条位移指令是由EIP-145引入的,从Constantinople虚拟机开始支持。这三条指令都是先后从栈顶弹出两个数n和x,其中x是要进行位移操作顶数,n是位移比特数,然后把结果推入栈顶。以左移指令SHL为例,下面是它的操作示意图:

SHR和SAR的区别在于,前者执行逻辑右移(空缺补0),后者执行算术右移(空缺补符号位)。下表总结了这三条位移指令对于操作数的解释,以及计算结果(这里^表示指数运算):

Solidity语言提供了<<>>运算符,下表总结了这两个运算符的含义(这里**表示指数运算):

在Constantinople之前,位移运算符使用EXP、MUL、DIV、SDIV等指令实现;从Constantinople开始,位移运算符可以使用位移指令实现。不过请读者注意,<<运算符可以直接编译成SHL指令,但是由于取整方式不同,所以>>运算符并不能直接编译成SAR指令,详见EIP-145和Solidity文档。读者可以通过下面的Solidity代码观察位移指令的用法(可以通过--evm-version选项告诉Solidity编译器目标EVM版本,例如solc --asm --opcodes --evm-version constantinople bitwise_demo2.sol,如不指定,默认是byzantium):

// bitwise_demo2.sol
pragma solidity ^0.4.24;

contract C {

function test() public pure {
int s1; int s2;
uint u1; uint u2;
uint n;

u2 = u1 << n; // SHL
s2 = s1 << n; // SHL
u2 = u1 >> n; // SHR
s2 = s1 >> n; // EXP、SDIV
//s2 = s1 >>> n; // SHR?
}

}

总结

本文介绍了EVM按位运算指令,下一篇文章将介绍EVM比较操作指令。

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

时间: 2024-11-06 03:35:07

以太坊虚拟机介绍4-按位运算指令的相关文章

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

以太坊虚拟机算术运算指令EVM总共定义了11条算术运算指令,见下表: 这些指令从栈顶弹出两到三个元素,进行相应计算,然后把结果推入栈顶.参与计算的元素和结果均被解释为按二的补码编码的整数.如果计算结果(假设为x)溢出(超出2^256),则最终的结果x'取值x % 2^256(%表示取模运算,^表示指数运算). 下面是算术运算指令的操作码分布图: ADD.MUL.SUB.DIV.SDIV.MOD.SMOD.EXP这8条指令操作方式比较类似,从栈顶弹出两个元素,进行计算,然后把计算结果推入栈顶.由于

以太坊虚拟机介绍

近期打算写一些关于以太坊虚拟机(后面简称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

使用 Go-Ethereum 1.7.2搭建以太坊私有链

1.什么是Ethereum(以太坊) 以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约.开源的底层系统,以太坊从诞生到2017年5月,短短3年半时间,全球已有200多个以太坊应用诞生.以太坊是一个平台和一种编程语言,使开发人员能够建立和发布下一代分布式应用. 以太坊可以用来编程,分散,担保和交易任何事物:投票,域名,金融交易所,众筹,公司管理, 合同和大部分的协议,知识产权,还有得益于硬件集成的智能资产. 以太坊的白皮书:https://github.com/ethe