689 lines
18 KiB
HTML
689 lines
18 KiB
HTML
<html>
|
|
<head>
|
|
<title>Jasmin User Guide</title>
|
|
<link href="style.css" rel="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<table>
|
|
<tr><td width=550>
|
|
<center>
|
|
<p><img src=jasmin_icon.jpg></p>
|
|
<p>
|
|
<div class="h1">JASMIN USER GUIDE</div>
|
|
Jonathan Meyer, July 1996
|
|
</p>
|
|
</center>
|
|
|
|
<h1>About This Document</h1>
|
|
|
|
This guide describes the rules and syntax used in Jasmin, and
|
|
how to run Jasmin. Note that this document doesn't
|
|
explain the Java Virtual Machine itself, or give syntax notes for
|
|
every instruction known to Jasmin. See the Java Virtual Machine specification
|
|
for more information on the JVM.<p>
|
|
|
|
<h1>What is Jasmin?</h1>
|
|
|
|
<p>
|
|
Jasmin is an assembler for the Java Virtual Machine. It takes
|
|
ASCII descriptions of Java classes, written in a simple
|
|
assembler-like syntax using the Java Virtual
|
|
Machine instruction set. It converts them into binary Java class files,
|
|
suitable for loading by a Java runtime system.<p>
|
|
</p>
|
|
<p>
|
|
Jasmin was originally created as a companion to the book "Java Virtual Machine",
|
|
written by Jon Meyer and Troy Downing and published by O'Reilly Associates. The
|
|
book is now out of print. Jasmin survives as a SourceForge Open Source project.
|
|
</p>
|
|
|
|
<h1>Jasmin Design</h1>
|
|
|
|
<p>
|
|
Jasmin is designed as a simple assembler. It has a clean easy-to-learn
|
|
syntax with few bells and whistles. Where possible, Jasmin adopts a
|
|
one-to-one mapping between its syntax and the conventions followed by Java class files.
|
|
For example, package names in Jasmin are delimited with the '/' character
|
|
(e.g. "java/lang/String") used by the class file format, instead
|
|
of the '.' character (java.lang.String) used in the Java language.</p>
|
|
|
|
<p>
|
|
The Jasmin assembler does little compile-time processing or
|
|
checking of the input code. For example, it doesn't check that
|
|
classes you reference actually exist, or that your type descriptors are
|
|
well formed. Jasmin also lacks many of the feautures
|
|
found in full macro assemblers. For example, it doesn't
|
|
inline mathematical expressions, perform variable
|
|
substitutions, or support macros.</p>
|
|
|
|
<p>
|
|
On the other hand, using Jasmin you can quickly try out nearly
|
|
all of the features of the Java Virtual Machine, including
|
|
methods, fields, subroutines, exception handlers, and so on.
|
|
The Jasmin syntax is also readable and compact.</p>
|
|
|
|
<h1>Running Jasmin</h1>
|
|
<p>
|
|
The <code>jasmin.jar</code> file is an executable JAR file that runs Jasmin.
|
|
For example:</p>
|
|
|
|
<pre><strong> java -jar jasmin.jar myfile.j</strong></pre>
|
|
|
|
<p>assembles the file "myfile.j". Jasmin looks at the
|
|
<code>.class</code> directive contained in the file to
|
|
decide where to place the output class file. So if myfile.j starts
|
|
with:</p>
|
|
|
|
<pre>
|
|
.class mypackage/MyClass
|
|
</pre>
|
|
|
|
<p>then Jasmin will place the output class file "MyClass.class" in the
|
|
subdirectory "mypackage" of the current directory. It will create the
|
|
mypackage directory if it doesn't exist.</p>
|
|
|
|
<p>You can use the "-d" option to tell jasmin to place the output
|
|
in an alternative directory. For example,</p>
|
|
|
|
<pre><strong> java -jar jasmin.jar -d /tmp myfile.j </strong></pre>
|
|
|
|
<p>will place the output in /tmp/mypackage/MyClass.class.</p>
|
|
|
|
<p>Finally, you can use the "-g" option to tell Jasmin to include
|
|
line number information (used by debuggers) in the resulting
|
|
.class file. Jasmin will number the lines in the Jasmin source
|
|
file that JVM instructions appear on. Then, if an error occurs,
|
|
you can see what instruction in the Jasmin source caused the error.
|
|
Note that specifying "-g" causes any .line directives within the
|
|
Jasmin file to be ignored.
|
|
</p>
|
|
|
|
<h1>Statements</h1>
|
|
|
|
<p>Jasmin source files consists of a sequence of newline-separated statements.
|
|
There are three types of statement: </p>
|
|
|
|
<ul>
|
|
<li>directives
|
|
<li>instructions
|
|
<li>labels
|
|
</ul>
|
|
|
|
<p>
|
|
Directives and instructions can take <i>parameters</i>. These parameters
|
|
are placed on the same line as the directive or instruction,
|
|
separated by spaces.</p>
|
|
|
|
<h3>Directives</h3>
|
|
|
|
<p>
|
|
Directive statements are used to give Jasmin meta-level information.
|
|
Directive statements consist of a directive name, and then zero or more
|
|
parameters separated by spaces, then a newline.</p>
|
|
|
|
<p>
|
|
All directive names start with a "." character. The directives in Jasmin are:</p>
|
|
|
|
<pre>
|
|
.catch .class .end .field .implements .interface .limit .line
|
|
.method .source .super .throws .var
|
|
</pre>
|
|
|
|
<p>
|
|
Some example directive statements are:</p>
|
|
|
|
<pre>
|
|
.limit stack 10
|
|
|
|
.method public myMethod()V
|
|
|
|
.class Foo
|
|
</pre>
|
|
|
|
<p>
|
|
The parameters used by each directive are described in more detail
|
|
later in the document.</p>
|
|
|
|
<h3>Instructions</h3>
|
|
|
|
<p>
|
|
An instruction statement consists of an instruction name, zero or
|
|
more parameters separated by spaces, and a newline.</p>
|
|
|
|
<p>
|
|
Jasmin uses the standard mnemonics for JVM opcodes as instruction names.
|
|
For example, aload_1, bipush and iinc are all Jasmin instruction names.</p>
|
|
|
|
<p>
|
|
Here are some examples of instruction statements:</p>
|
|
|
|
<pre>
|
|
ldc "Hello World"
|
|
iinc 1 -1
|
|
bipush 10
|
|
</pre>
|
|
|
|
<p>
|
|
</p>See <a href="instructions.html">Jasmin Instructions</a> for more details on
|
|
the syntax of instructions in Jasmin.</p>
|
|
|
|
|
|
<h3>Labels</h3>
|
|
|
|
<p>
|
|
</p>A Jasmin label statement consists of a name followed by a ':', and a newline.
|
|
For example:</p>
|
|
|
|
<pre>
|
|
Foo:
|
|
|
|
Label:
|
|
</pre>
|
|
|
|
<p>Label names cannot start with a numeric digit, and cannot contain
|
|
any of the special characters:</p>
|
|
|
|
<pre>
|
|
= : . " -
|
|
</pre>
|
|
|
|
<p>
|
|
You cannot use directive names or instruction names as labels. Other
|
|
than that, there are few restrictions on label names.
|
|
For example, you could use the label:</p>
|
|
|
|
<pre>
|
|
#_1:
|
|
</pre>
|
|
|
|
<p>
|
|
Labels can only be used within method definitions. The names are
|
|
local to that method.</p>
|
|
|
|
<h1>The Jasmin Tokenizer</h1>
|
|
|
|
<p>
|
|
Jasmin tokenizes its input stream, splitting the stream into tokens
|
|
by looking for whitespace characters (spaces, tabs and newlines).
|
|
The tokenizer looks for:</p>
|
|
|
|
<ul>
|
|
<li>directive names
|
|
<li>instruction names
|
|
<li>labels
|
|
<li>comments
|
|
<li>type descriptor names
|
|
<li>class names
|
|
<li>numbers and quoted strings
|
|
<li>etc.
|
|
</ul>
|
|
|
|
<p>
|
|
The rules used by the tokenizer are described below:</p>
|
|
|
|
<h3>Comments</h3>
|
|
|
|
<p>
|
|
A comment is a token that starts with a ';' character, and
|
|
terminates with the newline character at the end of the line. </p>
|
|
|
|
<p>
|
|
Note that the semicolon must be preceded by a whitespace character (a space, tab, newline), i.e.
|
|
embedded semicolons are ignored. For example,</p>
|
|
|
|
<pre>
|
|
abc;def
|
|
</pre>
|
|
|
|
<p>
|
|
is treated as a single token "abc;def", and</p>
|
|
|
|
<pre>
|
|
Ljava/lang/String;
|
|
</pre>
|
|
|
|
<p>
|
|
is the token "Ljava/lang/String;", whereas</p>
|
|
|
|
<pre>
|
|
foo ; baz ding
|
|
</pre>
|
|
|
|
<p>
|
|
is the token "foo" followed by a comment "baz ding".</p>
|
|
|
|
<h3>Numbers and Strings</h3>
|
|
|
|
<p>
|
|
In Jasmin, only simple decimal and integer numeric formats are
|
|
recognized. Floats in scientific or exponent format are not yet
|
|
supported. Character codes and octal aren't currently supported either. This
|
|
means you can have:</p>
|
|
|
|
<pre>
|
|
1, 123, .25, 0.03, 0xA
|
|
</pre>
|
|
|
|
<p>
|
|
but not</p>
|
|
|
|
<pre>
|
|
1e-10, 'a', '\u123'
|
|
</pre>
|
|
|
|
<p>
|
|
Quoted strings are also very basic. The full range of
|
|
backslash escape sequences are not supported yet, although "\n" and "\t"
|
|
are.</p>
|
|
|
|
<h3>Class Names</h3>
|
|
|
|
<p></p>Class names in Jasmin should be written using the Java class file format
|
|
conventions, so java.lang.String becomes java/lang/String.</p>
|
|
|
|
|
|
<h3>Type Descriptors</h3>
|
|
|
|
<p>
|
|
Type information is also written as they appear in class files (e.g.
|
|
the descriptor I speficies an integer, [Ljava/lang/Thread; is an
|
|
array of Threads, etc.).</p>
|
|
|
|
<h3>Methods</h3>
|
|
|
|
<p>
|
|
Method names are specified using a single token, e.g.</p>
|
|
|
|
<pre>
|
|
java/io/PrintStream/println(Ljava/lang/String;)V
|
|
</pre>
|
|
|
|
<p>
|
|
is the method called "println" in the class java.io.PrintStream, which
|
|
has the type descriptor "(Ljava/lang/String;)V" (i.e. it takes a String
|
|
and returns no result). In general, a method specification
|
|
is formed of three parts: the characters before the last '/' form the class
|
|
name. The characters between the last '/' and '(' are the method name. The
|
|
rest of the string is the type descriptor for the method.</p>
|
|
|
|
<pre>
|
|
foo/baz/Myclass/myMethod(Ljava/lang/String;)V
|
|
--------------- ---------------------
|
|
| -------- |
|
|
| | |
|
|
class method descriptor
|
|
|
|
</pre>
|
|
|
|
<p>
|
|
As another example, you would call the Java method: </p>
|
|
|
|
<pre>
|
|
class mypackage.MyClass {
|
|
int foo(Object a, int b[]) { ... }
|
|
}
|
|
</pre>
|
|
|
|
<p>
|
|
using:</p>
|
|
|
|
<pre>
|
|
invokevirtual mypackage/MyClass/foo(Ljava/lang/Object;[I)I
|
|
</pre>
|
|
|
|
<h3>Fields</h3>
|
|
|
|
<p>
|
|
Field names are specified in Jasmin using two tokens, one giving the name
|
|
and class of the field, the other giving its descriptor. For example:</p>
|
|
|
|
<pre>
|
|
getstatic mypackage/MyClass/my_font Ljava/lang/Font;
|
|
</pre>
|
|
|
|
<p>
|
|
gets the value of the field called "my_font" in the class mypackage.MyClass.
|
|
The type of the field is "Ljava/lang/Font;" (i.e. a Font object).</p>
|
|
|
|
<h1>FILES</h1>
|
|
|
|
<p>
|
|
Jasmin files start by giving information on the class
|
|
being defined in the file - such as the name of the
|
|
class, the name of the source file that the class originated from,
|
|
the name of the superclass, etc.</p>
|
|
|
|
<p>
|
|
Typically, a Jasmin file starts with the three directives:</p>
|
|
|
|
<pre>
|
|
.source <source-file>
|
|
.class <access-spec> <class-name>
|
|
.super <class-name>
|
|
</pre>
|
|
|
|
<p>
|
|
For example, the file defining MyClass might start with the directives:</p>
|
|
|
|
<pre>
|
|
.source MyClass.j
|
|
.class public MyClass
|
|
.super java/lang/Object
|
|
</pre>
|
|
|
|
<h3>.source directive</h3>
|
|
|
|
<p>
|
|
The .source directive is optional. It specifies the
|
|
value of the "SourceFile" attribute for the class
|
|
file. (This is used by Java to print out debugging info
|
|
if something goes wrong in one of the methods in the class).
|
|
If you generated the Jasmin file automatically (e.g. as the result of
|
|
compiling a file written in another syntax) you should use the .source
|
|
directive to tell Java the name of the originating file. Note that
|
|
the source file name should not include any pathname. Use "foo.src"
|
|
but not "/home/user/foo.src".</p>
|
|
|
|
<p>
|
|
If no .source directive is given, the name of the Jasmin
|
|
file you are compiling is used instead as the SourceFile attribute
|
|
instead.</p>
|
|
|
|
<h3>.class and .super directives</h3>
|
|
|
|
<p>
|
|
The .class and .super directive tell the JVM the name of this
|
|
class and its superclass. These directives take parameters as
|
|
follows:
|
|
</p>
|
|
|
|
<dl>
|
|
<dt><class-name></dt>
|
|
<dd>is the full name of the class, including
|
|
any package names. For example foo/baz/MyClass.<p>
|
|
</dd>
|
|
|
|
<dt><access-spec></dt>
|
|
<dd>defines access permissions and other attributes for
|
|
the class. This is a list of zero or more of the following
|
|
keywords:<p>
|
|
<dl><dd>
|
|
public, final, super, interface, abstract
|
|
</dl>
|
|
</dl>
|
|
|
|
<h3>.interface directive</h3>
|
|
|
|
<p>
|
|
Note that, instead of using the directive .class,
|
|
you can alternatively use the directive .interface. This has
|
|
the same syntax as the .class directive, but indicates that the Jasmin file
|
|
is defining a Java interface. e.g.</p>
|
|
|
|
<pre>
|
|
.interface public foo
|
|
</pre>
|
|
|
|
<h3>.implements directive</h3>
|
|
|
|
<p>
|
|
After .source, .class and .super, you can list the
|
|
interfaces that are implemented by the class you are defining, using
|
|
the .implements directive. The syntax of .implements is:</p>
|
|
|
|
<pre>
|
|
.implements <class-name>
|
|
</pre>
|
|
<p>
|
|
where <class-name> has the same format as was used by .class and .super.
|
|
For example:</p>
|
|
|
|
<pre>
|
|
.class foo
|
|
.super java/lang/Object
|
|
.implements Edible
|
|
.implements java/lang/Throwable
|
|
</pre>
|
|
|
|
<h1>Field Definitions</h1>
|
|
|
|
<p>
|
|
After the header information, the next section of the Jasmin file
|
|
is a list of field definitions.</p>
|
|
|
|
<p>
|
|
A field is defined using the .field directive:</p>
|
|
|
|
<pre>
|
|
.field <access-spec> <field-name> <descriptor> [ = <value> ]
|
|
</pre>
|
|
|
|
<p>
|
|
where:</p>
|
|
|
|
<dl>
|
|
<dt><access-spec>
|
|
<dd>is one of the keywords:
|
|
<dl><dd>
|
|
public, private, protected, static, final,
|
|
volatile, transient
|
|
</dl>
|
|
</dl><p>
|
|
|
|
<dt><field-name>
|
|
<dd>is the name of the field.<p>
|
|
|
|
<dt><descriptor>
|
|
<dd>is its type descriptor.<p>
|
|
|
|
<dt><value>
|
|
<dd>is an integer, a quoted string or a decimal number, giving the
|
|
initial value of the field (for final fields).<p>
|
|
</dl>
|
|
|
|
<p>
|
|
For example, the Java field definition:</p>
|
|
|
|
<pre>
|
|
public int foo;
|
|
</pre>
|
|
|
|
<p>
|
|
becomes</p>
|
|
|
|
<pre>
|
|
.field public foo I
|
|
</pre>
|
|
|
|
<p>
|
|
whereas the constant:</p>
|
|
|
|
<pre>
|
|
public static final float PI = 3.14;
|
|
</pre>
|
|
|
|
<p>
|
|
becomes</p>
|
|
|
|
<pre>
|
|
.field public static final PI F = 3.14
|
|
</pre>
|
|
|
|
<h1>Method Definitions</h1>
|
|
|
|
<p>
|
|
After listing the fields of the class, the rest of the Jasmin file lists
|
|
methods defined by the class.</p>
|
|
|
|
<p>
|
|
A method is defined using the basic form:</p>
|
|
|
|
<pre>
|
|
.method <access-spec> <method-spec>
|
|
<statements>
|
|
.end method
|
|
</pre>
|
|
|
|
<p>
|
|
where:</p>
|
|
|
|
<dl>
|
|
<dt><access-spec>
|
|
<dd>is one of the keywords: public, private, protected, static, final,
|
|
synchronized, native, abstract<p>
|
|
|
|
<dt><method-spec>
|
|
<dd>is the name and type descriptor of the method.<p>
|
|
|
|
<dt><statements>
|
|
<dd>is the code defining the body of the method.<p>
|
|
</dl>
|
|
|
|
<p>
|
|
Method definitions cannot be nested. Also, Jasmin does not
|
|
insert an implicit 'return' instruction at the end of a method. It is
|
|
up to you to ensure that your methods return cleanly. So
|
|
the most basic Jasmin method is something like:</p>
|
|
|
|
<pre>
|
|
.method foo()V
|
|
return ; must give a return statement
|
|
.end method
|
|
</pre>
|
|
|
|
<h3>Method Directives</h3>
|
|
|
|
<p>
|
|
The following directives can be used only within method definitions:</p>
|
|
|
|
<dl>
|
|
<dt><pre>.limit stack <integer></pre><p>
|
|
<dd>Sets the maximum size of the operand stack
|
|
required by the method.
|
|
|
|
<dt><pre>.limit locals <integer></pre><p>
|
|
<dd>Sets the number of local variables
|
|
required by the method.
|
|
|
|
<dt><pre>.line <integer></pre><p>
|
|
<dd>This is used to tag the subsequent
|
|
instruction(s) with a line number. Debuggers use this information,
|
|
together with the name of the source file (see .source above)
|
|
to show at what line in a method things went wrong. If you are
|
|
generating Jasmin files by compiling a source file,
|
|
this directive lets you indicate what line
|
|
numbers in the source file produced corrosponding Jasmin
|
|
instructions. For example:
|
|
|
|
<pre>
|
|
.method foo()V
|
|
.line 5
|
|
bipush 10 // these instructions generated from line 5
|
|
istore_2 // of the source file.
|
|
.line 6
|
|
...
|
|
</pre>
|
|
|
|
<dt><pre>.var <var-number> is <name> <descriptor> from <label1> to <label2></pre><p>
|
|
<dd>The .var directive is used to define the name, type descriptor and scope of
|
|
a local variable number. This information is used by debuggers
|
|
so that they can be more helpful when printing out the values of local
|
|
variables (rather than printing just a local variable number, the
|
|
debugger can actually print out the name of the variable). For example:
|
|
|
|
<pre>
|
|
.method foo()V
|
|
.limit locals 1
|
|
|
|
; declare variable 0 as an "int Count;"
|
|
; whose scope is the code between Label1 and Label2
|
|
;
|
|
.var 0 is Count I from Label1 to Label2
|
|
|
|
Label1:
|
|
bipush 10
|
|
istore_0
|
|
Label2:
|
|
|
|
return
|
|
.end method
|
|
</pre>
|
|
|
|
<dt><pre>.throws <classname></pre><p>
|
|
<dd>Indicates that this method can throw
|
|
exceptions of the type indicated by <classname>.
|
|
e.g.
|
|
<pre>
|
|
.throws java/io/IOException
|
|
</pre>
|
|
|
|
This information isn't required by Java runtime systems,
|
|
but it is used by the Java compiler to check that methods
|
|
either catch exceptions they can cause, or declare
|
|
that they throw them.
|
|
|
|
<dt><pre>.catch <classname> from <label1> to <label2> using <label3></pre><p>
|
|
<dd>Appends an entry to the end of the exceptions table for the
|
|
method. The entry indicates that when an exception which is
|
|
an instance of <classname> or one of its subclasses is thrown
|
|
while executing the code between <label1> and <label2>, then
|
|
the runtime system should jump to <label3>. e.g.<p>
|
|
<pre>
|
|
.catch java/io/IOException from L1 to L2 using IO_Handler
|
|
</pre>
|
|
|
|
If classname is the keyword "all", then exceptions of any
|
|
class are caught by the handler.<p>
|
|
|
|
</dl>
|
|
|
|
<h3>Abstract Methods</h3>
|
|
|
|
<p>
|
|
To declare an abstract method, write a method with no body. e.g.</p>
|
|
|
|
<pre>
|
|
.method abstract myAbstract()V
|
|
.end method
|
|
</pre>
|
|
|
|
<p>
|
|
note that abstract methods can have .throws directives, e.g.</p>
|
|
|
|
<pre>
|
|
.method abstract anotherAbstract()V
|
|
.throws java/io/IOException
|
|
.end method
|
|
</pre>
|
|
|
|
<h1>Instructions</h1>
|
|
|
|
<p>
|
|
JVM instructions are placed between the <code>.method</code> and
|
|
<code>.end method</code> directives. VM instructions can take zero or more
|
|
parameters, depending on the type of instruction used. Some example
|
|
instructions are shown below:
|
|
</p>
|
|
|
|
<pre>
|
|
iinc 1 -3 ; decrement local variable 1 by 3
|
|
|
|
bipush 10 ; push the integer 10 onto the stack
|
|
|
|
pop ; remove the top item from the stack.
|
|
|
|
</pre>
|
|
|
|
<p>
|
|
See <a href="instructions.html">Jasmin Instructions</a> for more details on the syntax
|
|
of instructions in Jasmin.
|
|
</p>
|
|
|
|
<hr><address>Copyright (c) Jonathan Meyer, July 1996</address>
|
|
<hr>
|
|
<a href="http://jasmin.sourceforge.net">Jasmin Home</a> |
|
|
<a href="http://www.cybergrain.com">Jon Meyer's Home</a>
|
|
|
|
</td></tr></table>
|
|
</body>
|
|
</html>
|