High Level Assembly
From Wikipedia, the free encyclopedia
-
For the general concept, see High-level assembler. This article is about one specific implementation
High Level Assembler (HLA) is an assembly language developed by Randall Hyde which can use high-level language constructs to aid x86 assembly programmer beginners and advanced assembly developers alike. It fully supports advanced data types and object-oriented assembly language programming. It uses a syntax loosely based on several high-level languages, such as C/C++, Ada, Modula-2, and Pascal, to allow the creation of readable assembly language programs, and to allow HLL programmers to learn HLA as rapidly as possible.
Contents |
[edit] Origins and goals
HLA was originally conceived as a tool to teach assembly language programming at the college/university level. The idea is to leverage students existing programming knowledge when learning assembly language to get them up to speed as rapidly as possible. Most students taking an assembly language programming course have already been introduced to high-level control structures such as IF, WHILE, FOR, etc. HLA allows students to immediately apply that programming knowledge to assembly language coding early in their course, allowing them to master other prerequisite subjects in assembly prior to learning how to code low-level forms of these control structures. "The Art of Assembly Language Programming" by Randall Hyde uses HLA for this very purpose (see #External links to read an on-line version of the book).
[edit] High and low-level assembler
A common misconception about HLA is that it is not a "low-level assembler" like Microsoft's MASM or Borland's TASM products. People generally develop this misconception after looking at a typical "hello world" program in HLA that consists of a single macro invocation for the program's body:
program helloWorld; #include("stdlib.hhf") begin helloWorld; stdout.put( "Hello World" nl ); end helloWorld;
Combined with the Pascal and C-like declarations for a program, many people get the impression that HLA is not an assembly language at all, but rather some sort of high-level language. In fact, the "stdout.put" statement in the above code is nothing more than an assembly language macro that expands to code like the following:
program HelloWorld; #include( "stdlib.hhf" ) static hwString :string := "Hello World", nl; begin HelloWorld; // Push the address of the "Hello World" string push( hwString ); // Call an HLA Standard Library function that // will print the string whose address has // been pushed on the stack. call stdout.puts; end HelloWorld;
There is absolutely nothing stopping a programmer from writing the "Hello World" program in low-level assembly language, should they really want to do this (not that there is any practical reason for doing so, mind you). However, for the beginner who is experiencing their first hour with assembly language, the former code is far more approachable than this latter code (i.e., explaining the stack and how parameters are passed to a procedure via the stack is a relatively advanced subject).
HLA supports all the same low-level machine instructions as other x86 assemblers and, indeed, HLA's high-level control structures are based on the ones found in MASM and TASM (whose HLL-like features predated the arrival of HLA by several years). One can write low-level assembly code in HLA just as easily as with any other assembler by simply ignoring the HLL-control constructs. HLL-like features appear in HLA to provide a learning aid for beginning programmers, with the assumption that they will discontinue the use of those statements once they master the low-level instruction set (in practice, many experience programmers continue to use HLL-like statements in HLA, MASM, and TASM, long after they've mastered the low-level instruction set, but this is usually done for readability purposes).
[edit] Distinguishing features
Two HLA features set it apart from other x86 assemblers: its powerful macro system (compile-time language) and the HLA Standard Library.
[edit] Macro system
HLA's compile-time language allows programmers to extend the HLA language with ease, even creating their own little Domain Specific Language to help them easily solve common programming problems. The stdout.put macro briefly described earlier is a good example of a sophisticated macro that can simplify programmers lives. Consider the following invocation of the stdout.put macro:
stdout.put( "I=", i, " s=", s, " u=", u, " r=", r:10:2, nl );
The stdout.put macro processes each of the arguments to determine the argument's type and then calls an appropriate procedure in the HLA Standard library to handle the output of each of these operands. Assuming i is a 32-bit signed integer, s is a string variable, u is a 32-bit unsigned integer, and r is a 32-bit floating point value, the macro invocation above expands to code like the following:
push( iEqualsStr ); // "I=" string call stdout.puts; // Print "I=" push( i ); call stdout.puti32; // Print i as a 32-bit signed integer. push( sEqualsStr ); // " s=" string call stdout.puts; // print " s=" push( s ); // Push the address of the string call stdout.puts; // and print it. push( uEqualsStr ); // Push the address of " u=" string call stdout.puts; // and print it. push( rEqualsStr ); // Push the address of " r=" string call stdout.puts; // and print it. push((type dword r)); // Push r's value onto the stack. pushd( 10 ); // Push the field width. pushd( 2 ); // Push decimal positions. call stdout.putr32; // Print the value as real. call stdout.newln; // Print a new line character sequence.
It should be rather clear that the former code is much easier to write, read, and maintain than this latter code; this is one of the advantages of using macros in assembly language code. Of course, most assemblers provide some sort of macro capability, the advantage that HLA offers over other assemblers is that it is capable of processing macro arguments like "r:10:2" using HLA's extensive compile-time string functions, and HLA's macro facilities can figure out the types of variables (such as i, u, s, and r in this example) and use that information to direct macro expansion, as was done in this example.
[edit] Standard library
The HLA Standard Library is an extensive set of prewritten routines and macros (like the stout.put macro described above) that make life easier for programmers, saving them from reinventing the wheel every time they write a new application. Perhaps just as important, the HLA Standard Library allows programmers to write portable applications that run under Windows or Linux with nothing more than a recompile of the source code.
[edit] Command-line invocation
The HLA v1.x language system is a command-line driven tool that consists of several components including a "shell" program (e.g., hla.exe under Windows), the HLA language compiler (e.g., hlaparse.exe), a low-level translator (e.g., MASM, TASM, or FASM under Windows or Gas under Linux), a linker (link.exe under Windows, ld under Linux), and other tools such as a resource compiler under Windows.
The HLA "shell" application processes command line parameters and routes appropriate files to each of the programs that make up the HLA system. It accepts as input ".hla" files (HLA source files), ".asm" files (source files for MASM, TASM, FASM, or Gas assemblers), ".obj" (".o") files for input to the linker, and ".rc" files (for use by a resource compiler).
The HLAPARSE.EXE (just "hlaparse" under Linux) is a "compiler" that translates HLA source files into an intermediate ".asm" form (much like GCC translates C/C++ files into assembly language source files). The output of the HLAPARSE program is translated into object code by MASM, FASM, TASM, or Gas. The object code is linked into an executable format by a linker. Of course, this activity is transparent to the user -- the "shell" program performs all these steps automatically. Though using secondary assemblers such as MASM or Gas to process HLA output is someone controversial amongst "old-school" assembly programmers, one big advantage offered by this scheme is that it is a trivial matter to translate HLA syntax assembly code into MASM, TASM, FASM, or Gas assembly code. This is a very nice facility for those who need to translate code amongst different assemblers. HLA is the only assembler that provides the ability to translate its code into so many different syntaxes.