Synopsis
vasm [FILE …] [OPTIONS …]
Description
A standard compiler for LR Assembly, a weakly typed assembler language designed to be compatible with multiple VM environments.
Options
- -h, --help
-
Shows the help menu. Note: this is a work in progress and currently does not show anything on Windows devices because of execve being used to run
man
. As the frontend begins to become stabilized this will change. - --no-stylist
-
Disables running stylist when compiling a program. This disables any compile-time checks and also conflicts with the
--enforce-stylist
flag. - --strict | --enforce-stylist
-
Quits compilation early if stylist reports any style or potential UB issues. Useful for writing strictly typed LR assembly.
- -ln, --allow-large-numbers
-
Allows for large numbers to be in the program. (disabling lex-time checks for large numbers) It is recommended to keep this option ON as it prevents UB [1] from occuring within the program.
- -le
-
Specifies the
endian
flag as big in the compiler’s options. The endian flag controls the endianness of the binary generation. - -be
-
Specifies the
endian
flag as little in the compiler’s options. The endian flag controls the endianness of the binary generation. - -f, --format FORMAT
-
Specifies the output format for the binary. This output format will be the basis for any operations moving forward. This format flag is converted from a string to an enum that contains the format’s information. The format is used for
-
Lexer number sizes
-
Vendor sizes
-
Vendor name
-
- -o, --output FILE
-
Specifies the output location of the binary. This location must be a file, it can not be a directory.
- -O[N]
-
Sets the optimization level to N. For some architectures this will have an effect on what context is chosen and passed to the generator, and others it may not.
Vendors
A "vendor" is defined as information to help generate binaries based on documented instructions sets. Instead of mapping each instruction to a number, vasm supports generation of binaries through hand-implemented functions which are children of instructions. Using the VASM zig API, the OpenLUD vendor is created using the following method:
pub fn vendor(vend: *codegen.Vendor(i8)) !void {
vend.nul_after_sequence = true;
vend.nul_byte = 0;
try vend.createAndImplementInstruction(i8, "echo", &echoInstruction);
try vend.createAndImplementInstruction(i8, "mov", &moveInstruction);
try vend.createAndImplementInstruction(i8, "each", &eachInstruction);
try vend.createAndImplementInstruction(i8, "init", &initInstruction);
// ...
}
The above example uses createAndImplementInstruction
to implement a couple instructions that are specific to the OpenLUD format. These are optional as they are a part of the compilation process and not the language itself. Vendors are just a separate implementation that defines a streamlined process of compiling and verifying binaries.
Vendors then take input source and turn it into a PROCEDURE MAP that can then be operated on separately. Procedure maps are key-value pairs that represent the procedure hierarchy of a program. Procedures can be tagged by size (example a 5-byte procedure) and in that stage is where peephole optimizations can take place. The peephole optimizer (defined in peephole.zig) is not aware of the original source code and only aware of the generated binary, however, using information given to the optimizer prior, is able to free up and remove procedures that go unused.
In hindsight, this doesn’t have much benefit aside from memory consumption when procedure folding is enabled, however, using NexFUSE-like Procedures (where each procedure label is engraved in the resulting binary) yields higher results.
Information
This document’s version is 1.0.0.