<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: imtomt</title><link>https://news.ycombinator.com/user?id=imtomt</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Tue, 09 Jun 2026 20:20:39 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=imtomt" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>slowloris mititgations actually weren't too bad, just a couple syscalls to setitimer(), sigaction(), and setsockopt(). Range header parsing was awful, so was content length. I'd say all in all, probably Range headers. Just string parsing in general is pretty awful in assembly.</p>
]]></description><pubDate>Wed, 13 May 2026 23:03:55 +0000</pubDate><link>https://news.ycombinator.com/item?id=48128777</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48128777</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48128777</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Thank you. My favorite reasons for projects are "just because I wanted to" and "because someone told me I shouldn't", and this one ticks both boxes, haha.</p>
]]></description><pubDate>Mon, 11 May 2026 11:25:58 +0000</pubDate><link>https://news.ycombinator.com/item?id=48093618</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48093618</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48093618</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Oh wow! Your project was actually really inspiring to me, thank you for making this. I was really impressed reading through it a while back. Is it alright if I add a link to your repo in my README?</p>
]]></description><pubDate>Sun, 10 May 2026 23:10:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=48089106</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48089106</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48089106</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Aw, that’s too bad. Sounds like it was a really fun project.<p>Thanks for the tips on CGI! Definitely going to look into it more. The server-side execution of CGI scripts definitely interests me more than the CGI scripts themselves, so I’ll probably just look for some existing (simple) CGI scripts and work on building the env vars and executing them.</p>
]]></description><pubDate>Sun, 10 May 2026 22:21:45 +0000</pubDate><link>https://news.ycombinator.com/item?id=48088745</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48088745</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48088745</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>It would be possible, but impractical for where this project is now. In retrospect, I could have written it with more portability from the start, but since it was just a personal learning project I didn’t think too hard about it.
Aside from syscall numbers all being different (which would just require changing the consts in defs.S), syscall numbers are stored in the x16 register on MacOS vs x8 on Linux, and the kernel is called with svc #0x80 on MacOS vs svc #0 on Linux.
The bigger issue at this point is MacOS-specific syscalls. proc_info() doesn’t exist on Linux, so that would need to be rewritten. The sigaction struct also has different members (Linux doesn’t have sa_tramp), as well as every other struct having different offsets and sizes. getdirentries64() also doesn’t exist on Linux, it has getdents64() which is called differently and has different output as well I believe, so directory.S would need to be reworked too.</p>
]]></description><pubDate>Sun, 10 May 2026 21:02:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=48087987</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48087987</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48087987</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Woah! I honestly feel more intimidated writing a CGI script in assembly than I was writing a server, lol. CGI support has been on my mind for a couple weeks, but I haven't really dug into it yet. I'd love to see yours if it's hosted anywhere! Could be a great reference when I do.</p>
]]></description><pubDate>Sun, 10 May 2026 08:34:40 +0000</pubDate><link>https://news.ycombinator.com/item?id=48082086</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48082086</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48082086</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Yeah, that's what I realized during this, too. You need to be much more explicit, but the way any given function works isn't fundamentally different. "strlen" will always iterate through a string searching for a NULL byte whether it's in C, Rust, Assembly, or whatever other language. I think it can feel almost <i>more</i> straightforward than other languages, since you're laying out exactly what the CPU needs to do, in what exact order.</p>
]]></description><pubDate>Sun, 10 May 2026 07:31:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081804</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081804</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081804</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>That's so cool! I would love to see it if you're sharing it anywhere.</p>
]]></description><pubDate>Sun, 10 May 2026 07:23:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081763</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081763</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081763</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Yeah, I know MacOS syscalls aren't stable. Interesting point about Go, I hadn't heard about that. Unfortunately I'm a masochist though, and want to avoid libSystem.dylib as much as possible. The only reason I link against it at all is because MacOS requires it for executables to run, I never actually call into it. Figured I'd just update the syscall numbers if/when they change.</p>
]]></description><pubDate>Sun, 10 May 2026 06:00:36 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081391</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081391</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081391</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Honestly haven't benchmarked it, but I would imagine ymawky would be considerably slower than most fully-featured web servers. ymawky uses fork-per-connection, which is fundamentally slower than what production servers like nginx or Apache use. nginx uses event-driven IO (kqueue/epoll), which can handle thousands of concurrent connections without the overhead of forking the process on each request. Apache uses pools of threads which handle multiple connections without needing to be spawned per-request. A head-to-head against any other web server would mostly measure "fork-per-connection vs event loop/thread pools", which assembly has nothing to do with.<p>In a comparison between a similar fork-per-connection server written in C and this, I would imagine the throughput would be about the same, because the bottleneck in this model is fork() itself rather than the actual code. It probably matters more for binary size and startup time than requests/sec. Would be fun to actually benchmark, though.</p>
]]></description><pubDate>Sun, 10 May 2026 05:54:35 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081372</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081372</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081372</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Ahh you caught me. I just kept telling ChatGPT dot com "no, make it less efficient" and copied whatever output it gave me.
jk, thank you!</p>
]]></description><pubDate>Sun, 10 May 2026 05:24:09 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081235</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081235</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081235</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Woah, that's really cool! I'm glad you did that even if you didn't need to. I honestly think <i>everyone</i> needs to write more assembly, <i>because</i> it's so much cooler.</p>
]]></description><pubDate>Sun, 10 May 2026 05:18:14 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081208</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081208</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081208</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Honestly, just reading existing assembly to get a feel for how it works, and then violently googling everything that goes wrong. The ARM Architecture Reference Manual (aka "The ARM ARM") ended up being really helpful for looking up what specific instructions do and how they're called. Another really helpful tool is writing something in C/C++, and compiling with "gcc -O1 -S file.c" to see the assembly gcc generated. It helps to mess around a lot with smaller programs in gdb or lldb.</p>
]]></description><pubDate>Sun, 10 May 2026 05:08:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081165</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081165</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081165</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Thank you! This is one of the nicest things I've heard in a while.</p>
]]></description><pubDate>Sun, 10 May 2026 04:53:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081111</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081111</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081111</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Why stop there? Next, I'm prying open a CPU and poking the transistors with a 9V battery and paperclips to make it execute what I want. Slower, but you get so much <i>control</i>.</p>
]]></description><pubDate>Sun, 10 May 2026 04:47:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081089</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081089</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081089</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Thanks for the link, bookmarking. I should note ymawky's main portability issues are unfortunately at the syscall layer rather than the asm layer. proc_info() and getdirentries64() are pretty Darwin-specific, so making it portable would require reworking that whole area rather than adjusting register/calling conventions.</p>
]]></description><pubDate>Sun, 10 May 2026 04:37:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=48081044</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48081044</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48081044</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>I wrote it for MacOS because I don't have a Linux machine right now :( Once I get one up and running again, I'll probably work on porting this.<p>As for why it wouldn't run on Linux, there are some pretty big differences in the actual assembly. One pretty superficial difference is calling conventions -- MacOS uses the x16 register for syscall numbers, Linux uses x8. Calling the kernel in Mac uses "svc #0x80", in Linux it's "svc #0". That's ~120 lines that need to be replaced, but easy enough to just use sed. Syscall numbers are all different, as are the struct layouts for sigaction(), MacOS has an "sa_tramp" field that Linux doesn't have. Enforcing max processes is done here using the MacOS-specific proc_info() syscall, which can be used to get the number of children any given process has. Linux doesn't have an equivalent, so process tracking would need to be done differently. Finally, Linux has the getdents64() syscall, rather than getdirentries64(), which uses a different struct and is called differently.<p>I'm sure an LLM could make all those changes, but it's a pretty large codebase, so it would probably make some mistakes or miss things.</p>
]]></description><pubDate>Sun, 10 May 2026 04:21:48 +0000</pubDate><link>https://news.ycombinator.com/item?id=48080982</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48080982</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48080982</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Thank you! The thing about eventually building your own meta language ends up happening all the time with bigger assembly projects. I do have a fair few quality-of-life macros too, but probably fewer than I should. I did end up needing to implement by hand what would be standard functions, things like atoi, itoa, strlen, memcpy, streqn.<p>Higher level languages are more convenient for 99% of things, but the directness of Assembly gives me a rush unlike any other. I didn't live through the C64/Amiga, but I was obsessed with old C64/ZX emulators growing up.</p>
]]></description><pubDate>Sun, 10 May 2026 03:56:16 +0000</pubDate><link>https://news.ycombinator.com/item?id=48080865</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48080865</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48080865</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Hey, thank you! Means a lot. It's an odd sort of meditation, but is surprisingly the most almost-therapeutic project I've worked on. Something about the constraints of Assembly that really pull you into the minutiae and clears your head, maybe.</p>
]]></description><pubDate>Sun, 10 May 2026 03:40:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=48080790</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48080790</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48080790</guid></item><item><title><![CDATA[New comment by imtomt in "Show HN: Building a web server in assembly to give my life (a lack of) meaning"]]></title><description><![CDATA[
<p>Honestly, read the main file, ymawky.S first. Then I'd read through get.S maybe, checking parse.S on an as-needed basis for parsing-related functions. delete.S or options.S are pretty short, too, so give those a read too.<p>Modularizing it into multiple files was easier than I expected it to be, you basically have other functions/labels in other files, and mark them as .global at the top. The Makefile compiles each file into their own .o, which you then link all together. You can "b" or "bl" to any label from any other file, as long as it's global and linked together. Same with data in .bss or .data, mark them as .global and they can be accessed from elsewhere.</p>
]]></description><pubDate>Sun, 10 May 2026 03:36:06 +0000</pubDate><link>https://news.ycombinator.com/item?id=48080774</link><dc:creator>imtomt</dc:creator><comments>https://news.ycombinator.com/item?id=48080774</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48080774</guid></item></channel></rss>