CSCI 235 — pre-assembly

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

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.

  1. y, is loaded into one register.
  2. z, is loaded into another register.
  3. The two registers are added.
  4. 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.

  1. The array pointer, V, is loaded into a register.
  2. The array index, i, is loaded into a register.
  3. The array offset, i*4 is computed by multiplying the array index by four. This is done with a left shift: i<<2.
  4. The array offset is added to the array pointer to obtain a reference to the element location, &A[i], that is &A*i.
  5. 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.

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.