Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JVM instruction ALOAD_0 in the 'main' method points to 'args' instead of 'this'?

Tags:

I am trying to implement a subset of Java for an academic study. Well, I'm in the last stages (code generation) and I wrote a rather simple program to see how method arguments are handled:

class Main {     public static void main(String[] args) {         System.out.println(args.length);     } } 

Then I built it, and ran 'Main.class' through an online disassembler I found at: http://www.cs.cornell.edu/People/egs/kimera/disassembler.html

I get the following implementation for the 'main' method: (the disassembled output is in Jasmin)

.method public static main([Ljava/lang/String;)V     .limit locals 1     .limit stack 2      getstatic   java/lang/System/out Ljava/io/PrintStream;     aload_0     arraylength     invokevirtual   java/io/PrintStream.println(I)V     return .end method 

My problem with this is:
1. aload_0 is supposed to push 'this' on to the stack (thats what the JVM spec seems to say)
2. arraylength is supposed to return the length of the array whose reference is on the top-of-stack

So according to me the combination of 1 & 2 should not even work.

How/why is it working? Or is the disassembler buggy and the actual bytecode is something else?

like image 376
ArjunShankar Avatar asked Jan 09 '11 19:01

ArjunShankar


People also ask

What type of instructions is supported by Java Virtual Machine?

A Java Virtual Machine instruction consists of a one-byte opcode specifying the operation to be performed, followed by zero or more operands supplying arguments or data that are used by the operation. Many instructions have no operands and consist only of an opcode.

Does JVM have registers?

The JVM has a program counter and three registers that manage the stack. It has few registers because the bytecode instructions of the JVM operate primarily on the stack. This stack-oriented design helps keep the JVM's instruction set and implementation small.

How is Java bytecode executed?

They can be executed by intepretation, just-in-time compiling, or any other technique that was chosen by the designer of a particular JVM. A method's bytecode stream is a sequence of instructions for the Java virtual machine. Each instruction consists of a one-byte opcode followed by zero or more operands.

How many Java opcodes are there?

Java bytecode is the instruction set of the Java virtual machine. Each bytecode is composed of one, or in some cases two bytes that represent the instruction (opcode), along with zero or more bytes for passing parameters. Currently, in Jan 2017, there are 205 opcodes in use out of 256 possible byte-long opcodes.


1 Answers

aload_0 is supposed to push 'this' on to the stack

Not quite … aload_0 reads the first reference argument (or, more generally, the first local reference variable) of the method and pushes it onto the stack.

In member functions, the first local variable happens to be the this reference.

But main is not a member function, it’s a static function so there is no this argument, and the true first argument of the method is args.

like image 124
Konrad Rudolph Avatar answered Oct 01 '22 23:10

Konrad Rudolph