Top
Best
New

Posted by guybedo 5 hours ago

Frame – Linux X server in Assembly(isene.org)
112 points | 66 comments
adrian_b 2 hours ago|
When first looking at the source code, I wondered why one would waste so much time to write 25k lines in raw assembly language, but then I saw that it was generated with Claude, for whom it does not matter much how expanded is the written text.

If someone had written this program manually, the strategy would have been very different. With a good macro-assembler (and nasm is good enough) one should define a great number of macros, to encapsulate all the tedious boilerplate, especially for things like function prologues, epilogues and invocations.

With a well written macro library, an assembly program can be almost as compact as a C program, instead of containing many text lines for each equivalent high-level language statement.

Such an assembly source with good macros can be read and understood much more easily than raw assembly language, like in this "frame.asm".

Otherwise, this is interesting work.

kees99 2 hours ago||
Claude has surprisingly good knowledge of X11 protocol.

The other day, colleague showed me a (pretty basic) terminal emulator written in one-shot by Opus. Kicker is - that was compiled to a 30 KB static binary. That's right. No libX11, no libXfont, not even libc.

amszmidt 51 minutes ago|||
Only because the X Window System is very heavily documented, e.g., in the excellent "The Definitive Guides to the X Window System Series".
glitchc 2 hours ago|||
No libc? It used inline assembly routines?
kees99 1 hour ago|||
Yes, something like this:

  static inline long read(int fd, void *buf, long count) {
    register long rax asm("rax") = __NR_read;
    register long rdi asm("rdi") = (long)fd;
    register long rsi asm("rsi") = (long)buf;
    register long rdx asm("rdx") = count;

    asm volatile(
        "syscall"
        : "+r"(rax)
        : "r"(rdi), "r"(rsi), "r"(rdx)
        : "rcx", "r11", "memory"
    );
    return rax;
  }
asveikau 30 minutes ago||
The linux kernel also has its own headers (IIRC it was something like <asm/unistd.h> and/or <sys/syscall.h>, but might depend on architecture and version) where it will provide the stub asm statements.

In my memory the syscall ABI has changed a few times (i386 had int $0x80, then sysenter, then abstracting it in the vdso, then amd64 has 'syscall'), so it may be easier to let the kernel header provide the mechanism.

Chu4eeno 1 hour ago|||
It's quite easy to get it to do syscalls directly, I even got Fable to do a simple standalone TLS implementation (in C). Not really useful since it hardcoded a set of supported algorithms etc., but it's fun to see how "simple" you can force it to go.
Aurornis 1 hour ago|||
It’s an interesting strategy, but I question how much it pays off, if at all. Very few parts of a program benefit from manually tuned assembly compared to the naive C implementation. Writing everything in assembly adds an extra layer of thought, which even for an LLM is additional effort that could have been used for targeted optimizations instead. It makes it harder to notice patterns that have been trained into the data set, from security problems to performance opportunities.

On a long enough time frame with enough tokens invested there’s probably not a difference, but being written in assembly by an LLM doesn’t imply optimal to me. I’d almost prefer having an LLM rely on higher level abstractions offered by a programming language rather than rolling everything itself. After reviewing a lot of LLM code, even at Fable and Sol levels, I just don’t trust that LLMs are writing optimal code. Assembly makes it harder to even review.

I do it find it very fun and entertaining. This is a component and I’m grateful that it was shared.

cogman10 24 minutes ago||
It will make the code slower.

Writing maintainable assembly is at odds with writing fast assembly in most circumstances.

A key optimization that's hard to pull off is inlining.

An optimizing compiler can see that a method is small enough that it can be pulled into the caller, it can then further eliminate from that smaller method branches that can't be executed due to the nature of the caller (Imagine calling a function with a `bool` parameter and you send in `true` at the call site).

To make the code faster in hand written assembly, you have to do the inlining, but that makes writing more structured code a lot harder. You are duplicating logic paths in the name of performance.

Not to mention the fact that the compiler gets updated and knows about more instructions and architectures then you do or then you could have. Hard to write the FMA instruction if it didn't exist when you were writing the assembly in the first place.

casey2 1 hour ago|||
Once you create an abstraction (like a macro, routine, language) you forfeit the benefits using machine code gives you wherever you use that abstraction, since there could be some bespoke implementation that solves the problem.

That entire point is moot here because the abstraction in this case is a massive ball of crap and it's used everywhere. So you never get the benefit you think you would for using a lower level language. That's why generally LLMs are best with python and even better with a "harness" (domain specific framework and language)

tty456 2 hours ago||
Sounds like another prompt is in order to re-write the code
bogwog 1 hour ago||
> I wrote my own

I see the growing trend of words losing all meaning is still going strong in 2026. I wonder what human communication will look like in the near future?

QwenGlazer9000 1 hour ago||
You're absolutely right!
ape4 37 minutes ago|||
I wrote my own.... symphony, novel, programming language, etc
xkriva11 37 minutes ago||
Reminds me this meme: https://pbs.twimg.com/media/HNIjjQQasAA77yl.jpg
ozhero 3 minutes ago||
This is the very definition of "scratching your own itch" lol.

Very inspiring and I applaud your efforts.

I haven't written assembler in years but this inspires me to do a small project for the fun of it.

yjftsjthsd-h 3 hours ago||
I am loving the shift from 'X11 is too big and messy to ever reimplement' to 'there are multiple wildly different X servers being built from scratch'.

Also, has anyone run it successfully? I got as far as building and running with --display and then running `DISPLAY=:7 dwm` and `DISPLAY=:7 alacritty`, but I can't seem to focus the window to actually type. Given that the author posted a picture of the thing actually running a live environment and claims to actually be using it, I'm pretty sure this is a me problem but I haven't been able to figure out where it is. Mouse works, too.

vidarh 2 hours ago||
Yeah, I have a mostly-functioning X11 server in Ruby, myself (not anywhere public yet).

Isene and I have relatively similar philosophies on this, except I have Claude burning tokens on optimizing and fixing my Ruby compiler now because I still want things in a high-level language, and my entire stack is Ruby instead of asm. But I love what he's doing - I just don't love x86 asm...

Turns out a functioning X server is a relatively simple piece of software. It's mostly just tedious. And most of the bulk is protocol handling that Claude can handle really trivially.

Kelteseth 2 hours ago|||
> 'there are multiple wildly different X servers being built from scratch'

by claude code. So this was only possible since no human had to bear looking at X original source code.

bogdan 2 hours ago||
Try running `tile` as a wm. I imagine it's not fully compliant to support dwm.
yjftsjthsd-h 2 hours ago||
Huh. So it's not the window manager. It's individual applications that are working or not.

Working: tile, dwm, pcmanfm-qt, feh, dmenu, glass

Not: alacritty, st

So... Thus far, anything but a terminal other than glass. I'd think the problem was alacritty doing fancy things with APIs that frame doesn't have, but st??

ToyKeeper 3 hours ago||
It's funny to see someone using a LLM as a compiler, making it convert higher-level operations into assembly, instead of just using a compiler.
vitally3643 30 minutes ago||
Given how few programmers very seriously write lots of assembly, it's kind of astonishing how good LLMs are at working with assembly. They can compile and decompile all on their own with apparently very little effort.

I suspect (with zero proof or understanding) that this has something to do with how well C maps to assembly. It's not a stretch to say the model's vector space maps this chunk of assembly with that line of C. And we all know how much C code exists online.

pjmlp 2 hours ago|||
Eventually that will be the way, revenge of COBOL and 4GLs.
duskwuff 43 minutes ago|||
"Congratulations! You've reimplemented compilers, except slower, less reliable, hopelessly proprietary, and you have to pay to use it."

(Oh, and the "compiler" will also refuse to operate on certain types of programs.)

idiotsecant 1 hour ago||
There is evidence that LLMs are capable of making assembly that runs a great deal more efficiently than the compiler can manage on its own.
wild_egg 1 hour ago|||
There are a ton of optimization opportunities that hinge on the intent of a piece of code which static compilers can never detect at scale. LLMs can actually navigate that and write surprisingly optimal assembly.

I've had all my side projects being written in x64 for the last 6 months and it is shockingly effective.

kibwen 1 hour ago||||
The purpose of an optimizing compiler is not merely to produce efficient assembly. The goal of an optimizing compiler is to produce efficient assembly while confidently preserving a program's observable logical semantics. Asking an LLM to spit out raw unstructured assembly based on inferred context from a specification given in English is a contender for one of the worst ideas I have ever heard; I award you no points, and may God have mercy on your soul.
vitally3643 21 minutes ago||
Code is code my dude. If an LLM can turn English into Python, there's really no reason it can't do assembly. Assembly is not magic, it's just code that humans find difficult to grok. LLMs, it would seem, don't have the same kind of trouble understanding assembly that humans do.

Have you ever compiled something by hand? You should try sometime, it's an illuminating experience. Humans find it hard because you have to remember a lot of details while simultaneously paying attention to a different large set of information while also generating instructions. It's tough, but not impossible, it takes humans a lot of time and effort. How might a computer fare if it could remember everything and pay attention to multiple inputs and outputs at once? That's what an LLM does.

Agingcoder 1 hour ago||||
Do you have references ?
throwaway613746 1 hour ago|||
[dead]
dlojudice 1 hour ago||
How many times have people posted here about how software is no longer optimized because CPUs keep evolving, making programmers lazy? It seems things have changed. The question is: will LLMs manage to squeeze the most out of this hardware, better than compilers do? In the few tests I’ve run, yes, a lot.
jcs 1 hour ago|
Most of the gain seems to come from choosing a much smaller program. Frame implements enough X11 for this one desktop and leaves out decades of compatibility work that a compiler would still have to preserve.
Quitschquat 55 minutes ago||
I'm a prolific vibe coder too, but I'm not going say I WROTE MY OWN Emacs for Commodore 64.
NetOpWibby 2 hours ago||
Beautiful. Using LLMs to create perfect tools for yourself is my favorite thing about them.

No dependencies and better performance? Fantastic.

asveikau 47 minutes ago||
I can have a machine generated X server in assembly too. It's called cc -s.

Or:

   $ objdump --disassemble /usr/lib/xorg/Xorg
Maybe I'm getting too old for this, but I really don't see the point in having AI generate assembly code for this.
gen2brain 2 hours ago|
I would like to see a similar project that fixes Wayland. Like, can someone vibe-code window positioning, add SSD to GNOME (damage was already done, but still), and add the ability to send events so you can automate and drive the app offscreen for testing.
edumucelli 2 hours ago||
OMG, yes, please, get rid of all those composers, all that mess that people are doing. X11 is 40 years of battle testing. Wayland in 22 years (it already has 18) will be 100x worse than X11.

A Dockbar I am working on https://github.com/edumucelli/docking/ is a pain to build on Wayland. It already supports a lot of composers and even mutter/gnome with that Gnome shell extension, but at what cost ...

Chu4eeno 1 hour ago|||
One of the issues with Wayland is that it forces every compositor to reimplement the X server, badly.

So you can't really "fix it", short of patching e. g. Gnome's compositor, with patches that will never be accepted upstream.

fc417fc802 3 minutes ago||
It's also an 80% solution, the same thing so many rust "rewrites" are notorious for. Sure it finally mostly works at this point. Mostly. But it took a decade of kicking and screaming to get here and there are still edge cases that don't work, many clearly viewed as wontfix simply because there isn't enough popular support to force the hand of the purists. Hopefully llms make a community bootleg wayland protocol effort viable.
More comments...