2016-10-09 - Nightmares
I occasionally have what people might call nightmares. That is to say I have dreams that are about scary things. I remember having a dream a while ago where I was running around an industrial plant at night and being chased by zombies. The thing is though, I don't find them to be scary. I actually find them rather enjoyable. I sometimes get startled awake while having these dreams but I never feel afraid to go back to sleep afterwards.
I think playing video games helps me to accept dreams as not being real. I'm used to controlling a character in a virtual world which makes it easier to separate myself from the dream world while still being a part of it. I can be impacted by what's happening in the dream but I know it can't actually hurt me.
What I find really terrifying is when you wake up but are unable to move. You lay there yelling at your muscles to do something. Trying to force yourself to fully wake up. That sense of dread that you are trapped in your own body. That's a nightmare.
2016-09-18 - In IL: Largest of Three Numbers (If-ElseIf-Else)
Last time we looked at a program which used an If statement to determine which of two numbers was the largest. If statements can actually get a lot more complicated. They can be extended with additional else if clauses which allow alternative conditions to be tested. The condition can also contain multiple comparisons combined using logical operators.
Continuing from last time let's look at a program that reports which of three numbers is the largest using if, else if, else statements in Visual basic .NET.
Before we look at the compiled output I want to point out one thing. The If condition uses the AndAlso operator (&& in C#) while the ElseIf uses the And operator (& in C#). We will be able to see the difference between these two operators when we look at the compiled code. So let's do that now.
As expected we have three sets of instructions which print text to the console. There are also three branching instructions used to implement the if-else chain.
Branching instructions are generally of the form Value1 Operation Value2 where Value1 is the second value popped off the stack, Value2 is the first value popped off the stack, and Operation is the condition specified by the branch instruction. Last time we determined Value1 and Value2 by running through the program and determining the values on the stack at the point of the branch instruction. This will become very time consuming as our programs get more and more complicated so I'd like to find an easier way.
The value at the top of the stack will be the last value pushed onto the stack and not removed. The value second from the top of the stack will be the second to last value pushed onto the stack and not removed. This means we can determine Value1 and Value2 by working backwards from the branch instruction and looking at what gets pushed onto the stack.
Looking at the first branch instruction on line 90 we see the first instruction before it loads local variable 1 while the second instruction before it loads local variable 0. This means Value1 is NumberA and Value2 is NumberB. The instruction is ble so the condition is NumberA <= NumberB. Looking at the code this matches up with the first part of the if condition (Remember the compiler likes to inverse branch conditions compared to if conditions). If the condition is true we jump to line 110 which is the start of the ElseIf block.
The second branch instruction will only be encountered if the first condition is false. It is also a ble instruction but this time it compares local variable 0 and local variable 2. So the condition is NumberA <= NumberC which matches up with the second part of the if condition. If the condition is true we again jump to line 110. If the condition is false we execute the If block and print that NumberA is the largest.
If either of those conditions are true we branch to the ElseIf Condition. This time though we have two greater-than compare instructions and an and instruction followed by a brfalse instruction. The process for determining comparison values is the same as branching instructions so the full condition is NumberB > NumberA And NumberB > NumberC which is exactly the ElseIf condition. If the result is false we branch to the Else block otherwise we execute the ElseIf block and print that NumberB is the largest.
Why does the ElseIf condition perform the full comparison while the If condition had two branch instructions? As I mentioned earlier the ElseIf uses And while the If uses AndAlso. The difference between these two operators is that AndAlso is lazy. Since logical and requires all of its arguments to be true in order for the result to be true it's possible to know that the result is false after only checking some of the arguments if one of them turns out to be false. AndAlso uses this fact to skip the other comparison if it determines that the first is false. And on the other hand performs all comparisons.
AndAlso is able to make less comparisons which in some ways makes it more efficient. And always executes all comparisons which is important if some of those comparisons have side effects.
Next time we are going to look at the IL Switch instruction.
2016-08-10 - Histories of Countries
I am fascinated by the history of countries. The course of events that lead to the current situation. The critical points that drastically changed how a country worked. The impact countries have on each other. It's interesting because there is just so much that has happened in the very short span of human history.
For example did you know that Greece was once under control of the Turks? That Italy was only unified in the 1800s? That France is in it's fifth republic? That Spain was once a Muslim country and that the Netherlands were once controlled by Spain? That Austria was almost a part of Germany but didn't join because it would have meant giving up its non-Germanic territories? That Poland and Lithuania were once united as the Polish–Lithuanian Commonwealth?
I'd really like to spend some time researching the history of countries and maybe doing some writing on the subjects. I really like computers and programming but I would also like to learn about other things.
2016-07-24 - In IL: Largest of Two Numbers (if-else)
Last time we looked at IL branching Instructions. The simplest use of branching instructions is probably the If statement which allows the program to conditionally execute a set of instructions. If the condition is true then the program executes the code within the if block. Statements like this exist in most high level languages because they allow the program to make decisions about whether or not code should be executed. If statements can also have Else blocks which are only executed if the condition is false.
Let's look at a simple program that reports which of two numbers is the largest using if, else statements in C#.
Compile it and we get something like this.
The first few lines are things we've seen before. You have the stack size directive, the local variable declaration and then variable initialization. At line 69 is where things get interesting. We start by loading both local variables and then calling a branch less-than-or-equal instruction.
The target of the branch is encoded using a label. labels appear at the start of a line and ends with a colon. When the program is compiled into its binary form the branching instruction encodes the target as an integer offset from the branching instruction to the instruction marked with the given label. The IL disassembler generates a label for each instruction based on its offset from the start of the method. This is the IL_XXXX: that appears at the start of each line.
If we look past the branch instructions we will see two sets of instructions which print a formatted string to the console. This code is very similar to instructions to print the volume of a cylinder that we saw earlier except it uses Console.WriteLine to perform the formatting and not string.format. The first set of instructions prints "numberA ({0}) is larger than numberB ({1})" and the second prints "numberB ({0}) is larger than numberA ({1})". If we compare this to the original C# program we see these sets of instructions match the if and else blocks respectively.
From last time we know that ble.s will cause the program to jump if the second value it pops off the stack is less than or equal to the first value it pops off the stack. The target of the branch has the label IL_0021 which is on line 83. At this point in the program the stack and local variables would look like this.
Evaluation Stack | Local Variables | |||
---|---|---|---|---|
Type | Value | Index | Type | Value |
int32 | 17 | 0 | int32 | 17 |
int32 | 96 | 1 | int32 | 96 |
The first value popped off the stack will be 96 and the second will be 17. Since 17 is less than or equal to 96 the condition will be true and the program branches. The next instruction to be executed will be at line 83. The program will print out "numberB (96) is larger than numberA (17)" and then return.
The ble instruction checks if numberB <= numberA. If we compare this to the original program we see that this is the inverse of the if statement condition, why is that? If you think about it the if statement and branching are opposites. An If statement says "Execute this code if the condition is true" while a branch instruction says "Jump away from this code if the condition is true". So the compiler inverses the logic to better match the instructions.
If you compile this program in debug mode you will see that the un-optimized version includes a greater-than comparison and then a branch false. This matches the original if statement better but requires more instructions. When running with optimizations on, the compiler tries to come up with the simplest set of instructions that functionally match the original program. This is also why both sets of instructions contain their own return instruction instead of a common return instruction which would have required the if set to end with a branch back to a point past the else instructions.
Next time we are going to do the same thing with three numbers.