javalin.org
JASM Specification
The goal of this document is to provide a specification for the Javalin Set of Macros (JASM) to enable Object Oriented Programming for Assembly Language. The intended audience is the developer responsible for creating or maintaiining versions of JASM macros compatible across a wide spectrum of assemblers.
Preprocessing
In order to provide a portable object framework the assembler being used must support the pre-processing of macro source files. It is these macros that the assembly language developer will use to build his or her application using the JASM oop methodology. Fortunately, all major assemblers today provide this capability.
Strings
In addition to supporting macro creation the assembler preprocessor must be able to provide string processing routines or macros that can parse macro argument strings. JASM requires support for string preprocessing. For example, the definition of a jpackage specifies a string argument consisting of a Uniform Resource Name (URN) (eg. in the form of jpackage org.javalin.examples). The macro must be able to parse this string into tokens as the dot separators are replaced with path separators on the developer's local build system and the final tokan represents the name of the package within that hierarchy.
The assembler must support routines (either intrinsically or macro-based) for string searching, concatenation, copying, and character replacement. Note that no requirement is given with regard to character type (eg. ASCII, UTF16, Unicode). This allows the developer to use their own language for object creation. However, distributing your objects will become an issue if you intend for your packages to be used by developers in other countries. It is recommended that your assembler be able to process ASCII strings and that your source code be written in ASCII to provide source code portability.
Case Sensitive
JASM is case-sensitive. Thus jpackage and JPACKAGE refer to two different macros. By convention JASM macros and keywords are written in lower case. By establishing this convention source code portability is ensured between an assembler that distinguishes between upper and lower case and assemblers that are case agnostic.
Includes
The assembler must support the inclusion of additional source files for processing. Again, all major assembler packages today support this feature. It is preferred that the assembler's include keyword allow for macro expansion of the filename argument rather than a constant string. This permits the system to supply a tokenized string which can be based on the JASMPATH environment variable. This is the preferred method as the JASMPATH environment variable will most probably be defined differently on each developer's local system. However, the assembler's standard include string constant format may be used if the assembler provides a command line switch or other method used to identify the JASMPATH root path for file incusion.
Note that JASM macros makes use of the JASM URN naming convention. Consequently, source code which uses the format jimport org.javalin.examples will need modified if using the constant string format jimport "org/javalin/examples".
Directory Structure
As indicated in the JASM Requirements document JASM uses a hierarchical file structure to contain system source files. The root of the directory is JASMPATH. Each subdirectory under the root is structured to contain contributor packages. This directory structuring prevents clashes of similarly named object packages from different vendors. The following shows the hierarchy of directories:
JASMPATH
|-----system
|-----org
| |----javalin
| |-----examples
| |-----jfc
|------com
|----vendor1
| |------packagename
|----vendor2
|------packagename
Programmers are free to choose their own directory structure for developing applications that will not make use of other vendor packages. However, the JASMPATH/system and JASMPATH/org/javalin directories must exist in order to successfully use JASM. It is highly recommended that you follow this structuring if you plan on distributing objects based on the JASM model.
Portability
JASM is designed to enable applications to be written using object oriented assembly souce code. It does this by establishing system conventions and encapsulating object creation and use from within the assembler's macro system. When talking about portability we are refering to the definition and instantiation of those objects. The actual logic executed within object methods is highly assembler specific. By providing a standard for object oriented programming we are assisting the assembly language developer regardless of assembler being used.
Portability between operating systems that execute on an architecture supported by the assembler is a real possibility. An object can encapsulate the disparate dependencies between operating systems. For example, JASM encapsulates calling convention differences between 32 and 64 bit architectures. Thus you can use JASM to define and execute the object's methods on those systems.
Naming Conventions
JASM keywords should be written in lower case. All package, class, and method names may be written in upper, lower, or mixed case. The preference of naming packages is lower case while class and method names are CamelCase. When creating an object's class and methods JASM make use of the following rule for name mangling:
packagename.classname.methodname@#
where packagename is the name of the package as well as the directory where the object can be found.
classname is the name of the class
methodname is the name of the method
@# represents the total number of bytes that constitute a method's parameters.
This complete sequence of characters form the method signature which is used when calling a class method.
To illustrate with a small example:
jpackage org.javalin.examples
jclass JPower
jmethod pow2, dword:base
jmethod power, dword:base, dword:exponent
jendclass
The method names become
org.javalin.examples.JPower.pow2@4
org.javalin.examples.JPower.power@8
This is the convention for method signatures and is how JASM differentiates between the class methods. JASM will define two single-line macros for each method of a class.
Using the first method in the previous example the two defines would be
in the jmethod definition:
org.javalin.examples.JPower.pow2@4: ; the methods starting address label
in the calling module source:
jinvoke JPower.pow2, 10 ; call org.javalin.examples.JPower.pow2@4
JASM_NO_SHORT_NAMES
A name space collision occurs when importing a package that contains a class and method name for which a short name had previously been defined. For source modules that require the functionality of both packages you must define JASM_NO_SHORT_NAMES prior to importing the second package and can subsequently undefine it after import to revert back to normal behavior.
If you do define JASM_NO_SHORT_NAMES then all class variables and methods imported following the define must be invoked using the full method signature from within your source file. You may define your own short name for the member variables and method signatures for use within your own source file.
For example, if two vendors each have a package containing the class named MathClass and each class implements a method named sin() then a name space collision will occur with the definition of the short name ( eg. MathClass.sin )for the second imported package.
Example:
jpackage MyPackage
jimport com.vendor1.math
%define JASM_NO_SHORT_NAMES
jimport com.vendor2.math
%undef JASM_NO_SHORT_NAMES
jmethod MyClass.MyMethod, dword:angle
; invoke vendor1 sin method using short name
jinvoke MathClass.sin, angle
; invoke vendor 2 sin method using full signature
jinvoke com.vendor2.math.MathClass.sin@4, angle
jendmethod
To ensure that your assembly source code never has short name collisions you can always use full signatures when calling any class methods.