Executable format for Dauug|36 binaries
Although standard formats such as ELF (Executable and Linkable Format) are a good idea in general, I am not aware of a suitable lightweight executable format for 36-bit architectures. Thus the assemblers, bootloader, and program loader are today best served by an executable format that is specifically for Dauug|36.
Dauug|36 executable files are read as a stream of 36-bit words. Every word in the stream is trivially classifiable as one of two types:
In-band data is any word that does not have all nine most significant bits set; that is, any unsigned word that is less than 777_000_000_000`o
.
Out-of-band commands are any words that have all nine most significant bits set; that is, any unsigned words greater than or equal to 777_000_000_000`o
.
Dauug|36’s instruction format uses the nine most significant bits as the opcode, and the instruction set assigns opcode 511 (777`o
) to privileged instruction XOOB
(executable out-of-band). XOOB
wouldn’t do anything if it’s executed, because the microcode defines it identically to NOP
. Instead, it’s used to format executable files.
The Dauug|36 executable format is defined as a stream where data is pushed on a stack, and commands act on this stack. The command set is extensible, and the stack is as deep as needed for the commands that are supported. The most recent word pushed on the stack is notated as S[0]
, the next most recent is S[1]
, and so on.
Defined commands
The following out-of-band commands defined for Dauug|36 executables as of 13 July 2023.
Command | Action |
...d36`t | magic number for Dauug|36 binaries |
...boo`t | copy from stream to code memory at offset S[0] until next command |
...len`t | last in-band word is the expected length of the code segment |
...cod`t | copy from stream to anywhere in code memory until next command |
...eof`t | disregard contents of stream from this point onward |
As a reminder, the digit .
means 63 in tetrasexagesimal, so the sequence ...
is eighteen 1
bits.
The very small number of commands are adequate for a bootloader to load a short program such as a small OS kernel in code memory and then branch to it. An n
-word executable file would contain n
− 6 instructions and look like:
Offset | Word | Description |
0 | ...d36`t | This file is a Dauug|36 executable. |
1 | 1024 | The code expects to be loaded and start at offset 1024. |
2 | ...boo`t | Copy this stream to the code memory location just indicated. |
3 | (length) | Place the length of the code segment in this word. |
4 | ...len`t | The prior word is the length of the code segment. |
... | The program’s code segment goes here. | |
n-1 | ...eof`t | This is the end of the file, so branch now to address 1024. |
The code segment’s length can be determined via the ...eof`t
out-of-band delimiter at the end, but Osmin wants to know in advance how much code memory to allocate before reading the segment. For this reason, the ...len`t
command appears before the code segment as an aid for the kernel.
More commands will be added to the executable format as they are needed, such as a means to include initialized data segments.