Because I like the cover here it is again

The big step here is that we add jumps, conditional and unconditional, because && and || can cause us to skip executing some code .
Ignoring Nora is a bad idea
This is where we start generating labels for jumps. The book says generate meaningful label names so that you can understand what’s going on when you see them later. My reaction “aint nobody got time for that”
(I am writing these blogs after I reached chapter 8, so I have some hindsight)
Anyway I just finished retro fitting intelligent names to labels.
More sample TACKY code
To get a feel for what things look like now here is one of the test programs (note how return is the only way that the programs under test can communicate with the test harness).
int main(void) {
return 0 || 0>1 && (1 / 0);
}
and here is the TACKY (I decided to capitalize this because calling things tacky is not nice) code
Function: main
JumpIfNotZero Int(0) "_or_true_0"
Binary GreaterThan Int(0) Int(1) Variable("temp.2")
JumpIfZero Variable("temp.2") "_and_false_3"
Binary Divide Int(1) Int(0) Variable("temp.5")
JumpIfZero Variable("temp.5") "_and_false_3"
Copy Int(1) Variable("temp.6")
Jump "_and_end_4"
Label "_and_false_3"
Copy Int(0) Variable("temp.6")
Label "_and_end_4"
JumpIfNotZero Variable("temp.6") "_or_true_0"
Copy Int(0) Variable("temp.7")
Jump "_or_end_1"
Label "_or_true_0"
Copy Int(1) Variable("temp.7")
Label "_or_end_1"
Return Variable("temp.7")
Return Int(0)
you will note how very inefficient this is, for example the first line says
JumpIfNotZero Int(0) "_or_true_0"
This is jump never going to be executed, “if 0 is not 0”! I assume we will improve this in part III of the book ‘Optimizations’. That adventure awaits me.
Notice how the TACKY code is self contained, it could be written to a file and processed by a separate program. In later chapters I wondered (and still do) about writing a TACKY interpreter. That would make debugging the front end a lot easier. It would be a fun project.
MASM differences
This is when we need to start worrying about the operand size differences. The setxx instructions (page 83) in gcc speak are easy since the target is always a byte. In MASM speak you have to tell it the size, up till now everything was 4 bytes so it was easy, not so much now. Here is that start of the code generated for the above TACKY
push rbp
mov rbp, rsp
sub rsp, 16
mov r11d, 0
cmp r11d, 0
jne _or_true_0
mov r11d, 0
cmp r11d, 1
mov DWORD PTR[rbp-4], 0
setg BYTE PTR[rbp-4]
cmp DWORD PTR[rbp-4], 0
je _and_false_3
Till now I was blindly emitting DWORD PTR now I have to know the size and emit the correct PTR prefix
When I finish a chapter I keep saying to myself, “now create a Hack CPU backend”. It will be much easier to do it when I am at a primitive stage, like where I am now. But no, I keep saying, “just one more chapter…”
Anyway on to, woohoo, local variables
Leave a comment