Targets

One assembler, many targets: Windows on Intel and ARM, DOS, ARM Linux and the Raspberry Pi Pico.

Three lines at the start of a source file say what a program is for: .format (the kind of file), .arch (the instruction set) and, for a board, .target. They also decide where the debugger starts the program: on this computer, in a helper process, on a second computer, in QEMU or on the board behind a debug probe. Under Debug > Debug targets you set this up once per target.

All targets at a glance

TargetSourceResultRuns and is debuggedDismonite
Windows, Intel 32 bit.format pe
.arch i386
PE32 (.exe)on this computerdisassemble, debug
Windows, Intel 64 bit.format pe
.arch x64
PE32+ (.exe)on this computer through the helper process asmodbgx64disassemble, debug
Windows on ARM, 32 bit.format pe
.arch thumb
PE32, Thumb-2on a Windows on ARM computer (debug server asmodbg)disassemble, debug
Windows on ARM, 64 bit.format pe
.arch arm64
PE32+, AArch64on a Windows on ARM computer (debug server asmodbg64)disassemble, debug
DOS.format binary
.arch x86_real
.COM or .EXE (MZ)in QEMU with FreeDOSdisassemble (MZ), debug
ARM Linux–ELF (from other tools)in QEMU (Raspberry Pi OS)disassemble, debug
Raspberry Pi Pico.target pico
.arch thumb
binary, UF2on the board over a debug probe–
Raspberry Pi Pico 2.target pico2
.arch thumb or riscv32
binary, UF2on the board over a debug probe–

Windows: PE files for Intel and ARM, 32 and 64 bit

With .format pe the assembler writes a finished Windows file: DOS stub, PE header, sections and import table. The source holds only code (.code), data (.data) and the functions it needs from DLLs (.import). No linker is needed.

32 bit64 bit
Intel.arch i386: PE32, machine 0x014C; arguments on the stack (stdcall, cdecl).arch x64: PE32+, machine 0x8664; arguments in rcx, rdx, r8, r9
ARM.arch thumb: PE32, machine 0x01C4 (ARMNT, Thumb-2); arguments in r0…r3.arch arm64: PE32+, machine 0xAA64; arguments in x0…x7
Intel, 32 bit (examples\windows_intel\hello_i386.asm)
.format pe console
.arch i386
.import msvcrt.dll printf, exit

.code
start:
    push dword msg      ; the argument on the stack
    call [printf]       ; through the import table
    add esp, 4          ; printf does not clean up
    push 0
    call [exit]

.data
msg db 'Hello, World!', 10, 0
Intel, 64 bit (examples\windows_intel\hello_x64.asm)
.format pe console
.arch x64
.import msvcrt.dll printf, exit

.code
start:
    sub rsp, 40         ; shadow space, stack aligned
    lea rcx, [msg]      ; first argument in rcx
    call [printf]
    xor ecx, ecx
    call [exit]

.data
msg db 'Hello, World!', 10, 0

The same for ARM, with an explanation, is on the page Windows on ARM. .format pe gui makes a window program instead of a console program (messagebox_*.asm, window_*.asm).

Debugging. Asmonite debugs a 32-bit Intel program itself, on this computer. An x64 program runs under the helper process asmodbgx64, because Asmonite itself is a 32-bit program; this too happens on this computer (or on another one with the same debug server). ARM programs run on a Windows on ARM computer with the debug server asmodbg or asmodbg64, connected over ssh or directly on the network; on the ARM computer itself also locally. Before each start Asmonite checks the file it made: header, sections, entry point and whether the imported DLLs and functions really exist.

DOS: .COM and .EXE in QEMU

With .format binary and .arch x86_real Asmonite writes 16-bit code for real mode, byte by byte as it stands in the source.

.COMNo header, only code. DOS loads the file at offset 0x100 of a segment; section 0x100 counts the labels from there. Code, data and stack share 64 KB. Example examples\dos\hello_com.asm.
.EXE (MZ)The MZ header is in the source, written with dw: size, memory needed, start (CS:IP) and stack (SS:SP); several segments with segment. Example examples\dos\hello_exe.asm, with every field explained.

Debugging. F9 puts the program on a hard disk image and starts QEMU with FreeDOS; the helper dbgload.com loads it there, and the debugger stops at the first line. Breakpoints, steps, registers and memory work as for Windows programs; a second run needs no new boot. qemu\run_freedos.bat gets the FreeDOS floppy once, QEMU itself is set up with qemu\install_qemu.bat. Dismonite opens finished DOS programs (MZ), finds code, data, jump tables and the end of the program and lets you mark regions by hand.

ARM Linux: ELF programs in QEMU

This target belongs to Dismonite: it reads ELF files for 32-bit ARM, as GCC or another compiler makes them on Linux, and debugs them in a Raspberry Pi OS that runs in QEMU.

Raspberry Pi Pico and Pico 2

With .target pico (RP2040, Cortex-M0+) or .target pico2 (RP2350, Cortex-M33 or RISC-V Hazard3) Asmonite writes the bytes for the board and checks them: the allowed instructions, RAM and flash, the boot2 block on the Pico, the IMAGE_DEF block on the Pico 2. F7 puts the program into the RAM or the flash over a CMSIS-DAP debug probe and stops at _start, without OpenOCD and without an SDK. Without a probe it goes onto the BOOTSEL drive as a UF2 file.

The page of the Raspberry Pi Pico →

Next

Syntax

Labels, constants, expressions and all directives.

The syntax page →

Examples

The small programs for each target, with their result.

The examples page →

Download

One ZIP with everything; unpack, start, done.

To the download →