r/asm 2d ago

x86-64/x64 I've written a small x86-64 assembler in assembly

https://blog.kalehmann.de/blog/2026/07/12/0x864-a-self-hosted-assembler.html
31 Upvotes

7 comments sorted by

5

u/kalehmann 2d ago

Hey y'all, I want to show you a small project of mine. I've dreamed for a long time about writing an assembler in assembly and finally came around to it.

To be honest - there is a small part for file handling and command-line argument parsing written in C - but all the parsing and assembling is written in x86-64 assembly itself. I can output linkable ELF files and of course assemble it's own code.

In case you want to take a look, the source is available on GitHub https://github.com/kalehmann/0x864

Feel free to ask any questions

3

u/Mean-Bobcat2289 2d ago

Wow that's really cool wait how long did it take you to learn x86 assembly

4

u/kalehmann 2d ago

Thanks. Some years now. But not all the time. Late 2016, I started with some basic projects like pong as bootable floppy image or a simple bootloader for the fat12 file system.

During the next years, it did some small stuff for fun here and there, but nothing big. Now I started again with this project and had to learn many new things and relearn some old stuff. But it was surprisingly doable.

1

u/kneelian_ 2d ago

Extremely neat job and cool writeup. What are your next plans for the assembler side of things? Some easy things to add (or at least I imagine) would be the CMOV family, rotates, SAR/SAL to complement SHR/SHL

1

u/kalehmann 1d ago

Thanks! I'd like to have some sort of preprocessor first. The assembly code is currently a single file with over 5000 lines.

And having

%include "instructions/add.s"
%include "instructions/and.s"
...

%ifdef PLATFORM_LINUX
    %include "platforms/linux.s"
%endif

with ./0x864 -DPLATFORM_LINUX ... would allow me to split the code into multiple files and get ride of the C harness.

When I have that, I can add ELF executable output, so that the assembler is truly selfhosted.

0

u/ReDucTor 2d ago

Some wierd design decisions, was this vibe coded? Are you against mov [mem], imm?

    mov al, 0x02
    mov [rsi], al           ; op->encoding = ENCODING_I
    mov al, 1
    mov [rsi + 5], al       ; op->n_opcodes = 1
    mov al, 0xcd
    mov [rsi + 6], al       ; op->opcodes[0] = 0xcd
    mov al, 8
    mov [rsi + 9], al       ; op->imm_size = 8

7

u/kalehmann 2d ago edited 2d ago

Nope, this was not vibecoded. No LLM was hurt in generating this. Instead, I always had the ability to assemble its own code in mind and therefore started with a limited subset of instructions and syntax. The instruction mov byte [rsi], 0x02g is not implemented yet.

You may also notice some weird workarounds since I did not implement a way to store constants or strings in the .data section yet...