Files
whitemagic/openspec/changes/whitemagic-foundation/specs/managed-assembler/spec.md
T
2026-07-21 22:30:10 +02:00

2.4 KiB

ADDED Requirements

Requirement: IAssembler abstraction with no native dependency

WhiteMagic SHALL define an IAssembler seam that produces machine code, with a default backend that has no native or third-party dependency. FASM MUST NOT be referenced by the default configuration.

Scenario: default backend is dependency-free

  • WHEN WhiteMagic is built in its default configuration
  • THEN no reference to FASM or ManagedFasm MUST be present in the output

Scenario: backend is replaceable

  • WHEN an alternate IAssembler implementation is supplied
  • THEN execution and injection MUST use it without other code changes

Requirement: Hand-emitted calling-convention stubs

The default StubAssembler SHALL emit call trampolines for the cdecl, stdcall, thiscall, and fastcall conventions — pushing/placing arguments, calling the target, cleaning the stack per convention, and returning — for both x86 and x64 targets.

Scenario: cdecl stub encoding

  • WHEN a cdecl call stub for a function with N 4-byte arguments is emitted (x86)
  • THEN the bytes MUST push the arguments in reverse order, call the target, add esp, N*4, and ret

Scenario: stdcall omits caller cleanup

  • WHEN a stdcall stub is emitted
  • THEN it MUST NOT emit a caller-side stack cleanup (the callee cleans)

Scenario: x64 uses register argument order

  • WHEN an x64 call stub is emitted
  • THEN the first integer arguments MUST be placed in the platform argument registers before the call

Requirement: Byte emitter primitives

StubAssembler SHALL provide little-endian emit primitives (EmitU8, EmitU32, EmitU64) used to hand-assemble stubs deterministically.

Scenario: little-endian 32-bit emit

  • WHEN EmitU32(0x11223344) is called
  • THEN the appended bytes MUST be [0x44, 0x33, 0x22, 0x11]

Requirement: Optional Iced backend for arbitrary assembly

WhiteMagic SHALL provide an optional IcedAssembler backend that assembles arbitrary x86/x64 mnemonic text to machine code for callers who require runtime text assembly.

Scenario: arbitrary mnemonics assembled

  • WHEN the Iced backend assembles "push 0\nadd esp, 4\nret" at a given origin
  • THEN it MUST return the corresponding machine code bytes

Scenario: origin-relative encoding

  • WHEN assembly containing a relative jump is assembled at a specified origin address
  • THEN the encoded relative offsets MUST be correct for that origin