----- Documentation: [html](https://docs.ethers.io/) ----- Assembler ========= Help ---- ``` Usage: ethers-asm [ FILENAME ] [ OPTIONS ] OPTIONS --define KEY=VALUE provide assembler defines --disassemble Disassemble input bytecode --ignore-warnings Ignore warnings --pic generate position independent code --target LABEL output LABEL bytecode (default: _) OTHER OPTIONS --debug Show stack traces for errors --help Show this usage and exit --version Show this version and exit ``` Example Input Files ------------------- ``` ; SimpleStore (uint) ; Set the inital 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") }} ] } ``` ``` 0x602a6000556044601160003960446000f334601e5760003560e01c8063209652 0x5514602457806355241077146030575b60006000fd5b60005460005260206000 0xf35b6024361415601e5760043560005560006000f3 ``` #### Note: Bytecode File Syntax A bin file may be made up of multiple blocks of bytecode, each may optionally begin with a `0x` prefix, all of which **must** be of even length (since bytes are required, with 2 nibbles per byte) All whitespace is ignored. Assembler Examples ------------------ ``` /home/ethers> ethers-asm SimpleStore.asm 0x602a6000556044601160003960446000f334601e5760003560e01c80632096525514602457806355241077146030575b60006000fd5b60005460005260206000f35b6024361415601e5760043560005560006000f3 # Piping in ASM source code /home/ethers> cat SimpleStore.asm | ethers-asm # Same as above # Setting a define which the ASM file checks and adds a checksum /home/ethers> ethers-asm --define checksum SimpleStore.asm 0x602a6000556065601160003960656000f334601e5760003560e01c80632096525514602457806355241077146030575b60006000fd5b60005460005260206000f35b6024361415601e5760043560005560006000f37f10358310d664c9aeb4bf4ce7a10a6a03176bd23194c8ccbd3160a6dac90774d6 ``` ### Options #### **--define KEY=VALUE** *or* **--define FLAG** This allows key/value pairs (where the value is a string) and flags (which the value is `true`) to be passed along to the assembler, which can be accessed in [Scripting Blocks](/v5/api/other/assembly/dialect/#asm-dialect-scripting), such as `{{= defined.someKey }}`. #### **--ignore-warnings** By default any warning will be treated like an error. This enabled by-passing warnings. #### **--pic** When a program is assembled, the labels are usually given as an absolute byte position, which can be jumped to for loops and control flow. This means that a program must be installed at a specific location. Byt specifying the **Position Independent Code** flag, code will be generated in a way such that all offsets are relative, allowing the program to be moved without any impact to its logic. This does incur an additional gsas cost of 8 gas per offset access though. #### **--target LABEL** All programs have a root scope named `_` which is by default assembled. This option allows another labelled target (either a [Scopes](/v5/api/other/assembly/dialect/#asm-dialect-scope) or a [Data Segment](/v5/api/other/assembly/dialect/#asm-dialect-datasegment) to be assembled instead. The entire program is still assembled per usual, so this only impacts which part of the program is output. Disassembler Examples --------------------- ``` /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 # Same as above ```