|
Informatik-Vollmer | |
vam.pl - Virtual Assembler Machine: an interpreter for a simple processor's instruction set
vam.pl [--help] [--manual | -M] [--verbose ] [--Version] [--input infile] [--output outfile] [--registers count] [--memory size] [--dump | -D] [--statistics] [srcfile...]
Default: stdin.
Default: stdout.
Default: 32M
Default: 32
Option names may abbreviated as long as the are unique. Instead of --XX -XX may be used.
vam.pl is an interpreter of a simple processor's (designed by me and called VAM, Virtual Assembler Processor) instruction set. It has the ``usual'' machine instructions available on ``real'' processors.
vam.pl may be used e.g. in a compiler construction course to have a ``play ground'' when generating machine code.
vam.pl read the instructions to be interpreted either from stdin or
the file(s) srcfile given on the command line.
The BIOS (Basic Input / Output System) of the processor allows
to read and write a file during runtime (see --input and --output).
The source file srcfile contains the assembler instructions to be interpreted.
A line is either empty, contains a comment or one instruction or one (string or data) declaration.
The # character starts a comment up to the end of the line.
The instruction and registers names are case insensitive. Labels and string literals are case sensitive.
The VAM processor has a usual von-Neumann architecture with registers, memory, an ALU (arithmetic logical unit) etc.
The processor knows two data types: (signed) integers and floating point numbers. Memory addresses are positive integer values.
The number of registers may be specified by the --registers command line option and are denoted by R0, R1, ... A register may hold one value of a given data type at a time.
The memory is partitioned into memory cells, which may hold one value of a given data type at a time.
The registers R0, R1 und R2 are reserved and should not be used for other purposes (even it is legal to modify them). All other registers may be used without any restrictions.
With the exception of the control flow and non-executable statements, after performing the operation specified by an instruction, the instruction counter R0 will be incremented by 1.
Address | Description
----------------+-------------------------------------------------
0 | Undefined address
----------------+-------------------------------------------------
1 | The instruction to be executed at program start
... | More instructions.
<code-end> | The textual last instruction
----------------+-------------------------------------------------
<data-start> | Global data
... | ........
<data-end> | ........
----------------+-------------------------------------------------
<malloc-start> | Start of free memory.
... | ....
<high-memory>-1| Last memory cell, initial top of stack
----------------+-------------------------------------------------
The free memory ``grows'' towards larger address, while the stack grows towards small addresses.
The VAM emits under the following conditions an error message and terminates:
In the sequel the instruction are declared, which the processor is able to process. In the description below r, r1, r2, r3 specify any processor register R0, R1, ..., Rmax_registers-1, even the reserved ones. If for an instruction several registers may be specified, the same register may be used several times.
The notion M[address] specifies the access of the memory cell at the given address.
There are three kinds of named entities, named by so called label:
A label consists of a letter followed by letters, digits or an underscore character. The labels of each entity class (data, string, instruction) reside in a separate namespace and must be unique in that namespace.
The string and data declarations are non-executable instructions, therefore the instruction counter is not modified. They may occur everywhere in the source file.
Memory cells holding global data must be reserved and a label must be given be given. This declaration reserves count memory cells. The address of the first memory cell may be accessed using the name label.
A string declaration declares a name for a character string used in the write_s instruction. The two characters ``\n'' represent a newline. The two characters ``\t'' represent a tabulator.
A control flow statement may use an instruction label to specify the next statement to be executed.
Some instructions have a suffix in their name. The suffix _f indicates floating point and _i integer operation. The suffix _c indicates that the instruction takes a literal integer argument, _r a register is used and _l a label.
A prefix i indicates some kind of indirection.
r1 = r1 - 1; Memory[r1] = R0 + 1; R0 = label
r1 = r1 - 1; Memory[r1] = R0 + 1; R0 = r2
R0 = Memory[r]; r = r + 1;
If register r holds the shown condition, then continue execution with the instruction specified by label, else continue with the textual next instruction.
The registers should contain an integer value.
See also cmp_i and cmp_f.
Except when noted, all registers used by an instruction must hold values of the same datatype, which must match the type of the instruction. Otherwise the result may be undefined.
The processing of an instructions read the source registers performs the operation and store the result in the destination register.
There is no test over underflow or overflow of the result. A division by 0 causes an error.
If r3 == 0 an error message is emitted and the program is terminated.
If r3 == 0 an error message is emitted and the program is terminated.
Note: there is no floating point mod operation!
r1 holds an integer -1, 0, or 1 according to:
r1 = r2 <operand> value
Right shift: r1 = r2 >> r3 (in C speak)
All registers must hold integer values.
Transport instructions move values from one place to another.
If a register specifies an address, it must hold an positive integer value. Everything else is undefined.
r1 = Memory[r2]
r1 = Memory[label]
r1 = Memory[r2 + value]
value is an (signed) integer number.
Memory[r1] = r2
Memory[label] = r2
Memory[r1 + value] = r2
value is an (signed) integer number.
Stack grows from higher to lower addresses.
r1 = r1 - 1; Memory[r1] = r2
r1 should contain an address, while r2 may hold any value.
r1 = r1 + r2
r1 = r1 + value
r1 should contain an address, while r2 / value is an integer.
The VAM has a build in BIOS (basic I/O system) which allows to write character strings and numbers to a file (see --output). Only numbers may be read from a file (see --input).
###############################################################################
The following instruction read some values from the input file.
If r1 and r2 denote the same register, no error code is stored. In case of an error the value 0 is stored in the register.
The read number must be terminated by RETURN (newline).
The following instruction write some values to the output file.
The following program prints the square numbers 1 ... n^2:
############################################################# # Description: A VAM program computing square numbers # Input: read a number # Output: write square numbers 1 .... n^2
s_in: "Please input an integer: " s_out: "^2 = " NL: "\n"
start:
write_s s_in
read_i R4, R4 # R4: n (ignore errors)
write_s NL
cload_i R5, 1 # R5: i = 1
loop:
cmp_i R6, R5, R4 # if (i > n) goto end
ifgt R6, end
mult_i R6, R5, R5 # i * i
write_i R5 # printf ("%d^2 = %d\n", i, i*i);
write_s s_out
write_i R6
write_s NL
add_c R5, R5, 1 # i = i + 1
goto loop # and loop
end:
end
#############################################################
More examples will be found in the example files shipped together with this program.
perl(1)
Dr. Jürgen Vollmer <Juergen.Vollmer@informatik-vollmer.de>
Copyright (C) 2005 Dr. Jürgen Vollmer, Karlsruhe.
Homepage of VAM: http://www.informatik-vollmer.de/software/vam.html
If have written ``large programs'' doing some interesting job, it would be nice to send me your VAM source.
If you find this software useful, I would be glad to receive a postcard from you, showing the place where you're living:
Dr. Jürgen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe, Germany.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
http://www.gnu.org/copyleft/gpl.htmlVersion 1.0 of 2005/02/24
$Log: vam.pl,v $ Revision 1.8 2005/07/12 12:06:43 vollmer *** empty log message ***
Revision 1.7 2005/07/12 11:20:57 vollmer *** empty log message ***
Revision 1.6 2005/06/19 10:41:10 vollmer fixed focu
Revision 1.5 2005/03/11 22:58:51 vollmer fixed name of vam_ifne
Revision 1.4 2005/03/11 22:51:40 vollmer sub cm: if a memory cell undefined during an access, assign 0 to it
Revision 1.3 2005/03/11 22:48:05 vollmer fixed sub_f
Revision 1.2 2005/03/11 14:11:45 vollmer fixed docu
Revision 1.1 2005/02/24 16:55:52 vollmer Initial revisionDr. Jürgen Vollmer (www.informatik-vollmer.de)