PAL -- Primitive/Portable Assembly Language

PAL is designed to demonstrate some concepts of assembly language programming, with a minimum of machine-specific detail and a minimum of new tools to learn. It is simply a way of writing assembly-language style programs in C (or C++). Think of it as an architecture with only 64K of RAM memory and a lot of registers, with a separate (unaddressable) bank of ROM for the program, and a separate (unaddressable) stack to hold the return address during function calls.

PAL language guide

We will simulate some of the basic concepts of assembly language by programming in a restricted subset of C in which:

  1. var = constant ;
  2. var = var op var;
  3. var = (type ) var;
  4. if (var) goto label ;
  5. memop(var, address);
  6. return; /* if not in main */
  7. return var; /* if in main */

where

  1. op is a non-destructive binary C operation such as +, -, *, /, %, &&, &, >, ==, etc.
  2. type is int or double
  3. memop is either ld (load) or st (store) followed by b, w , or d to indicate a byte, word, or double (i.e. ldw(r1, 0) to load an integer from bytes 0-3 of memory into variable r1).
  4. address is either a constant or a variable plus a constant (of type int in either case), and is divisible by sizeof(int) (i.e. 4) for word operations and sizeof(double) (i.e. 8) for double operations, and is between 0 and 2^16-1.
  5. Only the return from main may include a return value.

You may choose to debug your programs with a C/C++ debugger, or by inserting C or C++ I/O statements, but if you do the latter, you must remove these statements (you may do this with #define and #if you you wish).

The semantics of a PAL program are defined by the semantics of C plus a set of definitions in PAL.h (shown below for a machine with 4-byte integers and 8-byte doubles), plus information about the architecture on which the programs are to be run. Note that the definition of C's mod operation (%) and the effects of using a single memory location for multiple types depend on the architecture.

/* This is PAL.h */

char memory[65536];

#define bmem(a) (memory[(a) & 0xffff])

#define wmem(a) (*((int *) (memory + ((a) & 0xfffc))))

#define dmem(a) (*((double *) (memory + ((a) & 0xfff8))))

#define ldb(v,a) v = bmem(a)

#define ldw(v,a) v = wmem(a)

#define ldd(v,a) v = dmem(a)

#define stb(v,a) bmem(a) = v

#define stw(v,a) wmem(a) = v

#define std(v,a) dmem(a) = v