# How would your life be IF you start learning assembly?

**URL:** <https://forum.openzeppelin.com/t/how-would-your-life-be-if-you-start-learning-assembly/1126>\
**Category:** Guides and Tutorials\
**Tags:** tutorial, assembly-series\
**Created:** [August 1, 2019, 3:42pm UTC](https://forum.openzeppelin.com/t/how-would-your-life-be-if-you-start-learning-assembly/1126 "2019-08-01T15:42:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![andresbach](https://avatars.discourse-cdn.com/v4/letter/a/839c29/32.png) [@andresbach](https://forum.openzeppelin.com/u/andresbach)\
**Post date:** [August 1, 2019, 3:42pm UTC](https://forum.openzeppelin.com/t/how-would-your-life-be-if-you-start-learning-assembly/1126/1 "2019-08-01T15:42:45Z")

</div>

![cover_forum_assembly](https://us1.discourse-cdn.com/flex022/uploads/zeppelin/original/2X/5/5544ac31fcb3f0ceba14db2ecb29ee724def376d.png)

> NOTE: This article is part of the [series of posts about coding in assembly](https://forum.openzeppelin.com/t/how-to-survive-in-the-assembly-world/1125); please check out the entire series for more fun.

# Captain's log day 0

You wake up one day in your blockchain dev life and you think:

– _Huh, what's that [assembly](https://solidity.readthedocs.io/en/latest/assembly.html) that everyone is talking about? What should I do?_

Start reading **right now** the [amazing post series from Ale](https://blog.openzeppelin.com/deconstructing-a-solidity-contract-part-i-introduction-832efd2d7737/), in which you will learn how the EVM interprets and executes the Solidity code. Only after that, you may `RETURN`.

– _Ok, I read it!_&nbsp; you may say...  
Great then! `JUMPI(DAY1,1)`

 ![yep, that's a wormhole](https://us1.discourse-cdn.com/flex022/uploads/zeppelin/original/1X/aee1834af5614659623fc05ec50cd529b797b0cd.jpeg)

# Captain's log day 1

If now you wonder:

– _Huh, how should I work with conditionals in assembly?_  
Don't leave because **THAT** is what we will be dealing with today.

Let's start...

## Writing the code, the _hello-world_ of `if` cases

Our first goal is to tackle the most used `if` conditional statement. [In `assembly` it's used like](https://solidity.readthedocs.io/en/latest/assembly.html#if) the regular Solidity one. The following is a trivial use of the conditional in Solidity:

```javascript
function solidityIf() public pure returns (uint256 output) {
    if (true) { output=0x1; }
}

```

It's written in assembly as:

```javascript
function assemblyIf() public pure returns (uint256 output) {
    assembly {
        if 0x1 { output:=0x1 }
    }
}

```

See? You don't have to be afraid of it =)  
Just let me point out that calling `solidityIf` consumes 323 `gas` while calling `assemblyIf` only needs 310. In certain situations, like this one, coding in assembly can reduce the overall gas consumption. Yeey! Nevertheless, although you would like to squeeze every `wei`, it's recommended to achieve a better readability in the contracts rather than a minor gas optimization. That's a task for the compiler. So don't base your decision of using `assembly` on that; use `assembly` only when a higher level language - like Solidity - can't achieve certain functionality. You have been warned.

## Writing the code, a _true_ `if` situation ~~(see the irony?)~~

In a real situation we wouldn't be hardcoding a `true` value inside the conditional, otherwise we would be wasting gas. So let's make things "_a bit more complex_" and let's try to output a one when I input a 26, number that it's strangely also the [index of the Z letter](https://en.wikipedia.org/wiki/Z) in the English alphabet. Both functions should look like:

```javascript
function solidityIf(uint256 input) public pure returns (uint256 output) {
    if (input == 0x1a) { output=0x1; }
}

function assemblyIf(uint256 input) public pure returns (uint256 output) {
    assembly {
        if eq(0x1a, input) { output:=0x1 }
    }
}

```

Okey, we have a new instruction: `eq`. This instruction `eq(x, y)` takes two parameters and outputs a one in case that both `x` and `y` are equal, but a zero in all other cases.

In our example, when the input value is 26 (0x1a in hexadecimal) the output is assigned as a one, but in all other cases, the output will be the default value: zero.

Now we realize that we wanted to do the opposite; we want to output a one in all cases **EXCEPT** when we introduce a 26. For that, the codes changes to:

```javascript
function solidityIf(uint256 input) public pure returns (uint256 output) {
    if (input != 0x1a) { output=0x1; }
}

function assemblyIf(uint256 input) public pure returns (uint256 output) {
    assembly {
        if eq(eq(0x1a, input), 0x0) { output:=0x1 }
    }
}

```

With assembly it's better to go slow because it can get complicated easily, so let's re-analyze that line. The conditional `if` statement will come to life if, and only if, you have a true statement. In the previous case, the `eq(0x1a, input)` would return a one when `input == 0x1a` and a zero in all other cases. Taking advantage of that, you can use those zeros and compare it with a zero using `eq` again, reversing the output.

You may say _Why don't we use the `not` instruction for that?_  
Because we can't, that's why. The `not(x)` instruction changes all the bits of the word at the same time, it acts as a bitwise complement or inverter. E.g. `not(0x0)` - where 0 is a 32 `byte` word full of zeros - would become a 32 `byte` word full of ones - the maximum number that we can represent with 256 `bit`s -, but if we have now a `not(0x1)`, that doesn't become a zero, it becomes a `not(0x0)-0x1` where all the digits are ones except the last one - which is a zero.

What we could have used instead of the second `eq` is another instruction called `iszero(x)`, which returns a one when `x == 0x0` and a zero otherwise. That line would have been:

`if iszero(eq(0x1a, input)) { output:=0x1 }`

## STOP! OPCODE TIME

Now that we are back on track, let's make use of what we learned from the post I mentioned in the beginning and try to see what bytecode does.

For the `assemblyIf` function we see that after the `input` is already placed in the stack, the important instructions are:

| # | Opcode | Value |
| --- | --- | --- |
| 376 | PUSH1 | 00 |
| 378 | DUP1 | |
| 379 | DUP3 | |
| 380 | PUSH1 | 1A |
| 382 | EQ | |
| 383 | EQ | |
| 384 | ISZERO | |
| 385 | PUSH2 | 0189 |
| 388 | JUMPI | |
| 389 | PUSH1 | 01 |
| 391 | SWAP1 | |
| 392 | POP | |
| 393 | JUMPDEST | |
| 394 | SWAP2 | |
| 395 | SWAP1 | |
| 396 | POP | |
| 397 | JUMP | |

Let's try to not get a nightmare from this.

Remember, we have ~~magically~~ the `input` in the stack. The first thing the bytecode does with the `PUSH 1 00`, `DUP1`, `DUP3`, and `PUSH1 1A` is setting the values for both comparisons (remember, the first one checks if the `input` is 26 and then the other `EQ` checks if the result was a zero). Those instructions are then called in 382 and 383.

Pay extra attention here because it's where the rest of the magic comes in. After 383 we should have a result based on the `input` in the stack: 1 for a non-26-ish value and a 0 for the 26. When the `ISZERO` instruction is executed, the value is inverted. After that, the value 0x0189 is pushed which corresponds to the line 393 in hex, and the `JUMPI` instruction is called which is a conditional `JUMP` that **only jumps** if the second parameter is a one. Here we have a crossroads: if the `input` value was not 26, the second parameter would be a zero (so it wouldn't jump), but if the `input` was 26, the parameter would be a one and the 388 `JUMPI` would takes us to line 393.

_Okey, we skipped 4 lines, what gives?_&nbsp; - you may wonder, but in those 4 lines (389-392) we swap a zero for the value that will be output - in our case, a one - :o

After that, the `JUMP` in 397 takes us to another place of the code where it finds an empty place in memory to save the final output, saves it, and returns it using the `RETURN` instruction. In the case that we jumped in 388, the output would be 0 because we didn't swap it for the desired value, but if we didn't jump - when `input` is not 26 - the output is 1.

Pretty cool, huh?  
Could it be better? Yeah, sure! See that the `ISZERO` instruction in 384 mirrors the result from the second `EQ`? That means that the bytecode is mirroring the result twice, and the final result is the input that comes to the second `EQ`, so those may not be required to have the same functionality.

## Conclusion

As we saw, coding in assembly shouldn't be as scary as it sounds. Yes, you should know what you are doing in assembly because its usage increases the likelihood of errors, but also sometimes it reduces the gas costs - as we saw in this case.

As you may know, this is the first article of a [series of posts that we will be doing to have fun with assembly](https://forum.openzeppelin.com/t/how-to-survive-in-the-assembly-world/1125). In [the next chapter](https://forum.openzeppelin.com/t/switch-the-way-you-use-conditionals/1651) we will continue having fun with another conditional statement that can be used in assembly but not in straight Solidity. ~~Can you imagine which one it is? 😛~~

---

<div class="post-metadata">

**Author:** ![ylv-io](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/ylv-io/32/331_2.png) [@ylv-io](https://forum.openzeppelin.com/u/ylv-io)\
**Post date:** [August 5, 2019, 3:12pm UTC](https://forum.openzeppelin.com/t/how-would-your-life-be-if-you-start-learning-assembly/1126/2 "2019-08-05T15:12:33Z")

</div>

Love the style and the puns!

---

<div class="post-metadata">

**Author:** ![balajipachai](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/balajipachai/32/416_2.png) [@balajipachai](https://forum.openzeppelin.com/u/balajipachai)\
**Post date:** [August 12, 2019, 4:49am UTC](https://forum.openzeppelin.com/t/how-would-your-life-be-if-you-start-learning-assembly/1126/3 "2019-08-12T04:49:52Z")

</div>

It is a good starting point to get into assembly.  
However, I noticed there is no line number 390 in the instruction set.

---

<div class="post-metadata">

**Author:** ![andresbach](https://avatars.discourse-cdn.com/v4/letter/a/839c29/32.png) [@andresbach](https://forum.openzeppelin.com/u/andresbach)\
**Post date:** [August 12, 2019, 7:49pm UTC](https://forum.openzeppelin.com/t/how-would-your-life-be-if-you-start-learning-assembly/1126/4 "2019-08-12T19:49:31Z")

</div>

Hey @balajipachai, thanks for the note and for reaching out!

As you may see, there are more places where 1 - or more - line is missing like the one you said. Other places are the 377, 381, and 386-387.

Those lines correspond to the _data_ or _value_ that uses the instruction and add to the execution flow. For instance, 377 corresponds to the pushed value 00, 381 to the 1A, and so on. For the `PUSHi` instructions, you will be using `i` more lines to enter the values after the instruction. That’s why the `PUSH2` of line 385 skips 2 lines after the instruction, but the rest of the `PUSH1` only takes one more line with them.

---

<div class="post-metadata">

**Author:** ![balajipachai](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/balajipachai/32/416_2.png) [@balajipachai](https://forum.openzeppelin.com/u/balajipachai)\
**Post date:** [August 13, 2019, 2:42am UTC](https://forum.openzeppelin.com/t/how-would-your-life-be-if-you-start-learning-assembly/1126/5 "2019-08-13T02:42:18Z")

</div>

Thanks, the explanation helps, cheers!!!
