Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Data directives and layout expressions

Data directives emit values directly, without an instruction opcode:

SpellingBytes per valueAccepted result
db or byte10 through 255
dw or word20 through 65535
dd or dword40 through 2147483647 (current expression limit)
dq or qword80 through 2147483647 (current expression limit)

All four accept comma-separated expressions terminated by a semicolon. Multi-byte values use little-endian byte order, with no automatic alignment or padding.

db 60+5,66,0;       // 41 42 00
byte 0xAA,0x55;    // AA 55
dw 4660;           // 34 12
word 0x55AA;       // AA 55
dd 0x12345678;     // 78 56 34 12
dword 40+2;        // 2A 00 00 00
dq 42;            // 2A 00 00 00 00 00 00 00
qword 0;          // 00 00 00 00 00 00 00 00

Each word list element occupies two bytes: word 0xAA,0x55; emits AA 00 55 00. Empty lists, trailing commas, missing commas, negative results, and results above the directive’s range are rejected. The existing signed 32-bit expression rules still apply to intermediate calculations. DD and DQ store four and eight bytes respectively, but full unsigned 32-bit and 64-bit expression values are not yet supported. Even though their current range diagnostics name wider storage limits, the expression evaluator rejects results above 2147483647 first.

Prefix a data directive with times <count> or fill <count> to repeat its complete comma-separated list. The count is an expression, must be nonnegative, and must fit size_t.

times 3 db 170;          // AA AA AA
fill 2 dw 4660,0;        // 34 12 00 00 34 12 00 00
times 2 dd 42;           // 2A 00 00 00 2A 00 00 00

Labels include the size of preceding data. Executable examples must jump over embedded data, as in examples/data_all_jump.asm, which mixes all four widths. Data-only examples are encoding fixtures, not functions to execute.

The CLI writes source-named .bin and .h files for images containing data, but prints Data emitted; instruction-only decoding skipped. instead of trying to disassemble the image. Instruction-only images retain their decoded listing. TIMES/FILL repetition is supported for data directives. Strings, alignment, and symbol-valued data remain future work.

Generated images are capped at 16 MiB (16,777,216 bytes) by KASM_IMAGE_LIMIT. This output limit includes instructions and repeated data; it is separate from dynamically allocated source-file storage.

Location-aware padding

The assembler also supports $ and $$ inside repeat-count expressions:

mov eax, 42;
times 510-($-$$) db 0;
dw 0xAA55;

$ is the current image offset and $$ is the image start, which is offset zero for the current single-image layout. The count is resolved during layout, after earlier statements have known sizes. In this example, mov eax, 42; is five bytes, so the padding count is 510 - (5 - 0) = 505, followed by the little-endian signature bytes 55 AA.

This produces a 512-byte data image. It is a tested layout fixture, not yet a bootable sector: a signature alone does not define an entry convention, segment state, stack, BIOS services, or an emulator workflow. Negative padding is rejected before the repeat count is converted to size_t.

Permanent tests cover all eight spellings, expression values, range boundaries, exact bytes, mixed-width layout, jump targets, constant and location-aware TIMES/FILL repetition, and invalid lists and ranges. The Windows Debug build validates the data-directive suite, including encode.times_fill, encode.boot_pad, and invalid-input cases within semantic.data_invalid. After configuring and building, run them with:

ctest --test-dir build/windows-debug -C Debug -R "(encode.data_|encode.times_fill|encode.boot_pad|semantic.data_invalid)" --output-on-failure

Symbol-valued data (label expressions inside directives) resolves after layout as of 0.33.0; constant-only expressions retain the checked arithmetic described in Control instructions and overflow safety.