Programming with the goto
- There is no while in machine language
- Programming education in the old days
- Linus Torvalds on the
Stuff to do
Start by downloading a C project into your csci235 directory.
In your solution, do not modify collatz.c. Only change pa-collatz.c. That way you will always have a copy of a standard C program.
Pointers — How it is done
Using the “facts about arrays” in the
C pointers page, transform
the two array element assignments in the
fill_collatz_table so that that neither assignment uses
the brackets. We’re trying for the most
machine-like implementation. This means using
void * in the second assignment.
Now we are heading back to programming in the 60’s.
Open the C programming with the
goto handout in another window.
The worse if
goto has been banned in Java and almost all
computer science courses.
However work your way down to the discussion of the
if and the
First, apply this transformation to the
if in the
This is probably your first label and your first
Be sure to compile and run your program before proceeding.
Now apply the rule for translating the
Imagine the spaghetti
code we used to write in our introductory programming courses!
if’s are nested, the spaghetti gets
Let’s replace that
You’ll find this rule about 70% of the way through
Sometimes this transformation is mentioned in the first programming course.
Again, compile and run before plunging on.
This is the hard one. Once you add the backward branching
it gets particular messy.
Go to the discussion of the
You will notice two transformation rules.
I suggest you use the second as it tends to be a little faster
and, of course, more complex!
You’ll find this rule about 60% of the way through
First apply the rule to the
while in the
collatz. Do not think too hard!
Just apply the rule.
Test before proceeding.
And finally apply the rule to the remaining
which used to be a
What about Java?
Download a tar-gzip of the collatz program written in Java. Extract it and then compile and run it with the following commands. (Isn’t the inconsistency odd.)
javac edu/unca/csci235/Collatz.java java edu.unca.csci235.Collatz
Run a couple of commands using javap, the Java disassembler, to view and save the compiled Java bytecode.
javap edu.unca.csci235.Collatz javap -c edu.unca.csci235.Collatz | more javap -c edu.unca.csci235.Collatz > Collatz.java-bytecode
Take a look at A Java Programmer’s Guide to Byte Code.
The Java Virtual Machine is a stack-based computer that is simulated in
Open up your Collatz.java-bytecode
and go to the
collatz routine. (It will be around address 262.)
Add some ”comments“ to your code describing what is happen.
It should start with something like this:
static int collatz(int); Code: 0: iconst_0 [ 0 ] 1: istore_1 [ ] Store in count 2: iload_0 [ n ] 3: iconst_1 [ n 1 ] 4: if_icmpeq 33 [ ] Jumps if n == 1
Three significant instruction sets
Modern Reduced Instruction Set Computers have fairly simple instruction sets. There are load/store instructions that can move the memory location to/from a register. Generally these instructions index memory relative to a register, which can be a stack or frame pointer, a global offset (this one is hard), or a register containing a C pointer.
An assignment statement, such as
x = y + z
requires, in the worse case, four instructions.
y, is loaded into one register.
z, is loaded into another register.
- The two registers are added.
- The result is stored in
Storing variables in registers, rather than memory, greatly improve performance.
An integer array index, such as
in the worse case, five instructions.
- The array pointer,
V, is loaded into a register.
- The array index,
i, is loaded into a register.
- The array offset,
i*4is computed by multiplying the array index by four. This is done with a left shift:
- The array offset is added to
the array pointer to obtain a reference to the element location,
&A[i], that is
- A load instruction is used to obtain
Of course, most compilers do much better by keeping
&A[i] in a register.
Branches are performed with the control flow instructions listed
in Sample PIC32 (MIPS) instructions
Finally, note that the ABI (application binary interface) specifies
how registers are used. Note that
$a3 are used to pass arguments and
$v1 are used to return results.
IBM System 360
Look at a copy of the
IBM System/360 Green card stored at the
Computer History Museum.
Notice that the
LD instruction could add two registers
and a displacement to obtain an address.
However, the displacement is only twelve bits long.
The Intel x86-64 instruction set
The Intel x86-64 is the the ultimate
CISC, Complex Instruction Set Computer.
Take a look at the
x86-64 instruction set.
Go on to a summary of the
We will return to this in Chapter 3. We will return to this in CSCI 335.
The assigned task
Take a look at the file pseudo_regs.h . It defines several fake registers that we will use to simulate an assembly language program.
_it3— temporary registers
_ia3— argument registers
_ir1— return registers
Hopefully, you have a copy of the pc-collatz.c program we wrote last week. If you don’t, you can download this one which contains low-level control structures.
By the way, this is the first time I have tried this lab. It might be rough!
count with the return ”register“
n with the argument ”register“
This one is tricky.
replace complex statements like
_ia0 = 3 * _ia0 + 1 ;
with sequences of statements where the right-hand side of an assignment contains no more than one arithmetic operations and the operands to arithmetic operations are registers. This means that the assignment seen above must be replaced with three assignments. You will need to use a temporary register
_it0 to do this.
This one is messy.
Start by changing the header of
collatz to the following
fill_collatz_table to pass its
_ia0 and receive its result
This is the real world.
This one is huge because it repeats all the previous subtasks, but
fill_collatz_table so that it receives its arguments in
Notice, that it must be
_pa0 rather than
_ia0 to make the C compiler happy!
If you look at a pseudo_regs.h, you
will see how the magic of the
union makes this possible.
i with a temporary register.
You will also need to modify
print_table to pass arguments
fill_collatz_table in the appropriate registers.
However, the really tricky thing is that
will need to save copies of its argument and and temporary registers
collatz. You will do this with code
similar to the following before the call:
saveTemp0 = _it0 ;
and similar to the following after the call:
_it0 = saveTemp0 ;
Such is the life of an assembly language programmer.
There will also be some very messy C to handle the array accesses. Hint:
_it1 = _it0 << 2 ; _pt1 = (void *)(((unsigned long)(void *)_pa0) + _it1) ; *((int *)_pt1) = _ir0 ;