Nightmare of Operations

Bobby Yang
HackerNoon.com
5 min readMar 5, 2017

--

Choose wisely or you’ll have an extra blog post assignment

I open my eyes. It’s pitch black. Panic sets as I prepare for the worst. I scream out for help but mid-scream a spotlight shines in to my eyes, temporarily blinding me. Instinctively, I raise my arm up to my face to block the light. As my eyes start to adjust to the light, I see the silhouette of a doll.

A few seconds go by, and the doll turns it’s head towards me and said in a french accent:

“ I want to play ze game... Iz i = i++ ze same aaaz i++? ”

Being a 1 month old software engineering student, I think back to all of my experience to try to answer the question.

That’s it, I lost.

I jolt up from my bed, with my phone alarm ringing in my ears. I swipe right turn off my alarm. Fully awake, I look up at the ceiling and recuperate my thoughts about my dream.

Does i = i++ increment i then assigns the value to i ?

Something about the problem intrigued to dive deeper. So I leaped out of bed to my computer to get to the bottom of this enigma.

I put on some KPOP and started to write a simple test.

pretty self explanatory

My heart jumped a beat when the program ran.

i done messed up

Shit, you done messed up A-aron.

I had some time before I had to leave to go to school, so I decided to actually go even deeper and take a look at what exactly is going on in Assembly.

I opened up the test program executable with gdb and set a breakpoint at main so the program would run until main returns then stop.

(gdb) break main

Then I ran the program with this new breakpoint.

(gdb) run

Finally, I wanted to see the assembly instructions for the current function (main) so I used the disassemble command.

(gdb) disassemble

That gave me this.

assembly for test program

Quick Assembly lesson.

Immediate values are constants and prefixed by a $ . Like $0xa is the decimal 10 in hexadecimal. Register names are prefixed a % .

Registers are small memory spaces in the processor of a computer that hold a single value. There are two types of registers: general registers and special registers. In our code sample, %eax , %edx , %esi and %edi are general registers, while %rbp and %rsp are special registers.

The first two lines are called the function preamble. This pushes the old base pointer onto the stack to save for later. Then it copies the value of the stack pointer to the base pointer. So after first two lines, %rbp will point to the base of main’s stack frame.

Skipping down a few lines, we can see that the value $0xa which is 10 in hexadecimal gets copied into -0x4(%rbp)using the movl instruction. movl is the same as the mov command but the l signifies that the operands will be a long. -0x4(%rbp) is the same as %rbp + -0x4 and because the stack grows downwards, subtracting 4 from the base of the current stack frame actually accesses the current frame itself. Thats were the local variable i is stored. So $0xa is being copied into the local variable i .

The next line is where it gets interesting.

The lea instruction is sort of like the mov instruction. mov , using syntax like mov <destination>, <source> , moves the contents from the source to the destination.

lea , however, moves the address of the source to the destination. It calculates the address specified by its second operand as if it were going to load or store data from it, but instead it stores the calculated address into the register specified by its first operand.

So the above instruction means %edx = %rax + 1 .

Then on the next line we see.

This moves the contents of -0x4(%rbp) which is the local variable i that has the value $0xa into %edx . So this operation is stored in a another temporary register, not the original register. So the increment was done, just in another temporary register.

Then I compared that to the second test of i++ .

This added $0x1 to i .

This explains why i = i++ returns i instead of i + 1 .

So the crux of the problem is a problem of evaluation order.

So when i = i++ is compiled:

  1. the value of i gets copied to a temporary location
  2. The temporary value is incremented and saved as a new value (not overwriting)
  3. The new value is stored in i
  4. Then ireturns the temporary value, which is the same as the original value

Having found the answer, I packed my things and got ready to go to school.

I arrived at school just in time for our Peer Learning Day.

I listened and participated as my peers started going over assignments from the previous week. Then out of nowhere I heard the question with the same french accent:

Iz i = i++ ze same aaaz i++?

Hacker Noon is how hackers start their afternoons. We’re a part of the @AMI family. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.

If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!

--

--