JVM Programming assignments JVM3-1, 3-2
Due: Wednesday, April 30 at class time
The JVM3
The JVM3 is an enhancement of the JVM2 that allows the user to work with integer arrays. The JVM3 is constructed by adding one new RAM and three new machine instructions to the JVM2. The three new instructions are the newarray, iaload, and iastore instructions, with opcodes 0xBC, 0x2E, and 0x4F, respectively.
Arrays in the JVM3 are stored in the heap, which is where dynamic data structures such as objects are stored in the real JVM (and in most other programming languages). In our case, the heap will be a new RAM that you need to create.
To access the heap, the JVM3 should use the "heap" register, which is 32 bits wide. The heap register should contain a pointer to (that is, the address of) the next available cell in the heap RAM for allocation to a new object. This heap register has already been added to the JVM2 machine that I gave to you for the previous project.
The newarray instruction is a 1-byte instruction that is used to allocate space on the heap for new integer arrays. (The newarray instruction in the real JVM is actually a 2-byte instruction and the second byte tells what kind of array to create. Since we are dealing with only integer arrays, we will use a simpler form of the newarray instruction.) This instruction pops the top value (call it n) off the stack and uses n as the size of the array (that is, the number of integers that can be stored in the array). It then allocates 4n bytes for the array (remember that each entry in the array is an integer that needs 4 bytes) from the heap starting at the location pointed to by the heap register and pushes on the stack the value of the heap register, which gives the address of the first array location (that is, the array slot with index 0). The newarray instruction will then need to increment the heap pointer by 4n so that the heap pointer again points to available heap space for the next new array object to be allocated.
In your JVM assembly language programs, the newarray instruction is typically followed by an istore instruction that stores the array pointer in a local variable.
The iaload instruction is a 1-byte instruction that pushes on the operand stack a value from the array. The iaload instruction pops the top value on the stack to use as the index into the array for the data that is to be pushed on the stack. The iaload instruction also pops the second-to-top value on the stack to use as a pointer to the start of the array (that is, the address of B[0], if B is the name of the array). For example, if the top of the operand stack contains a 3 and the second-to-top value on the stack contains a pointer to array B, then the iaload command pops those two values from the stack and pushes the value of B[3] on the stack.
The iastore instruction is a 1-byte instruction that stores the top value from the operand stack in an array. The second-to-top value on the stack gives the index into the array where the top stack value is to be stored. The third-to-top value on the stack contains a pointer to (that is, the address of) the start of the array (that is, the address of B[0], if B is the name of the array). For example, if the top of the operand stack contains a 5, the second-to-top value is a 3 and the third-to-top value is the starting address of array B in the Heap, then the iastore command will pop the three values from the stack and store the value 5 in B[3].
Here is a sample JVM3 program that creates an array of length 4, stores a 9 in location B[3] and then pushes the value of B[3] on top of the stack. It assumes that the sp and lv registers are initialized to 0 and so there is already a slot on the stack for the local variable with index 0.
;; create the new array B of length 4
bipush 4
;push 4--the size of the array
newarray ;create array B of length 4
istore 0 ;store the array B pointer in local var 0
;;
store 9 in B[3]
iload 0 ;load array B
pointer from local var 0
bipush 3 ;push index 3
bipush 9 ;push data 9
iastore
;store the value 9 in B[3]
;; load B[3] onto the operand stack
iload 0 ;load array B pointer from lv 0
bipush 3 ;push index 3
iaload
;load the value of B[3] onto the stack
stop
Exercise
JVM3-1
Step 1: Create the JVM3. You need to create the new Heap RAM and then create the newarray, iaload, and iastore instructions.
Step 2: Write a JVM3 program that reads in an integer n followed by n more integers. Your program stores the n integers in an array of size n in the heap. It then uses a findIndexOfMax function to help it find and output the largest of the n integers in the array. You may assume that n >= 1.
Details
public int findIndexOfMax(int n, int[]
B) {
int indexOfMax = 0; //the index of the largest value so far
for
(int j = 1; j < n; j++) {
if (B[j] > B[indexOfMax])
indexOfMax = j;
}
return indexOfMax;
}
Write a JVM3 program that reads in a positive integer n followed by n more integers. Your program stores the n integers in an array of size n in the heap. It then sorts the n integers in the array in place using the findIndexOfMax function from the preceding exercise and a SelectionSort subroutine. After it is done sorting, your program writes out the n integers from smallest to largest.
Details
General Notes
Please hand in a hard copy of your JVM3-1 and JVM3-2 assembly language code, create a folder called "JVM3.your-last-name(s)", drag a copy of your JVM3.cpu machine file and your two assembly code files into that folder and then zip up the folder and attach it to an email message to me.