mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #8022 from ethereum/updateAssembly2
Update assembly for 0.6.0.
This commit is contained in:
		
						commit
						197875c97a
					
				| @ -6,7 +6,8 @@ Solidity Assembly | ||||
| 
 | ||||
| Solidity defines an assembly language that you can use without Solidity and also | ||||
| as "inline assembly" inside Solidity source code. This guide starts with describing | ||||
| how to use inline assembly, how it differs from standalone assembly, and | ||||
| how to use inline assembly, how it differs from standalone assembly | ||||
| (sometimes also referred to by its proper name "Yul"), and | ||||
| specifies assembly itself. | ||||
| 
 | ||||
| .. _inline-assembly: | ||||
| @ -22,6 +23,10 @@ As the EVM is a stack machine, it is often hard to address the correct stack slo | ||||
| and provide arguments to opcodes at the correct point on the stack. Solidity's inline | ||||
| assembly helps you do this, and with other issues that arise when writing manual assembly. | ||||
| 
 | ||||
| For inline assembly, the stack is actually not visible at all, but if you look | ||||
| closer, there is always a very direct translation from inline assembly to | ||||
| the stack based EVM opcode stream. | ||||
| 
 | ||||
| Inline assembly has the following features: | ||||
| 
 | ||||
| * functional-style opcodes: ``mul(1, add(2, 3))`` | ||||
| @ -48,32 +53,22 @@ these curly braces, you can use the following (see the later sections for more d | ||||
| 
 | ||||
|  - literals, i.e. ``0x123``, ``42`` or ``"abc"`` (strings up to 32 characters) | ||||
|  - opcodes in functional style, e.g. ``add(1, mload(0))`` | ||||
|  - variable declarations, e.g. ``let x := 7``, ``let x := add(y, 3)`` or ``let x`` (initial value of empty (0) is assigned) | ||||
|  - variable declarations, e.g. ``let x := 7``, ``let x := add(y, 3)`` or ``let x`` (initial value of 0 is assigned) | ||||
|  - identifiers (assembly-local variables and externals if used as inline assembly), e.g. ``add(3, x)``, ``sstore(x_slot, 2)`` | ||||
|  - assignments, e.g. ``x := add(y, 3)`` | ||||
|  - blocks where local variables are scoped inside, e.g. ``{ let x := 3 { let y := add(x, 1) } }`` | ||||
| 
 | ||||
| The following features are only available for standalone assembly: | ||||
| 
 | ||||
|  - direct stack control via ``dup1``, ``swap1``, ... | ||||
|  - direct stack assignments (in "instruction style"), e.g. ``3 =: x`` | ||||
|  - labels, e.g. ``name:`` | ||||
|  - jump opcodes | ||||
| 
 | ||||
| .. note:: | ||||
|   Standalone assembly is supported for backwards compatibility but is not documented | ||||
|   here anymore. | ||||
| 
 | ||||
| At the end of the ``assembly { ... }`` block, the stack must be balanced, | ||||
| unless you require it otherwise. If it is not balanced, the compiler generates | ||||
| a warning. | ||||
| Inline assembly manages local variables and control-flow. Because of that, | ||||
| opcodes that interfere with these features are not available. This includes | ||||
| the ``dup`` and ``swap`` instructions as well as ``jump`` instructions and labels. | ||||
| 
 | ||||
| Example | ||||
| ------- | ||||
| 
 | ||||
| The following example provides library code to access the code of another contract and | ||||
| load it into a ``bytes`` variable. This is not possible with "plain Solidity" and the | ||||
| idea is that assembly libraries will be used to enhance the Solidity language. | ||||
| idea is that reusable assembly libraries can enhance the Solidity language | ||||
| without a compiler change. | ||||
| 
 | ||||
| .. code:: | ||||
| 
 | ||||
| @ -157,26 +152,23 @@ Opcodes | ||||
| ------- | ||||
| 
 | ||||
| This document does not want to be a full description of the Ethereum virtual machine, but the | ||||
| following list can be used as a reference of its opcodes. | ||||
| following list can be used as a quick reference of its opcodes. | ||||
| 
 | ||||
| If an opcode takes arguments (always from the top of the stack), they are given in parentheses. | ||||
| Note that the order of arguments can be seen to be reversed in non-functional style (explained below). | ||||
| Opcodes marked with ``-`` do not push an item onto the stack (do not return a result), | ||||
| those marked with ``*`` are special and all others push exactly one item onto the stack (their "return value"). | ||||
| If an opcode takes arguments, they are given in parentheses. | ||||
| Opcodes marked with ``-`` do not return a result, | ||||
| those marked with ``*`` are special in a certain way and all others return exactly one value. | ||||
| Opcodes marked with ``F``, ``H``, ``B``, ``C`` or ``I`` are present since Frontier, Homestead, | ||||
| Byzantium, Constantinople or Istanbul, respectively. | ||||
| 
 | ||||
| In the following, ``mem[a...b)`` signifies the bytes of memory starting at position ``a`` up to | ||||
| but not including position ``b`` and ``storage[p]`` signifies the storage contents at position ``p``. | ||||
| but not including position ``b`` and ``storage[p]`` signifies the storage contents at slot ``p``. | ||||
| 
 | ||||
| The opcodes ``pushi`` and ``jumpdest`` cannot be used directly. | ||||
| 
 | ||||
| In the grammar, opcodes are represented as pre-defined identifiers. | ||||
| In the grammar, opcodes are represented as pre-defined identifiers ("built-in functions"). | ||||
| 
 | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | Instruction             |     |   | Explanation                                                     | | ||||
| +=========================+=====+===+=================================================================+ | ||||
| | stop                    + `-` | F | stop execution, identical to return(0,0)                        | | ||||
| | stop()                  + `-` | F | stop execution, identical to return(0, 0)                       | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | add(x, y)               |     | F | x + y                                                           | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| @ -208,11 +200,11 @@ In the grammar, opcodes are represented as pre-defined identifiers. | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | iszero(x)               |     | F | 1 if x == 0, 0 otherwise                                        | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | and(x, y)               |     | F | bitwise and of x and y                                          | | ||||
| | and(x, y)               |     | F | bitwise "and" of x and y                                        | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | or(x, y)                |     | F | bitwise or of x and y                                           | | ||||
| | or(x, y)                |     | F | bitwise "or" of x and y                                         | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | xor(x, y)               |     | F | bitwise xor of x and y                                          | | ||||
| | xor(x, y)               |     | F | bitwise "xor" of x and y                                        | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | byte(n, x)              |     | F | nth byte of x, where the most significant byte is the 0th byte  | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| @ -220,7 +212,7 @@ In the grammar, opcodes are represented as pre-defined identifiers. | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | shr(x, y)               |     | C | logical shift right y by x bits                                 | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | sar(x, y)               |     | C | arithmetic shift right y by x bits                              | | ||||
| | sar(x, y)               |     | C | signed arithmetic shift right y by x bits                       | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | addmod(x, y, m)         |     | F | (x + y) % m with arbitrary precision arithmetic                 | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| @ -230,17 +222,9 @@ In the grammar, opcodes are represented as pre-defined identifiers. | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | keccak256(p, n)         |     | F | keccak(mem[p...(p+n)))                                          | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | jump(label)             | `-` | F | jump to label / code position                                   | | ||||
| | pc()                    |     | F | current position in code                                        | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | jumpi(label, cond)      | `-` | F | jump to label if cond is nonzero                                | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | pc                      |     | F | current position in code                                        | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | pop(x)                  | `-` | F | remove the element pushed by x                                  | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | dup1 ... dup16          |     | F | copy nth stack slot to the top (counting from top)              | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | swap1 ... swap16        | `*` | F | swap topmost and nth stack slot below it                        | | ||||
| | pop(x)                  | `-` | F | discard value x                                                 | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | mload(p)                |     | F | mem[p...(p+32))                                                 | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| @ -252,27 +236,27 @@ In the grammar, opcodes are represented as pre-defined identifiers. | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | sstore(p, v)            | `-` | F | storage[p] := v                                                 | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | msize                   |     | F | size of memory, i.e. largest accessed memory index              | | ||||
| | msize()                 |     | F | size of memory, i.e. largest accessed memory index              | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | gas                     |     | F | gas still available to execution                                | | ||||
| | gas()                   |     | F | gas still available to execution                                | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | address                 |     | F | address of the current contract / execution context             | | ||||
| | address()               |     | F | address of the current contract / execution context             | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | balance(a)              |     | F | wei balance at address a                                        | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | selfbalance()           |     | I | equivalent to balance(address()), but cheaper                   | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | caller                  |     | F | call sender (excluding ``delegatecall``)                        | | ||||
| | caller()                |     | F | call sender (excluding ``delegatecall``)                        | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | callvalue               |     | F | wei sent together with the current call                         | | ||||
| | callvalue()             |     | F | wei sent together with the current call                         | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | calldataload(p)         |     | F | call data starting from position p (32 bytes)                   | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | calldatasize            |     | F | size of call data in bytes                                      | | ||||
| | calldatasize()          |     | F | size of call data in bytes                                      | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | calldatacopy(t, f, s)   | `-` | F | copy s bytes from calldata at position f to mem at position t   | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | codesize                |     | F | size of the code of the current contract / execution context    | | ||||
| | codesize()              |     | F | size of the code of the current contract / execution context    | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | codecopy(t, f, s)       | `-` | F | copy s bytes from code at position f to mem at position t       | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| @ -280,7 +264,7 @@ In the grammar, opcodes are represented as pre-defined identifiers. | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | extcodecopy(a, t, f, s) | `-` | F | like codecopy(t, f, s) but take code at address a               | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | returndatasize          |     | B | size of the last returndata                                     | | ||||
| | returndatasize()        |     | B | size of the last returndata                                     | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | returndatacopy(t, f, s) | `-` | B | copy s bytes from returndata at position f to mem at position t | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| @ -315,7 +299,7 @@ In the grammar, opcodes are represented as pre-defined identifiers. | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | selfdestruct(a)         | `-` | F | end execution, destroy current contract and send funds to a     | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | invalid                 | `-` | F | end execution with invalid instruction                          | | ||||
| | invalid()               | `-` | F | end execution with invalid instruction                          | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | log0(p, s)              | `-` | F | log without topics and data mem[p...(p+s))                      | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| @ -328,23 +312,23 @@ In the grammar, opcodes are represented as pre-defined identifiers. | ||||
| | log4(p, s, t1, t2, t3,  | `-` | F | log with topics t1, t2, t3, t4 and data mem[p...(p+s))          | | ||||
| | t4)                     |     |   |                                                                 | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | chainid                 |     | I | ID of the executing chain (EIP 1344)                            | | ||||
| | chainid()               |     | I | ID of the executing chain (EIP 1344)                            | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | origin                  |     | F | transaction sender                                              | | ||||
| | origin()                |     | F | transaction sender                                              | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | gasprice                |     | F | gas price of the transaction                                    | | ||||
| | gasprice()              |     | F | gas price of the transaction                                    | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | blockhash(b)            |     | F | hash of block nr b - only for last 256 blocks excluding current | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | coinbase                |     | F | current mining beneficiary                                      | | ||||
| | coinbase()              |     | F | current mining beneficiary                                      | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | timestamp               |     | F | timestamp of the current block in seconds since the epoch       | | ||||
| | timestamp()             |     | F | timestamp of the current block in seconds since the epoch       | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | number                  |     | F | current block number                                            | | ||||
| | number()                |     | F | current block number                                            | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | difficulty              |     | F | difficulty of the current block                                 | | ||||
| | difficulty()            |     | F | difficulty of the current block                                 | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| | gaslimit                |     | F | block gas limit of the current block                            | | ||||
| | gaslimit()              |     | F | block gas limit of the current block                            | | ||||
| +-------------------------+-----+---+-----------------------------------------------------------------+ | ||||
| 
 | ||||
| Literals | ||||
| @ -423,12 +407,6 @@ Local Solidity variables are available for assignments, for example: | ||||
|     To clean signed types, you can use the ``signextend`` opcode: | ||||
|     ``assembly { signextend(<num_bytes_of_x_minus_one>, x) }`` | ||||
| 
 | ||||
| Labels | ||||
| ------ | ||||
| 
 | ||||
| Support for labels has been removed in version 0.5.0 of Solidity. | ||||
| Please use functions, loops, if or switch statements instead. | ||||
| 
 | ||||
| Declaring Assembly-Local Variables | ||||
| ---------------------------------- | ||||
| 
 | ||||
| @ -574,8 +552,7 @@ opcode. | ||||
| 
 | ||||
| Functions can be defined anywhere and are visible in the block they are | ||||
| declared in. Inside a function, you cannot access local variables | ||||
| defined outside of that function. There is no explicit ``return`` | ||||
| statement. | ||||
| defined outside of that function. | ||||
| 
 | ||||
| If you call a function that returns multiple values, you have to assign | ||||
| them to a tuple using ``a, b := f(x)`` or ``let a, b := f(x)``. | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user