assembler命令行工具允许您将Ethers ASM Dialect汇编成可部署的EVM bytecode,并将EVM字节码反汇编成人类可读的助记符。
用法:
ethers-asm [ FILENAME ] [ OPTIONS ]
选项
--define KEY=VALUE provide assembler defines
--disassemble 反汇编输入字节码
--ignore-warnings 忽略警告
--pic 生成独立位置代码
--target LABEL 输出LABEL字节码 (默认: _)
其他选项
--debug 显示错误的堆栈跟踪
--help 显示此用法并退出
--version 显示此版本并退出
SimpleStore.asm
; SimpleStore (uint)
; Set the initial value of 42
sstore(0, 42)
; Init code to deploy myContract
codecopy(0, $myContract, #myContract)
return(0, #myContract)
@myContract {
; Non-payable
jumpi($error, callvalue)
; Get the Sighash
shr({{= 256 - 32 }}, calldataload(0))
; getValue()
dup1
{{= sighash("getValue()") }}
jumpi($getValue, eq)
; setValue(uint)
dup1
{{= sighash("setValue(uint)") }}
jumpi($setValue, eq)
; No matching signature
@error:
revert(0, 0)
@getValue:
mstore(0, sload(0))
return (0, 32)
@setValue:
; Make sure we have exactly a uint
jumpi($error, iszero(eq(calldatasize, 36)))
; Store the value
sstore(0, calldataload(4))
return (0, 0)
; There is no *need* for the PUSH32, it just makes
; decompiled code look nicer
@checksum[
{{= (defines.checksum ? concat([
Opcode.from("PUSH32"),
id(myContract.source)
]): "0x")
}}
]
}
SimpleStore.bin
0x602a6000556044601160003960446000f334601e5760003560e01c8063209652
0x5514602457806355241077146030575b60006000fd5b60005460005260206000
0xf35b6024361415601e5760043560005560006000f3
Note: 字节码文件语法
一个bin文件可以由多个字节码块组成,每个字节可以选择以0x
前缀开头,所有的字节必须为偶数长度(因为字节是必需的,每个字节有2个nibbles)。
所有空白都会被忽略。
汇编器通过汇编阶段的多次遍历,将Ethers ASM Dialect成字节码,每次🏪都接近最终结果。
这允许对字节码的一小部分进行修改和调整,直到字节码稳定。This allows for more compact jump destinations,并允许代码包含更高级的元编程技术。
/home/ethers> ethers-asm SimpleStore.asm
0x602a6000556044601160003960446000f334601e5760003560e01c80632096525514602457806355241077146030575b60006000fd5b60005460005260206000f35b6024361415601e5760043560005560006000f3
# Piping in ASM source code
/home/ethers> cat SimpleStore.asm | ethers-asm
# 和上面一样
# 设置一个ASM文件检查并添加校验和的定义
/home/ethers> ethers-asm --define checksum SimpleStore.asm
0x602a6000556065601160003960656000f334601e5760003560e01c80632096525514602457806355241077146030575b60006000fd5b60005460005260206000f35b6024361415601e5760043560005560006000f37f10358310d664c9aeb4bf4ce7a10a6a03176bd23194c8ccbd3160a6dac90774d6
--define KEY=VALUE or --define FLAG
这允许键/值对(值是一个字符串)和flags (值是true
)传递给汇编程序,这可以在Scripting Blocks中访问,例如{{= defined.someKey }}
.
--ignore-warnings
默认情况下,任何警告都将被视为一个错误。This enabled by-passing warnings.
--pic
当程序在汇编的时候,标签通常以绝对字节位置给出,可以跳转到for循环和控制流。这就意味着程序必须安装在特定的位置。
通过指定Position Independent Code flag,代码将以所有偏移量都是相对的方式生成,允许程序在不影响其逻辑的情况下移动。
不过这确实会产生额外的gas成本,即每个偏移量需要8个gas。
--target LABEL
所有程序都有一个名为_
的作用域,默认情况下是进行汇编的。这个选项允许其他被标记了的目标( 作用域或者数据段(Data Segment)进行汇编 。整个程序仍然按照常规汇编,因此这只影响输出的一部分。
反汇编程序显示给定字节码的偏移量和助记符。这个格式在未来可能会改变,以使人类更易于阅读。
/home/ethers> ethers-asm --disassemble SimpleStore.bin
0000 : 0x2a ; #1
0002 : 0x00 ; #1
0004 : SSTORE
0005 : 0x44 ; #1
0007 : 0x11 ; #1
0009 : 0x00 ; #1
000b : CODECOPY
000c : 0x44 ; #1
000e : 0x00 ; #1
0010 : RETURN
0011 : CALLVALUE
0012 : 0x1e ; #1
0014 : JUMPI
0015 : 0x00 ; #1
0017 : CALLDATALOAD
0018 : 0xe0 ; #1
001a : SHR
001b : DUP1
001c : 0x20965255 ; #4
0021 : EQ
0022 : 0x24 ; #1
0024 : JUMPI
0025 : DUP1
0026 : 0x55241077 ; #4
002b : EQ
002c : 0x30 ; #1
002e : JUMPI
002f*: JUMPDEST
0030 : 0x00 ; #1
0032 : 0x00 ; #1
0034 : REVERT
0035*: JUMPDEST
0036 : 0x00 ; #1
0038 : SLOAD
0039 : 0x00 ; #1
003b : MSTORE
003c : 0x20 ; #1
003e : 0x00 ; #1
0040 : RETURN
0041*: JUMPDEST
0042 : 0x24 ; #1
0044 : CALLDATASIZE
0045 : EQ
0046 : ISZERO
0047 : 0x1e ; #1
0049 : JUMPI
004a : 0x04 ; #1
004c : CALLDATALOAD
004d : 0x00 ; #1
004f : SSTORE
0050 : 0x00 ; #1
0052 : 0x00 ; #1
0054 : RETURN
/home/ethers> cat SimpleStore.bin | ethers-asm --disassemble
# 和上面一样
The content of this site is licensed under the Creative Commons License. Generated on January 11, 2023, 9:24pm.