The Machine Language of the JVM

Questions and Activities
Sections:
    How to look at assembly code
    Simple machine architecture (at first glance).
    Arithmetic expressions
        Putting integer constants onto the stack
        Calculations


How to look at assembly code

  1. Set up the Java environment.
  2. Copy  and compile it by % javac Demo1.java.Then run the program by naming the class file (you don't type the .class suffix: % java Demo1.
  3. Run the disassembler by % javap -c -v Demo1.java
  4. Write a simple for loop to add up the numbers from 1 to 100 and print out the result.   Dissassemble the program and see what you get. (Note: reading data into a Java program is not a simple readln(my_data).  This is due to the i/o objects Java provides.)

Simple Machine Architecture

  1. Most instructions use one byte to refer to a local variable.  How many local varibles can be addressed?
  2. But there can be two bytes to refer to a local variable!  How many local variables can there be?
  3. Likewise, the index to a constant in the pool is one or two bytes.  How many constants can there be in a class?
  4. Are these reasonable numbers?
  5. Visit the Jasmin site  to see the detailed description of  the machine instructions.  What is the opcode for iadd?

Arithmetic Expressions

Putting Integer Constants onto the stack

  1. Name some one byte instructions.
  2. What is the machine instruction for pushing -1 onto the stack?
  3. What is largest integer you can use in bipush? In sipush?
  4. Show all the ways (most of them inefficient) you can push the consant 4 onto the stack?
  5. Why have many different assembler instructions that can do the same thing?
  6. Besides integers we have floating point numbers which are also represented by 32 bits. What do the instructions fconst_2 and fload_0 and fstore_0 accomplish?
  7. Why are there are separate instructions for working with floating point numbers?  Think "safe code".
  8. A taste of things to come: Java and the JVM treat floating point numbers much differently than integers.  For example, if you try  x = (float)1.0; where x is an integer, will get the message:  Incompatible type for =. Explicit cast needed to convert float to int.

  9.       x = (float) 1.0;
            ^   (I typecasted since 1.0 is of type double which is represented in 64 bits; it adds another level of complexity that I don't yet want to discuss.)
    You can't mix and match unless you tell the compiler that you want to (by  x = (int) 1.0;).

    Suppose you wanted to get around this at the JVM level and do the following nasty thing:
       fconst_1
       istore_0  which tries to save 1.0 as an integer.  If you try to execute this (using JDK 1.2) you will get
    Exception in thread "main" java.lang.VerifyError: (class: Jas1, method: main signature: ([Ljava/lang/String;)V) Expecting to find integer on stack
    What happened?  When your code is loaded, the JVM verifier will first check to see if it will behave properly before it executes it.  And saving a float as an integer is not a good idea.
    For those who don't care, you can run the program in Java 1.1 with the -noverify option.  Then you'll get what you deserve; I hope you don't have to reboot the computer.  This "feature" has been removed from 1.2 and later versions.
     

Calculations
  1. Suppose the JVM did not have the instruction ineg?  How could JVM still acomplish this? Then why does this instruction exist?
  2. Suppose the JVM did not have the instruction irem?  How could JVM still acomplish this?
Assume as in Demo1.java, local variables x, y, z, u, v, w correspond with 0 - 5.  Write expressions for the following.  You should not yet try to do any "tricks", so read the expression from left to right.
  1. x  = y - 100;
  2. u -= 10;
  3. v = (x + 4)*(y/9 + 11);
  4. w = (x << 5) * ( u >> 4);
  1. In Java we can define char ch = 'A';.  How does the JVM handle character data?  How does the  handle statements like int x = ch + 'B' + 1;.  To answer this question write a simple Java program with char declarations. Compile it and then look at the assembler code with javap. Note: charcter data is really Unicode which is represented as two bytes, but for this example you'll just one byte.

  2.  
  3. Logical instructions.  Manipulating the stack


Other sections to follow


© 2000 Carl. E. Bredlau

bredlauc@mail.montclair.edu