CC/jasmin/jasmin-2.4/docs/guide.html
Jeena Paradies 063194f8be first commit
2011-04-19 11:37:05 +02:00

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 &lt;source-file&gt;
.class &lt;access-spec&gt; &lt;class-name&gt;
.super &lt;class-name&gt;
</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>&lt;class-name&gt;</dt>
<dd>is the full name of the class, including
any package names. For example foo/baz/MyClass.<p>
</dd>
<dt>&lt;access-spec&gt;</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 &lt;class-name&gt;
</pre>
<p>
where &lt;class-name&gt; 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 &lt;access-spec&gt; &lt;field-name&gt; &lt;descriptor&gt; [ = &lt;value&gt; ]
</pre>
<p>
where:</p>
<dl>
<dt>&lt;access-spec&gt;
<dd>is one of the keywords:
<dl><dd>
public, private, protected, static, final,
volatile, transient
</dl>
</dl><p>
<dt>&lt;field-name&gt;
<dd>is the name of the field.<p>
<dt>&lt;descriptor&gt;
<dd>is its type descriptor.<p>
<dt>&lt;value&gt;
<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 &lt;access-spec&gt; &lt;method-spec&gt;
&lt;statements&gt;
.end method
</pre>
<p>
where:</p>
<dl>
<dt>&lt;access-spec&gt;
<dd>is one of the keywords: public, private, protected, static, final,
synchronized, native, abstract<p>
<dt>&lt;method-spec&gt;
<dd>is the name and type descriptor of the method.<p>
<dt>&lt;statements&gt;
<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 &lt;integer&gt;</pre><p>
<dd>Sets the maximum size of the operand stack
required by the method.
<dt><pre>.limit locals &lt;integer&gt;</pre><p>
<dd>Sets the number of local variables
required by the method.
<dt><pre>.line &lt;integer&gt;</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 &lt;var-number&gt; is &lt;name&gt; &lt;descriptor&gt; from &lt;label1&gt; to &lt;label2&gt;</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 &lt;classname&gt;</pre><p>
<dd>Indicates that this method can throw
exceptions of the type indicated by &lt;classname&gt;.
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 &lt;classname&gt; from &lt;label1&gt; to &lt;label2&gt; using &lt;label3&gt;</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 &lt;classname&gt; or one of its subclasses is thrown
while executing the code between &lt;label1&gt; and &lt;label2&gt;, then
the runtime system should jump to &lt;label3&gt;. 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>