------------------------------------ - Simple Code Generation Example 1 - - (based on an old grammar) - ------------------------------------ Source code: { string n n = "ALAN" print(n) } $ string n makes an entry into the heap temp table, aliasing n with location t0. That's about all we can do now since we don't yet know where the heap will begin. n = "ALAN" is where we have to make a choice to either (1) write the immutable string literal into the runtime image and use more heap memory should we alter its value; or (2) generate the op codes to load and store the ASCII values of the string literal, which creates more code but allows us to make the string mutable and reuse its heap memory in circumstances where its redefined value is equal or shorter in length. For this example, let's take the first option, though there is nothing wrong with the second choice. Update the heap table with the new value of n. ("ALAN") print(n) Finally we can generate some code. A0 t0 A2 02 FF 00: A0 t0 A2 02 FF .. .. .. 08: .. .. .. .. .. .. .. .. We're at the end of the code, so add a BRK. 00: A0 t0 A2 02 FF 00 .. .. 08: .. .. .. .. .. .. .. .. We can begin the heap area at 0x06 because there is no stack space in this tiny example. If there were stack-allocated variables, we'd have to move the beginning of the heap to just after the end of the stack area. Backpatch the heap start value into the code. 00: A0 06 A2 02 FF 00 .. .. Note that we used only one byte of the address here. This 08: .. .. .. .. .. .. .. .. is an inconsistency in the CPU simulation. It's Alan's fault. Now write the string literal into the heap. We'll null-terminate our strings, so "ALAN" takes five (5) bytes: A, L, A, N, null. A = ASCII 65 base 10 or 41 in hex L = 0x4C A = 0x41 N = 0x4E null = 00 00: A0 06 A2 02 FF 00 41 4C 08: 41 4E 00 .. .. .. .. .. And we're done. Looking at it as a stream: A0 06 A2 02 FF 00 41 4C 41 4E 00 Try that in an OS on our class web site.