My Login Shell in Assembly
14 points by isene
14 points by isene
Nobody wants to read about something you couldn’t be bothered to write.
wtf.. why is this level of hate not only tolerated but upvoted here? Absolutely shocking, this place has been allowing this festering for a while but this is disgraceful
Hate? How is this hate speech? I come here to read about people's own work, not AI slop plagiarism.
Allowing vibecoders to fill this place with spam was a mistake, not allowing me to say I don't like it.
I don't think it's hateful, but your assertions about what the entire community wants have no place here. I have flagged your comment as "unkind" twice, because your misguided belief that you can speak on behalf of everyone is unkind. Somehow my flags have been revoked, so I will flag again.
Please continue sharing your own opinions, without nasty qualifiers that nobody else wants things you dislike.
Yeah, I think I'm far from the only one with my opinion.
Right, so now you reframe "nobody" as "I'm far from the only one". I expect people who understand programming and logic to do better than this. If you want to express some shifty incongruous boolean distortion, take it elsewhere.
Flagging has been broken for the last three weeks, 1967 and 1991 are the two open tickets. 1980 is an open PR to fix the issue.
I'd prefer the site block submissions with both the show and vibecoding tags. That combination is one of the few places where personal attacks are permitted, and that's not a good look.
@pushcx: seriously, can I get some clarity here? This feels frankly libelous to call my comment hate speech.
Your comment was not called "hate speech". Your comment was described as (possessing a certain level of) "hate". These are two different things; not all hate (an emotion) is hate speech (a legal term). I'm sure you understand this.
I actually find this interesting. It adds to my line of research into the philosophy of free will and the binding that identifications have on a person.
the way people are behaving and communicating here recently is unacceptable, it's unconstructive, it shuts people down, it comes from fear and misunderstanding - for intelligent people it's shameful. you may be used to the harsh mannerisms of the way people in some domains communicate but to me it's not 'interesting' behaviour, it's people putting aside basic decency, no one should be spoken to the way you were spoken to here in any forum, let alone one that is about discussion of technology by leaders in that field.
I sense a real Luddite feel on almost all forums. This place is no exception. When people identifies with the process and the process seem under attack, their identity feels attacked. And then there is the real concern that the Luddites had - of losing income. Both may result in defensiveness masked as quality concerns.
Tangential, but related to Luddism and technology today: Blood in the Machine: The Origins of the Rebellion Against Big Tech. I enjoyed the book immensely. EDIT: The pretense of detached interest in the parent and related posts I find weirdly condescending. I actually find it interesting whether it has its own influence on the discussion.
I'm way above your petty complaints. They don't bother me at all, in fact I hardly even notice them, and anyway I'm doing this all as a social experiment. Tell me about your relationship with your father.
(it's an extremely ancient pattern on the internet)
Wait, who is this? Sock puppets are not allowed. EDIT: I did not read this as you intended it to be read, in another's voice. I retract the previous thick-headed statement with apologies: you are not a sockpuppet, you are a funny person.
Regardless, the tone has gotten away from us all in this thread. So, back to balance and substance: I like people working on shells; I love following oils for example. Bravo for that choice of project. For this particular post, I think more technical detail in would have been interesting to me personally, and would have made the role of vibecoding more palatable. Perhaps following up with more focused discussion expanding on what you've learned about "exactly what the shell does" would pull people like me into a series of posts on the project.
The problem with posting on 17 levels of irony is that I can't tell if you're seriously accusing me of being a sock-puppet of Mr. Only-Posts-Self-Promo OP, or not :)
before dismissing this, please take a look at the ruby and the rust shells. just ignore the vibecoding experiment.
There's nothing to ignore. All the comments are "coauthored" by Claude.
I'm not going to try and judge how much of this was human effort because frankly, it's not worth my time. I'm here to see real humans' work. Every commit says "some unclear amount of this was not made by me"
I'm not going to try and judge how much of this was human effort
Then don't.
That’s what I’m saying. I see no indication that the OP did more than ask Claude to do all the work. And I’m not going to go looking for it.
Therefore: this is spam with no value to anyone.
I could have done this myself and gotten a similar result, and it wouldn’t be any more or less worth reading or talking about than this.
This is really cool... and I hate to take away from that. I hate to be that guy... but I'm about to.
I thought it was extremely impressive that somebody wrote a shell in assembly, so before reading the article I opened the repo to check it out. I looked past the blatantly LLM generated README and to my dismay I saw that every commit is coauthored by Claude.
Now, yes this is a finished product, and it is still cool, but the "wow" factor of this for me was the fact that someone wrote it in assembly. Now that I see Claude is in the mix it's just... How much of it is the author's genius and how much of it is just Claude now I will never know. Sorry.
Also, the body text of the blog post is also shamelessly LLM generated. The blantantness of it is what gets me, no attempt to hide the obvious LLM prose in the writing.
Noting it is also completely my fault that I didn't read the article first to see that Claude was heavily involved.
I mean no disrespect to you, the author, personally, and maybe I'm out of line on this one, but I'm kind of tired of this.
i feel your fatigue and the raw frustration of people here. This isn't your fault, it's not the fault of the poster, it's a gross failure of moderation and constructive community management here and every on both sides of this needs to start calling it out. I'm looking at you @pushcx because I don't see anyone else moderating this space. Letting a community violently fight amongst itself without drawing a line in the sand is like keeping a little experiement for yourself in a petri dish and taking delight in the fight. That would be fine if it was a biology experiement in a petri-dish, but this is really people starting to be violently unhappy with each other in a way that the community doesn't have guardrails for. There are two very valid things the community can do but it requires coherent, firm management:
The middle ground of not taking either of these actions is, for the person/people who manage this space not less than disgraceful.
Good response, he deserves to be called out. This is not okay.
I am curious as to why you think it is not okay. Would you care to elaborate?
It's common to say that George Vanderbilt "built" the Biltmore Estate, and in a way, that is true, but another way of looking at it is that he simply financed the building of the Biltmore Estate, it was Richard Hunt who designed the house, and Frederick Olmsted (of New York's Central Park fame) who designed the landscaping, and thousands of unnamed workers who did the actual construction and landscaping. Yes, Vanderbilt also talked with Hunt and Olmsted about what he wanted, but aside from that, he didn't do any actual work.
The same could be said of your login shell. You specified what you wanted, and maybe even financed it, but didn't do the actual programming work itself. Some (like myself) might find it distasteful for you to say you "wrote it," while others might let it slide---you conceived of the idea so that's the important thing, not who (or what) worked on it. My girlfriend loves the work of glass artist Dale Chihuly, but Chihuly doesn't actually do the glass blowing---he has an entire team who do the actual work. So is Chihuly an artist? I say no, because he doesn't do the work and I don't think he gives credit to his workers; my girlfriend says yes, because he directs his team (his tools, so to speak) to do the work. Who's right is subjective (I think).
As Les Orchard said:
Before AI, both camps were doing the same thing every day. Writing code by hand. Using the same editors, the same languages, the same pull request workflows. The craft-lovers and the make-it-go people sat next to each other, shipped the same products, looked indistinguishable. The motivation behind the work was invisible because the process was identical.
Now there's a fork in the road. You can let the machine write the code and focus on directing what gets built, or you can insist on hand-crafting it. And suddenly the reason you got into this in the first place becomes visible, because the two camps are making different choices at that fork.
I labeled the post here as vibecoding, I clearly wrote it in the blog post, the README and every single commit. And have never passed the shell bare as anything else. Another's comment of plagiarism is funny since it is a direct copy of my work, rsh (Ruby-shell) that I have been hand-coding for years.
And so I am still waiting for what someone think is "no okay". Could it be that it would not be okay to make bare on my own spare time? Or not okay to post about it on my blog? Or not okay to link to it here (even though I clearly flaired it as vibecoding). What exactly is "not okay"?
Vibe coding here is a touchy subject. Some here push it as the way to only program going forward (the "make-it-go" camp) and are happy about that, while others had to be banned for their own health due to the existential depression it caused them (the "craft-lovers" camp, and will hate this project). It's a polarizing subject.
As for the project itself---can you not write Rust that doesn't rely upon its standard library? (I don't know Rust, so I don't know the answer) Implement the system calls yourself? I know you can do this with GCC, compiling with -static -nostdlib (and either write some minimal assembly code to do the system calls directly, or using GCC's hideous __asm__ syntax). Did you not think (or know) of that? Did Claude Code not even suggest that? This is a downside I see of LLMs---they aren't creative and thus, part of the solution space isn't even considered.
rsh (Ruby-shell) that I have been hand-coding for years.
I wanted to check that claim, so I took a look at the repo. You started writing it in late May 2023, so yes, "years" could apply. But "hand-coding"? One year in and you are using Claude Code, which is something I would not call "hand-coding." At this point, I wouldn't consider rsh to be hand-coded. But do you consider it hand-coded because that's how it started? I'm not trying to do a "gotcha!" moment here, I'm honestly curious.
Another question for you---is Chihuly an artist?
I started using CC in June 2025, so that was 2+ years of handcoding rsh. Then I did bugfixes and ironing stuff out and adding functionality with CC since then. Then I ported it to Rust with CC (named rush) then to pure assembly as the OP points to. Point is - you really can't go more bare than asm. It is the fastest you can go. Anything on top of that is beyond pure syscalls. There are garbage collection, abstractions, libs. Rush is 25x the size of bare in RAM and bare is 3x faster. And the whole project fits easily into the CC context window, meaning it cranks out code faster with next to no bugs. This is ideal for me since I want a lightning fast shell that I can get functionality and changes to in minutes. It is the perfect shell. For me. It was pure fun to produce. For me. People may think I'm having fun the wrong way, but I really couldn't care less. I do all this for me, and then I release it in case anyone else like to use it or have it as inspiration. The luddites I ignore.
I apologize, you did do 2+ years of hand-coding (I can't math, that's why I use computers).
First, you said:
I am curious as to why you think it is not okay. Would you care to elaborate?
Even though I'm not the one you asked, I did try to elaborate, and then you go
The luddites I ignore.
So which is it?
I wondered if he had a real concern. I couldn't conclude he was a luddite of the bat like that.
I have had similar feelings of losing the "wow" factor after realizing something was written with/by an LLM. The list of things I've wanted to make or write because I thought it would be interesting is long, but when I contemplate having them all finished before me I recognize that the journey is the important part for me. That is where I would feel the sense of accomplishment at doing something new or novel, even if entirely unnecessary. To have them in hand without experiencing the creation process would remove their value.
It feels like Lord of the Rings was shortened to taking the Eagles from the Shire to Mt Doom and back again in 3 chapters.
Oh man I totally agree with all of this. Have come to a similar realisation myself about the journey being very important for me.
I have a number of rough, unfinished, projects I'll never finish that will probably never see the light of day because they're useless in their current state. But man if I haven't learnt heaps from making them.
There's nothing genius about coding in assembly. It's just slow, delicate and fragile. LLM is a good tool to take away find of the pain.
To me your overshooting in both directions.
Also to the author, I think having an asm implementation as a reference, this would be a good spot to optimize the Rust version. Eg link with musl + lto, then keep comparing and trimming.
I had a similar feeling, including where I wonder if it is me that is wrong.
Would it have been different if the author had framed the whole story differently? e.g. look, I thought it would be cool to have a shell written in asm, and I used a LLM to do it; this is the outcome, big disclaimer if you use it!
If they are using it and it makes them happy, that's great. I've written plenty of scripts that I use (no LLM required), and despite they work for me, I wouldn't share them!
Checking the code, it assumes 64-bit pointers and ints, so is not portable (considering that is ASM it may not matter). I wonder why the author (or the LLM) didn't use structs instead of just a magic numbers getting the result of syscalls, as it doesn't feel maintainable. But then I got to the part where the CLI flags are checked and it is a bit spaghetti, instead of using a reusable function to compare strings, and it makes sense that it is what it is.
I wouldn't use it, and I don't think is useful as learning material either. Yet, it is a custom made tool for one user, and that's OK.
It seems hopeless. No matter how many long threads we have on here, asking people to stop posting slop, or flagging it, there is a group that can't or won't hear the message.
I can't tell if they're thinking "but mine is the exception" or if they post but don't read. Elsewhere in the comments, people will pretend they were unaware, and get defensive. The slop can be produced faster than the requests to stop. How does a community defend against that?
It's interesting to see the comments here. And let me address the bulk of them in this manner:
I want the best shell possible, for me. The best filemanager possible. For me. The best messaging client, astronomy tools, imdb client, calendar app, etc, etc. I live in the terminal, hence cli and tui. (When I code for fun, I code Focal or MCODE. And that's also fun. For me.) And for me it is pure fun to get the tools exactly like I want them - regardless of how it is made. No more installing software that almost fits my bill. Now I get software that is completely tailored to my specific needs. I may have fun the wrong way, but this is the way I feel. And for 25 years I have been giving away all my code because my sole reason for existence is helping others. And while this is now my daily login shell, I hope nobody else use it. Why? Because they should instead clone the repo, fire up CC and create their own based off of it - or from scratch.
PS: I wrote the post myself - but obviously got my automated buddy to push it ;)
You gotta ignore the haters, they’re just having a hard time adjusting to change. I imagine there was similar repetition in the voices of the past as other step changes of software /hardware changed
If you wrote this manually, then you should recalibrate, the style is extremely LLM-gilded, it feels like half of it came straight out of an LLM's webchat.
I don't care if you use AI to help you do stuff faster, I'm saying this as someone who appreciates being able to throw LLMs at niche tasks that I never had the time for before, like texture synthesis and task-specific 3d model preview tools. As-is, I don't want to read this, it feels like claude wrote most of it. If I want to read something that's mostly AI output I would go talk to gemini or claude myself.
LLMs are frightfully resistant to writing blogpost-style or announcement-style text without using the SEO marketing spam format, and that's what this post turned into. I looked at your older posts and they're MUCH better. This is the wrong direction to be going in.
bare terminates by signal SIGSEGV (Address boundary error) here as soon as I type the first character at the prompt.
What distro/terminal are you running? Also, does ./bare -c "echo hello" work (non-interactive mode)? That would help narrow down whether the crash is in terminal setup or the line editor.
I am using the kitty terminal on ArchLinux.
When I launch bare it prints a tip and displays the prompt. The first character I type is echoed to the terminal before the crash. Whether the ~/.bare_* configuration files are present or not doesn't affect the experience. Also, the environment inherited from the underlying shell (fish) from which bare was launched, doesn't seem to be the culprit.
Running bare -c 'echo hello' works (but bare -c 'echo $(date)' just prints $(date) without evaluating the $(date) construct, but that's another kettle of fish).
Thanks for the report. Could you run this and paste the last ~20 lines?
strace -f ./bare 2>trace.log
(type one character, let it crash, then tail -30 trace.log)
That will show us exactly which syscall or memory access triggers the SIGSEGV.
Also, can you confirm you're on x86_64? (bare is pure x86_64 assembly, it won't work on ARM.)
I have posted the trace in https://github.com/isene/bare/issues/1
Yes, I'm on a x86_64, and I just invoked the Makefile to build the binary.
Thanks for the strace. The crash address 0x244ba14 is outside the binary's address space, so a return address on the stack is corrupted. Could you run this:
gdb -batch -ex run -ex 'info registers' -ex 'x/i $rip' -ex bt ./bare
Type one character when the prompt appears, and paste the full gdb output. That will show which instruction is crashing and the register state.
Also, could you check: nasm --version and readelf -h bare | grep Type
It would be interesting to benchmark this against some statically linked shells (e.g. busybox, bash-static). But it's also worth trying to see if you can't achieve similar startup speeds by either building a c project with no libc (or maybe even rust with nostd?).
(also not to dogpile, but the LLM writing is obnoxious. I think LLM generated code allows for some really interesting possiblities, but I would rather read a human written bullet point list than the default LLM voice. I haven't tried this myself, but maybe a voice card would help? But regardless I want to read about the experiences of other people, not an LLM's perception of someone's experience.)
I reviewed some of the code and it appears that this project has exceeded what the LLM can handle reliably.
There are 48 cases of popping and then pushing the same register, e.g. "pop (r\w+).*\n\s+push \1". This is harmless, but strongly suggests the LLM is confused about what registers are live.
pop rcx
push rcx
The LLM gave up at this label.
.ges_prefix_done:
; Copy name
pop rax ; restore fd to rax
push rax ; keep it on stack
lea rsi, [glob_dir_buf]
; We need to reconstruct the pointer to d_name
; Actually, we already have the entry pointer on the stack... let's just recalculate
; Get the current entry offset from the outer stack
; This is getting messy, let's use a simpler approach
pop rbx ; restore fd
jmp .ges_skip_entry ; bail out of the complex path case for now
There are also several cases (.hs_add, .hv_eq, .add_job) where strlen is called while masking the result; these are clearly bugs.
push rax
call strlen ; returns ignored result in rax
pop rax
Great code review. All updated in the repo and releases, with CC updated files to avoid similar patterns and bugs going forward. This made it well worth posting the project here. Thank you so much.
Very cool!
Any idea what accounts for the startup difference between the Rust and assembly versions?
How do you think the different projects fare on maintainability?
Did you direct Claude to your Ruby/Rust implementations to help implement this, or was this from scratch?
Damn. Someone with an actual question. Here goes;
The startup difference comes down to what happens before main(). Rust binaries go through the standard C runtime initialization, dynamic linker setup (unless statically compiled), and Rust's own runtime init. The assembly shell skips all of that; it's just a static binary making direct syscalls with zero initialization overhead.
I find that maintainability with my pure CC projects (bare and the Fe2O3 suite of rust apps) are much, much easier than my handcoded Ruby projects. I have been coding Ruby since 2003 and several projects with a hefty dose of OCD - which is why I have had very few bugs reported on my RTFM file manager since its inception, despite it racking up almost 130K downloads on Rubygems. But CC does an even better job with 3x less bugs reported on the code produced via CC. And the asm shell is even easier to maintain since 13K LOC asm is tiny and the whole thing easily fit into the CC Opus 4.6 1M context. CC is a lot better at maintaining anything than I ever was.
All the Rust tools were ported from my Ruby originals. I pointed Claude Code at each Ruby source and described what I wanted, feature by feature. I never read the Rust code myself; I work entirely through descriptions and screenshots, comparing side by side with the Ruby versions until parity is reached. The assembly shell was also built with Claude Code, from scratch, directed the same way.
This is so cool. ASM and raw syscalls w/o the manual maintenance burden!
Beside all the riff-raff of vibecoding discussions, what this demonstrates for me is a path where I could skip the waiting for some driver to be released or some feature to be shipped. I can just make it, anything I need.