Inline Assembly
Introduction
This document covers inline assembly in the Wave language. Inline assembly is one of the features provided by Wave, offering extreme level syntax that allows direct access to low-level hardware control while maintaining the convenience of high-level language.
In other words, it enables operations such as register manipulation, direct memory access, and execution of special commands that are difficult to handle with general Wave code. It is used when performance optimization or hardware-dependent tasks are needed.
Basic Syntax
asm {
"assembly command" // actual assembly code (one command per line)
...
in("register") value // input register mapping
out("register") variable // output register mapping
}
Grammar Components
-
Assembly Command
- Written in
"..."
string format, it is a low-level assembly command executed on the actual CPU. - Multiple lines can be written, with one command per line.
- Example:
"mov rax, 1"
"syscall"
- Written in
-
in("register") value
- Loads the value of a variable (or expression) into the specified register.
- Example:
-> Puts the value of the variable
in("rdi") s
s
intordi
, the first syscall argument register in the x86-64 convention.
-
out("register") variable
- Fetches the value of the specified register into a Wave variable.
- Example:
-> Stores the value of the
out("rax") ret
rax
register, where the return value of thesyscall
is stored, into the variableret
.
Simple Example
fun main() {
var msg_ptr: ptr<I8> = "Hello from syscall!\n";
var ret_val: i64;
asm {
"mov rax, 1"
"syscall"
in("rdi") 1
in("rsi") msg_ptr
in("rdx") 20
out("rax") ret_val
}
}
Precautions
- Inline assembly circumvents the type safety of Wave, so using incorrect instructions may lead to program crashes or undefined behavior.
in
andout
mappings are verified at compile time, but the validity of the commands themselves is not guaranteed.