LASM - Lucia Assembly Language
LASM (Lucia Assembly) is a Rust crate that provides JIT (Just-In-Time) compilation of a custom assembly language to native machine code via Cranelift. Its key features are high-performance JIT execution and seamless variable interaction between Rust and LASM code.
Why LASM?
JIT Compilation: Unlike interpreted languages, LASM compiles to native machine code at runtime using Cranelift, providing near-native performance with minimal overhead.
Variable Bridge: Seamlessly pass data between high-level Rust code and low-level assembly, enabling performance-critical sections while maintaining safety.
Modern Assembly: Register-based architecture with convenient syscalls, eliminating the boilerplate of traditional assembly programming.
Rust Integration: Drop LASM code anywhere in your Rust application for instant performance boosts.
Purpose: LASM was developed as the low-level execution backend for the Lucia Programming Language. It powers the lasm module, allowing performance-critical sections of an otherwise interpreted language to execute at near-native speed through JIT compilation.
Installation
As a Cargo Crate
Add to your Cargo.toml:
[]
= { = "1", = "lucia-lasm" }
Or use the latest version from crates.io:
Building from Source
Usage
As a Library
use ;
use HashMap;
Command Line Tool
The crate includes a CLI binary for testing and development:
Or after building:
Library API
Basic Usage
use ;
use HashMap;
Variable Interaction
One of LASM's most powerful features is seamless variable passing between Rust and LASM code:
use ;
use HashMap;
Variable Instructions
load "var_name", reg- Load a variable from Rust into a registerpush reg, "var_name"- Store a register value back to a Rust variable
Variables can be of type Int, Float, String, Ptr, or Null.
Architecture
Registers
- General Purpose: r0-r15 (64-bit)
- Stack Pointer: rsp
- Base Pointer: rbp
Instructions
Data Movement
mov <src>, <dst>- Move value from source to destinationldr <reg>, [<reg>]- Load from memory address in registerstr <reg>, [<reg>]- Store to memory address in registerload "var", <reg>- Load Rust variable into registerpush <reg>, "var"- Store register value to Rust variable
Arithmetic
add <dst>, <src>- Addsub <dst>, <src>- Subtractmul <dst>, <src>- Multiplydiv <dst>, <src>- Dividemod <dst>, <src>- Modulo
Floating Point Arithmetic
fadd <dst>, <src>- Add floatsfsub <dst>, <src>- Subtract floatsfmul <dst>, <src>- Multiply floatsfdiv <dst>, <src>- Divide floatsfmod <dst>, <src>- Modulo floats
Logic
and <dst>, <src>- Bitwise ANDor <dst>, <src>- Bitwise ORxor <dst>, <src>- Bitwise XORnot <dst>- Bitwise NOTshl <dst>, <src>- Shift leftshr <dst>, <src>- Shift right
Control Flow
cmp <left>, <right>- Compare registers/valuesbeq <label>- Branch if equalbne <label>- Branch if not equalblt <label>- Branch if less thanbgt <label>- Branch if greater thanble <label>- Branch if less or equalbge <label>- Branch if greater or equaljmp <label>- Unconditional jumpcall <label>- Call subroutineret- Return from subroutine
Stack Operations
pushr <reg>- Push register onto stackpopr <reg>- Pop from stack into register
Operands
Instructions can take:
- Immediate values: Numbers like
42or strings like"hello" - Registers:
r0,r1, etc. - Labels: For jumps and calls
Syscalls
LASM provides high-level syscalls that abstract away low-level system calls:
I/O
syscall write- Write to file descriptor (fd in r0, buffer in r1, count in r2)syscall read- Read from file descriptorsyscall print_int- Print integer (value in r0)syscall print_float- Print float (bits in r0)syscall print_str- Print null-terminated string (pointer in r0)syscall flush- Flush output stream (fd in r0)
Memory
syscall malloc- Allocate memory (size in r0, returns pointer in r0)syscall free- Free memory (pointer in r0)syscall memcpy- Copy memory (dst in r0, src in r1, len in r2)syscall memset- Set memory (dst in r0, val in r1, len in r2)
Strings
syscall strcmp- Compare strings (str1 in r0, str2 in r1, returns comparison in r0)syscall strcpy- Copy string (dst in r0, src in r1, returns dst in r0)syscall strlen- Get string length (str in r0, returns length in r0)syscall starts_with- Check if string starts with prefix (str in r0, prefix in r1, returns 1/0 in r0)syscall streq- Check if strings are equal (str1 in r0, str2 in r1, returns 1/0 in r0)syscall ends_with- Check if string ends with suffix (str in r0, suffix in r1, returns 1/0 in r0)syscall trim- Trim whitespace (str in r0, out in r1, returns length in r0)syscall trim_start- Trim leading whitespace (str in r0, out in r1, returns length in r0)syscall trim_end- Trim trailing whitespace (str in r0, out in r1, returns length in r0)syscall isws- Check if string is all whitespace (str in r0, returns 1/0 in r0)
Conversion
syscall atoi- String to integer (str in r0, returns int in r0)syscall atof- String to float (str in r0, returns float bits in r0)syscall itoa- Integer to string (int in r0, buffer in r1, size in r2, returns length in r0)syscall ftoa- Float to string (bits in r0, buffer in r1, size in r2, returns length in r0)syscall itof- Integer to float (int in r0, returns float bits in r0)syscall ftoi- Float to integer (bits in r0, returns int in r0)
Math
syscall fadd- Add floats (a bits in r0, b bits in r1, returns result bits in r0)syscall fsub- Subtract floatssyscall fmul- Multiply floatssyscall fdiv- Divide floatssyscall fmod- Modulo floats
Time & Random
syscall time- Get current time (returns nanoseconds in r0)syscall fmt_time- Format time (total_nanos in r0, format in r1, buffer in r2, returns length in r0)syscall rand- Generate random float (seed in r0, returns float bits in r0)
Utilities
syscall sleep- Sleep for milliseconds (ms in r0)syscall system- Execute system command (cmd in r0, returns exit code in r0)
System
syscall exit- Exit program (status in r0)
Examples
Hello World
; Hello World
mov "Hello, World!\n", r1
mov 1, r0
mov 14, r2
syscall write
mov 0, r0
syscall exit
Calculator
; Simple calculator
mov 10, r0
mov 20, r1
add r0, r1 ; r0 = 30
syscall print_int
mov "\n", r1
mov 1, r0
mov 1, r2
syscall write
mov 0, r0
syscall exit
Running Examples
The repository includes example LASM programs in the examples/ directory:
# Hello World
# Calculator
# Time display
# Interactive shell
Or after building the release binary:
Syntax Details
- Comments: Start with
;and continue to end of line - Labels: End with
:and can be jumped to - Strings: Enclosed in double quotes, null-terminated automatically
- Numbers: Decimal integers, can be used as immediates
- Case Sensitive: All keywords and register names are case sensitive
Error Handling
LASM provides clear error messages for:
- Syntax errors
- Undefined labels
- Invalid register names
- Unsupported syscalls
- File I/O errors
Performance
LASM's JIT compilation provides significant performance advantages for compute-intensive tasks:
use ;
use HashMap;
JIT compilation enables dynamic code generation while maintaining high performance.
Limitations
- 64-bit architecture only (x86_64, AArch64)
- No floating point registers (floats stored as bits in general registers)
- No direct hardware access
- Stack operations are simulated
Testing
Run the test suite:
The tests include various LASM programs demonstrating different features and syscalls.
Contributing
Contributions are welcome! This is a Rust crate that can be extended in several ways:
- Additional Syscalls: Add new high-level operations
- Optimization: Improve code generation and performance
- Error Handling: Better error messages and recovery
- Documentation: More examples and tutorials
- Cross-Platform: Support for additional operating systems
- Features: New instructions or language constructs
Development Setup
Publishing
To publish to crates.io:
Make sure to update the version in Cargo.toml and tag the release.