Use using to share imports, data, and procedures between ZASM files.
The compiler expands each header at the directive's position before assembly.
Syntax:
using "{filename.zh}"include/windows/console.zh
#IMPORT msvcrt.dll, puts, exitmain.zasm:
using "windows/console.zh"
; using "subfolder/myfile.zh"
jmp start
message db 'Hello Zero!', 0
start:
push message
call [puts]
add esp, 4
push 0
call [exit]Like C/C++ #include, using loads source text into the current program.
Each resolved file is included once per compilation, so shared dependencies
do not produce duplicate declarations. Circular includes are errors: the compiler
reports the chain, such as a.zh -> b.zh -> a.zh.
This is currently implemented for ZASM. Headers share the program's labels and imports; they do not introduce a namespace. Keep declarations before code that uses them for readability. Forward label references also work.
- The terminal's current working directory.
- Directories supplied with
-Ior--include, in command-line order. - The
includedirectory besidezero.exeorzcc.exe.
For using "subfolder/myfile.zh", the compiler checks that entire relative path
under each directory. Nested headers follow the same order; their own containing
directory is not added to the search. Absolute filenames are checked directly.
zero.exe run main.zasm -I "headers" -I "C:\Libraries\Zero"
# Managed builds from the repository need the header path explicitly:
dotnet output/Zero.Cli/Release/zcc.dll samples/hello-using.zasm -I include- Process nested using directives recursively.
- Include each resolved file once per compilation.
- Detect circular includes and report the chain, such as a.zh → b.zh → a.zh.
- Keep your stated search order for nested includes too; don’t silently add another search location.
- Report missing files with the requesting filename, line number, and paths searched.
- Normalize paths before comparing them so
file.zhand./file.zhrefer to the same file. - Recognize using as a complete directive, respecting quoted filenames and trailing comments.
Use double quotes around filenames. using is case-insensitive. A semicolon
starts a trailing comment outside quotes. Extra text after the filename is an
error. Errors inside headers report the header's filename and original line number.
| Header | Purpose | Imported functions |
|---|---|---|
windows/console.zh |
Console text and program exit | puts, printf, exit |
windows/windows.zh |
Basic Windows APIs | ExitProcess, GetModuleHandleA, MessageBoxA |
Additional DLL-specific headers cover core OS services, windows, GDI drawing, common controls and dialogs, the shell, sockets, registry/security, COM, Automation, path helpers, multimedia, HTTP, and file version resources. See the Windows API header guide for the full catalog.
Windows headers now live under include/windows; use paths such as
using "windows/console.zh". Root-level compatibility copies are not shipped.
Draft Linux headers live separately under include/linux and require future
ELF support. See Linux headers for their status.
The headers target the compiler's current Windows x86 output. puts and printf
use cdecl, so remove their arguments from the stack after calls. Windows API
functions remove their own arguments.
Running build.ps1 publishes this layout, also included in release ZIPs:
publish/
zero.exe
zcc.exe
include/
windows/
console.zh
windows.zh
kernel32.zh
user32.zh
comctl32.zh
...
linux/
libc/ # Drafts, not runnable with the PE backend.
syscalls/ # Comment-only architecture references.
readme.md
samples/
hello-using.zasm
...
From any working directory, run the published sample with:
C:\path\to\publish\zero.exe run C:\path\to\publish\samples\hello-using.zasmIt prints Hello Zero!. Keep the include folder beside the compiler when
moving or installing it. Headers containing executable code or inline data are
inserted exactly where using appears; use a jump to skip declarations when needed.
The file-based Zero.Compile API performs the same expansion as the CLI.
Pass Zero.Compilation.CompilerOptions as its optional fourth argument to set
IncludeDirectories, WorkingDirectory, or CompilerDirectory. For direct
assembler use, load files with Zero.Parsing.SourceLoader.Load and pass its
SourceLine list to Assembler.Assemble to retain source locations.
The existing Assemble(string[]) and CompileAsm(string[]) APIs still accept
assembly lines directly; use the file loader when those lines contain using.