I'm leanring low-level Solidity inline assembly, but confused by different output formats.
The ouptut option of Solidity compiler says:
--asm EVM assembly of the contracts.
--opcodes Opcodes of the contracts.
I tried both options to compile the contract below:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
contract MyContract {
string bar = "Hello World";
function foo() public view returns(string memory) {
return bar;
}
}
The command solc -o output --asm contract.sol
generated MyContract.evm:
/* "contract.sol":70:208 contract MyContract {... */
mstore(0x40, 0x80)
/* "contract.sol":96:122 string bar = "Hello World" */
mload(0x40)
dup1
0x40
add
0x40
mstore
dup1
0x0b
dup2
mstore
0x20
add
0x7657399374655890603765000000000000000000000000000000000000000000
dup2
mstore
pop
0x00
swap1
dup1
mload
swap1
0x20
add
swap1
tag_1
swap3
swap2
swap1
tag_2
jump // in
tag_1:
pop
/* "contract.sol":70:208 contract MyContract {... */
callvalue
dup1
... (and a lot more code)
The command solc -o output --opcodes contract.sol
generated MyContract.opcode:
PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0xB DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x7657399374655890603765000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x0 SWAP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 PUSH2 0x4F SWAP3 SWAP2 SWAP1 PUSH2 0x62 JUMP JUMPDEST POP CALLVALUE DUP1 ISZERO PUSH2 0x5C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x166 JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH2 0x6E SWAP1 PUSH2 0x105 JUMP JUMPDEST SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH2 0x90 JUMPI PUSH1 0x0 DUP6 SSTORE PUSH2 0xD7 JUMP JUMPDEST DUP3 PUSH1 0x1F LT PUSH2 0xA9 JUMPI DUP1 MLOAD PUSH1 ... ...
They look pretty much similar, although not 100% matching each other...
Questions
- Does
--opcodes
just give a more compact form of assembly code compared to--asm
output? PUSH1 0x80 PUSH1 0x40 MSTORE
in--opcodes
format vs.mstore(0x40, 0x80)
in--asm
format. Are they doing the same thing? (I guess so but not 100% sure...)- Is there a way to print
--opcodes
in a pretty format rather than in a single line? - Are there any good resouces to learn Solidity inline assembly? I googled around but found a bunch of one page blogs, which are good to explain the basics but unfortunately none of them gives a complete and in-depth tutorial