I am just diving into EVM assembly and am a little confused about the following. I have the following simple contract:
pragma solidity >=0.8.1;
contract MyTest {}
When I compile it using Remix, I get the following assembly code:
.code
PUSH 80 contract MyTest {\r\n \r\n}
PUSH 40 contract MyTest {\r\n \r\n}
MSTORE contract MyTest {\r\n \r\n}
CALLVALUE contract MyTest {\r\n \r\n}
DUP1 contract MyTest {\r\n \r\n}
ISZERO contract MyTest {\r\n \r\n}
PUSH [tag] 1 contract MyTest {\r\n \r\n}
JUMPI contract MyTest {\r\n \r\n}
PUSH 0 contract MyTest {\r\n \r\n}
DUP1 contract MyTest {\r\n \r\n}
REVERT contract MyTest {\r\n \r\n}
tag 1 contract MyTest {\r\n \r\n}
JUMPDEST contract MyTest {\r\n \r\n}
POP contract MyTest {\r\n \r\n}
PUSH #[$] 0000000000000000000000000000000000000000000000000000000000000000 contract MyTest {\r\n \r\n}
DUP1 contract MyTest {\r\n \r\n}
PUSH [$] 0000000000000000000000000000000000000000000000000000000000000000 contract MyTest {\r\n \r\n}
PUSH 0 contract MyTest {\r\n \r\n}
CODECOPY contract MyTest {\r\n \r\n}
PUSH 0 contract MyTest {\r\n \r\n}
RETURN contract MyTest {\r\n \r\n}
.data
0:
.code
PUSH 80 contract MyTest {\r\n \r\n}
PUSH 40 contract MyTest {\r\n \r\n}
MSTORE contract MyTest {\r\n \r\n}
PUSH 0 contract MyTest {\r\n \r\n}
DUP1 contract MyTest {\r\n \r\n}
REVERT contract MyTest {\r\n \r\n}
.data
When I use the solidity compiler to create assembly code from that contract (solc --asm
), I get the following:
/* "test.sol":26:49 contract MyTest {... */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
dataSize(sub_0)
dup1
dataOffset(sub_0)
0x00
codecopy
0x00
return
stop
sub_0: assembly {
/* "test.sol":26:49 contract MyTest {... */
mstore(0x40, 0x80)
0x00
dup1
revert
auxdata: 0xa264697066735822122057b4abeab2d44c9d2cbb61c1302d88d50541a562fe3c17fb627482ec50f5651064736f6c63430008130033
}
It seems like the Remix assembly code is going deeper to core EVM as it is using the actual opcodes as described in the Yellow Paper, while the Solidity compiler assembly has a layer of abstraction which I assume is some Yul syntax. Does anyone have information on the latter one? Maybe some documentation or tutorials? Why does the assembly output differ and what is the preferred way if you want to code directly in assembly?