From 4e1edee7383af381d51b11fce45b6a15b62f10e7 Mon Sep 17 00:00:00 2001 From: hachem Date: Sun, 13 Sep 2026 00:37:24 +0200 Subject: docs: split docs --- docs/getting-started.md | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 docs/getting-started.md (limited to 'docs/getting-started.md') diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..6f90618 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,107 @@ +# Getting started + +## Build the compiler + +hdass builds with [Meson](https://mesonbuild.com/): + +```bash +meson setup build +meson compile -C build +``` + +That produces `build/hdass`. It has two options you need: `-o ` writes the +output (default stdout), and `-t ` picks the assembler and architecture +(`nasm` by default, `fasm`, or `arm64`). `build/hdass --help` lists the rest. + +hdass only *transpiles*: it emits assembly text, which you assemble and link +yourself. The examples target Linux, so you need an x86-64 (and +for AArch64, an aarch64) Linux toolchain. The bundled +[Docker image](../README.md#building) has `nasm`, `fasm`, an aarch64 +cross-assembler and `qemu`; the commands below run inside it: + +```bash +docker compose up -d +docker compose exec hdass bash +``` + +## A first program (x86-64) + +Put this in `hello.hdass`: + +```hdass +[entry: main] + +const SYS_WRITE = 1 +const SYS_EXIT = 60 +const STDOUT = 1 + +data message = "Hello, hdass!\n" + +proc main +{ + rax = SYS_WRITE // write(STDOUT, message, message.len) + rdi = STDOUT + rsi = message + rdx = message.len + syscall + + rax = SYS_EXIT // exit(0) + rdi = 0 + syscall +} +``` + +Transpile, assemble, link and run: + +```bash +./build/hdass hello.hdass -o hello.asm +nasm -f elf64 hello.asm -o hello.o +ld -e main hello.o -o hello +./hello +``` + +It prints `Hello, hdass!`. `[entry: main]` exports `main` and drops its `ret`, so +the procedure ends the program itself with the exit syscall; `ld -e main` uses it +as the start symbol. Swap `-t fasm` and `fasm hello.asm hello.o` to use fasm +instead — the machine code is the same. + +## Running on AArch64 + +The same source model runs on ARM, but the syscall ABI differs (numbers and +argument registers), so this program is AArch64-specific. Written with the +[`logical_registers`](targets.md#the-portable-register-model) extension so the +registers read the same on both architectures: + +```hdass +[entry: main] +[enable: logical_registers] + +const SYS_EXIT = 93 // AArch64 Linux exit + +proc main +{ + r1 = 42 // x0 = exit code + r9 = SYS_EXIT // x8 = syscall number + syscall // svc #0 +} +``` + +Build it for AArch64 and run it under qemu: + +```bash +./build/hdass -t arm64 exit.hdass -o exit.s +aarch64-linux-gnu-as exit.s -o exit.o +aarch64-linux-gnu-ld -e main exit.o -o exit +qemu-aarch64 ./exit # exits 42 +``` + +`r1` maps to `x0` and `r9` to `x8`, `syscall` becomes `svc #0`. See +[Targets](targets.md) for the register mapping and the ABI tables. + +## Next + +- The whole language: [language reference](language.md). +- What runs where and why programs still carry per-architecture ABI details: + [targets](targets.md). +- More programs to read: [examples/](../examples/) and + [examples/arm64/](../examples/arm64/), each runnable with the steps above. -- cgit v1.3