Next:Negation
Up: Overview
Previous: What If It's Too Easy
Post Script
Depending upon how the material is taught, the entirety of the course material may be able to be finished before a semester is over. I personally anticipate that each lesson (of the 14) may be teachable in less than one standard lesson period (one week in the case of a 14 week semester), such that there's a lot of left over time at the tail portion of the semester.
After the Rex86 material has been finished, there is a great deal more that may be taught so that these novice programmers get some real, useful world experience. It is recommended that the C language be introduced, since the Rex86 instructions correspond fairly well to its capabilities, including its syntax for text (strings) and integer lists (int arrays).
The first step towards doing this is to introduce the memory model. Do this by abstracting it as a large one-dimenionsal list that can be accessed using indices, and each index is as fast to use as any other. Produce some example, diagrams, and circumstances to explain how the memory model works. Use the notation of "mem[num]" to specify the value stored in memory location "num". With this simple concept we can introduce the first program.
Write a C program that stores 7 in a variable, and then prints it out.
int main()
{
int a;
a = 7;
printf(a);
return 0;
}
In C, all code has to be in a function, which are just like the functions we used in Rex86. In this case we're using the function "main", which is always the function that C starts running first. Because C has a memory model, we don't have to worry about explicitly using registers. Instead, we just specify variables, such as "a" in this case, and C decides which register to use, if any. If it wants, C can instead use some memory location, like "mem[100]", to hold the value of variable "a".
Having C make decisions about how to allocate variables relieves us of having to decide how to use our registers. It also helps us keep track of what our intentions are concerning usage. For example, we declare in this code that "a" is an "int", or integer. Then C will make sure that we never misuse "a", by perhaps treating it as though it were text or an integer list. It is required that all variables be declared before they are used, and their type always has to be listed as part of their declaration. A declaration then consists of simply a type, followed by the variable name.
Once "a" is declared, using it is always the same, whether it is actually allocated as a register or a memory location. Then performing a = 7 is just like a MOV instruction. Although it looks superficially like an algebraic equality, it is really a movement of data from right to left, like "MOV AX,7". On the next line, "printf" will display a variable's value, although now we have to specify which variable we want printed, since we don't have an "AX" register to default to anymore. Finally "return 0" gives the return value of our "main" function, thus existing our program. Using 0 as a value means "no problems".
Further C concepts can be introduced in a similar fashion.
a += b; is just like ADD AX,BX
a -= b; is just like SUB AX,BX
a *= b; is just like MULT AX,BX
Though we don't have to strictly use mutator operations. We can also use arithmetic operations in expressions.
a = b + c;
Which is nearly the same as
MOV AX,BX
ADD AX,CX
Composition is made easier since we can use entire formulas in place of single values. For example,
a = b * c + d * 3;
Is much more concise than having to compute this formula one step at a time as in
MOV AX,BX
MULT AX,CX
MULT DX,3
ADD AX,DX
Also the expression version doesn't have the nasty side effect of making unintended modifications to other registers.
Other data types are easy to use as well.
char * a;
declares that "a" is to be used for text. "a" gets assigned text almost exactly the same way that POINT was used
a = "hello";
instead of
POINT AX,"hello"
And the same with integer lists
int * L;
declares that "L" is to be used for ints.
L = { 3, 4, 5 };
works just like
POINT AX,{ 3 4 5 }
Since we're using a memory model, we can access any element just as fast as any other. So getting the third element (index 2) doesn't require iterating past the first (index 0) and second (index 1) elements, For example:
int main()
{
int * L;
L = { 3, 4, 5 };
int x;
x = L[2];
printf(x);
x = L[0];
printf(x);
return 0;
}
Will print 5 and 3.
Next:Negation
Up: Overview
Previous: What If It's Too Easy
by dlong@progmatism.com. Plz don't copy kthx.