Assembly Block
Marked by assembly { ... }
pragma solidity ^0.6.1;
contract Hello {
function SayHi() {
assembly {
// assembly code here
}
}
}
## Comments
- Use the // or /* */ to denote comments
```
assembly {
// this is a comment
/* this is a multiline
* comment
*/
}
```
If
- Conditionally execute code
- No “else” block
if eq(value, 0) { value := 3 }
### Switch
- Similar to "if", but with more branching options
- Fallback or default case: `default`
- No fall through to following cases
```
assembly {
switch x
case 0 { x := 1 }
default { x := add(x,1) }
}
```
### Loop
- Repeat operations
- break: exit the Loop
- continue: skip to next iteration
```
function lo(uint max) public pure returns(uint result) {
assembly {
for { let i := 0 } lt(i, 20) { i := add(i, 1) } {
if lt(i,3) { continue }
if gt(i, max) { break }
result := add(result,1)
}
}
}
```
OpCode
OpCode (Operation Code) is a machine instruction that specifies the operation to be performed - Wikipedia
extcodehash
- Used in openzeppelin IsContract()
utilitity
- Returns the code hash of a contract
assembly { codehash := extcodehash(accountAddress) }
### Data Sanity
- If you access variables of a type that spans less than 256 bits (e.g. uint64, address, bytes16 or byte),
bits not part of the type, may not be `zeroed`
- Always clear data before using it
```
uint32 x = f();
assembly {
x := and(x, 0xffffffff)
/* now use x */
}
```
### Two's Complement
- Used in EVM
- Same arithmetic for signed and unsigned
- No negative 0
### Signed Functions
- Use to process signed data
- sdiv(), smod(), slt(), sgt(), sar(), signextend()
- Would x be 100 or 99 from the following code?
```
int a = -3;
assembly {
let x := 100
if lt(a, 0) {
x := 99
}
}
```
Gas Fee
- Fee schedule in Ethereum Yellow Paper
- Some opcodes are more expensive than others
- e.g. multiplication costs 5 gas; shift left costs 3 gas
### Benefits of Inline Assembly
- Code could be more gas efficient
- Bypass Solidity safety checks
- Less code, less gas fee
- Some operations only available in assembly