References
A Java introduction
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
software.
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
Programming with the goto
- There is no while in machine language
- Programming education in the old days
- Linus Torvalds on the
goto
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 function
so that that neither array assignment uses
the brackets. We’re trying for the most
machine-like implementation. This means placing a cast to
void * for table
in the second array assignment.
This is a two line change, but you’ll probably need to follow the instructor to figure it would.
Gotos
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
Yes, the 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
if—else.
First, apply this transformation to the
if in the fill_collatz_table routine.
This is probably your first label and your first goto.
Be sure to compile and run your program before proceeding.
Next apply the rule for translating the
if—else in collatz.
Imagine the spaghetti
code we used to write in our introductory programming courses!
When the if’s are nested, the spaghetti gets
very tangled.
The for
Let’s replace that
for in fill_collatz_table
with a while.
You’ll find this rule about 70% of the way through
the
goto handout.
Sometimes this transformation is mentioned in the first programming course.
Again, compile and run before plunging on.
The while
This is the hard one. Once you add the backward branching goto,
it gets particular messy.
Go to the discussion of the
while in the handout.
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
the handout.
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 while,
which used to be a for,
in fill_collatz_table.
Three significant instruction sets
RISC
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
x.
Storing variables in registers, rather than memory, greatly improve performance.
An integer array index, such as V[i] requires,
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:i<<2. - The array offset is added to
the array pointer to obtain a reference to the element location,
&A[i], that is&A*i. - A load instruction is used to obtain
A[i].
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
$a0 to $a3 are used to pass arguments and
$v0 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
many options
for the ADD instruction.
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.
_tmp0to_tmp3— temporary registers_arg0to_arg3— argument registers_ret0to_ret0— return registers
Starting by downloading and expanding this archive.
By the way, this is the first time I have tried this lab. It might be rough!
Subtask One
Replace the regular array accesses, such as X[i] with
pointer-based accesses, such as *(X+i) with
Subtask Two
Replace the
for in fill_collatz_table with
a while.
Subtask Three
Replace the
if–else
in collatz and the
if in
fill_collatz_table with
simple if statements using the goto.
Subtask Four
Replace the
while’s in
collatz and fill_collatz_table with
if’s and goto’s.
Use the second rule for translating the while
in the
C programming
with the goto handout. This is the one with the
test at the end.
Subtask Five
This will will simulate the argument passing with “registers”.
We’ll start with the call to collatz.
Start by changing the header of
collatz to the following
void collatz(void)
Now modify collatz to receive its argument in
“register” _arg0 and return its result
in “register” _ret0.
These registers are defined in the include file
pseudo_regs.h .
This means replacing n with _arg0
and count with _ret0.
You also need to modify fill_collatz_table to pass its
argument in _arg0 and receive its result
in _ret0.
This is the real world of assembly language programming.
Subtask Six
Another problem with real world assembly language programming is that you must store the result of each operation into a register. This is bit hard to explain, so watch only as we perform this operation. We will also do a few optimizations to avoid multiplication and division.
Subtask Seven
So what happens when we load up _arg0 in
main to call fill_collatz_table
and then load up _arg0 in
fill_collatz_table to call collatz.
The solution involves a stack.
You’ll need to also watch this one.