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.


1. UB stands for "Undefined Behavior". Essentially when anything uncontrollable or unpredictable happens within the program that is not going to or not currently planned to be fixed. A way for developers to cut off specific parts of their program that are too non-conforming to be manageable.