Programs
A program’s result is the list of values it emits, in order. Everything in this chapter is about arranging that list:
- Labels name positions in it.
- Sections group it into regions, like code and data.
- Linking combines the lists of several files.
- Executables put a header in front, so the result can run.
A complete program
This is examples/x86_64/hello.basm from the repository, a “Hello, world!”
for Linux on x86-64:
from std.x86_64.nasm import *
from std.formats.elf import *
elf64_executable EM_X86_64, _start
const text = "Hello, World!\n"
section .rodata
msg:
db text
section .text
pub _start:
mov eax, 1 # sys_write
mov edi, 1 # stdout
lea rsi, [rel msg] # buffer
mov edx, text.len # length
syscall
mov eax, 60 # sys_exit
xor edi, edi # status 0
syscall
Every piece of it is ordinary BitterASM:
elf64_executableis a macro fromstd.formats.elfthat emits an ELF header. See Executables.section .rodataandsection .textput the string and the code in separate sections.const textnames the string, sodb textcan emit it andtext.lengives its length.msg:and_start:are labels.pubexports_start.lea,mov,syscalland the rest are macros fromstd.x86_64.nasm, anddbis NASM’s data directive.
Build and run it:
bitter build examples/x86_64/hello.basm -o hello
./hello
Top-level statements run in order
The statements at the top level of a file run from top to bottom. Each call appends whatever it emits. Declarations can appear anywhere, since they’re visible throughout the file.