Hacker News

Top stories

Live mirror
30 storiesupdated just nowView source snapshot
  1. Android 17 is the first since 3.x to add new APIs without releasing to the AOSP(grapheneos.social ↗)
    64comments
  2. Cloudflare Quick Tunnels(cloudflare.com ↗)
    190comments
  3. Apple releases iPhone Duo simulator and Xcode 27.1 beta(developer.apple.com ↗)
    18comments
  4. Korea raises data breach fines to 10% of revenue(koreajoongangdaily.com ↗)
    1comments
  5. Saving another 100TB of RAM with math (and Rust)(cloudflare.com ↗)
    7comments
  6. Cache-to-Cache: Direct Semantic Communication Between Large Language Models(arxiv.org ↗)
    3comments
  7. Photon-Emission-Guided Laser Fault Injection Enables RP2350 Secure Debug(ledger.com ↗)
    33comments
  8. Show HN: Cactus Needle 3: 8-29MB automation models can match DeepSeek V4 Flash(cactuscompute.com ↗)
    57comments
  9. The Implications of Linguistic Illegibility for LLM Security(arxiv.org ↗)
    8comments
  10. OpenJev(openjev.com ↗)
    231comments
  11. C++26: Trivial infinite loops are no longer undefined behaviour(sandordargo.com ↗)
    139comments
  12. Our brain evolved from two primitive nervous systems that merged: Study(newscientist.com ↗)
    32comments
  13. I vibed a proof of Conway's conjecture(overreacted.io ↗)
    158comments
  14. North Korean nuclear test sets off years of earthquakes(science.org ↗)
    127comments
  15. Border agents can search cellphones without a warrant or reasonable suspicion(lawandcrime.com ↗)
    58comments
  16. The first new cat species discovered in 100 years(nationalgeographic.com ↗)
    13comments
  17. US Military had close call after using AI for hallucinated intelligence report(cnn.com ↗)
    203comments
  18. Show HN: Ax-check.com – Can agents use your product?(ax-check.com ↗)
    21comments
  19. Inside ZCode: Silently uploading your Git history to the cloud(ferstar.org ↗)
    83comments
  20. A heap overflow and SSO misconfiguration to compromise OpenAI internal repos(hacktron.ai ↗)
    193comments
  21. Minimal Phone 2(minimalcompany.com ↗)
    95comments
  22. How SpaceX streamlined the Raptor engine(construction-physics.com ↗)
    11comments
  23. Cekura (YC F24) Is Hiring(ycombinator.com ↗)
    discuss
  24. "From Geometry to Algebra and Back Again: 4000 Years of Papers" by Jack Rusher [video](youtube.com ↗)
    discuss
  25. Warez: The Infrastructure and Aesthetics of Piracy (2021)(archive.org ↗)
    6comments
  26. Show HN: Scry, programmable internet search w/ congestion pricing(scry.io ↗)
    12comments
  27. A search-and-inference database from scratch in pure Zig(antfly.io ↗)
    6comments
  28. How to Write with an LLM(sockpuppet.org ↗)
    211comments
  29. Mathematicians Build Long-Awaited Graph Sandwich(quantamagazine.org ↗)
    14comments
  30. Jemalloc 5.4.0(github.com/jemalloc ↗)
    82comments

A C89 compiler that produces executables that are also valid ASCII text files [pdf]

323 pointsby 8y agocs.cmu.edu
67 comments
8y agoHN ↗

This is the work of Tom7, well known for other projects like Learnfun & Playfun, ARST ARSW and running a marathon in hockey skates.

8y agoHN ↗

There was actually a tool "com2txt" back in the DOS days. So you could convert an executable and put it into an email....

Update: I have my data well sorted enough that I found it :-) It even comes with code and is under a vague free license: https://github.com/hannob/com2txt

8y agoHN ↗

Thanks for sharing!

Kind of uncanny to see a perfectly readable Makefile written around the year I was born...

8y agoHN ↗

Make's been around since the '70s. Bell Labs cranked it out right after inventing C.

8y agoHN ↗

It didn't just create a text file. It created an executable text file.

First two paragraphs of the README:

Com2txt is a tool on MS-DOS which converts a com file to a text file. It's DOS generic. Unlike tools such as uuencode, the text file generated by com2txt works as a com file, exactly like the original com file does. Using com2txt, you can create a com file which can be sent through networks such as internet, and runs without any decoding.

Moreover, the text file got by com2txt consists only of ECHOable characters; it doesn't contain characters such as `<' or `|'. So, using ECHO command, you can easily generate the textized com file and use it in a batch file. For detail see section 4.

8y agoHN ↗

I didn't gleam that from the original comment either.

Crazy fun stuff though.

8y agoHN ↗

Shameless plug: I also wrote a tool similar to com2txt in 1996: https://github.com/pts/pts-xcom . A quick comparison:

* com2txt.exe is 7110 bytes long, xcom.com is only 401 bytes long.

* xcom.com can also convert back from text to binary.

* xcom.com can also convert to data text (without the self-decoder header).

8y agoHN ↗

Can it also stop an alien invasion?

8y agoHN ↗

Does this output self-modifying code, or does it also try to avoid that like ABC does?

8y agoHN ↗

Back in the BBS/FidoNet days someone sent me a comic GIF that, when renamed with a .COM extension, would execute under DOS. It was a nifty little demo, although .COM files were going the way of the dinosaur around then.

8y agoHN ↗

Wish I could remember the trick, but in the DOS days I used to type in a few characters (5ish IIRC) at the start of text files that allowed them to be renamed and executed as COM files.

8y agoHN ↗

If you read the paper I think you'll find it is something like "ZM~~_#____PRinty__C", where _ is a space, (HTML compresses spaces). See section 8, also the beginning of the paper.

8y agoHN ↗

No, COM files had no header. [2] I think that's part of why they were replaced. ZM was for EXEs. I think that one was someone's initials. (Yes, looked it up. [1])

I think what parent is remembering were characters that effectively created a jump instruction at the beginning of the file.

[1] https://en.wikipedia.org/wiki/DOS_MZ_executable

edit: [2] Section 6 of the paper talks about that, just noticed.

8y agoHN ↗

They were replaced because they could not handle more than 64KB.

8y agoHN ↗

.COM files were straight binary, no header and loaded at address 256 (0x100) into any 64KB segment. All indirections were local to that segment, hence the 64KB limit of .com files.

The characters you were typing are (probably) the code for a jump to an entry point somewhere else in the file.

8y agoHN ↗

The good doctor murphy is a mad genius.

I laughed very hard indeed when I first read this and got to the last 30 seconds of the video.

8y agoHN ↗

The phrase 'For example, on the popular and elegant X86 architecture, the single byte 0xF4 is the "HLT" instruction' slays me every time.

8y agoHN ↗

"An elegant weapon... for an age more naive about ISA design"?

8y agoHN ↗

Can you explain this? Is it the "popular and elegant" part?

8y agoHN ↗

Absolutely. It's very subtle humor. Students of computer architecture consider x86 to be one of the least elegant architectures around. Its many warts include segment registers (originally a hacky workaround to stretch 64k of memory to 1M), and an extremely complex instruction encoding employing prefix bytes. Many of the legacy issues (such as not having enough registers) have been papered over, leaving traces behind. Many people felt that the complexity would doom the architecture, and that a cleaner, leaner RISC approach would win out.

However, Intel has used their advantage in process technology to throw massive amounts of transistors to make up for the problems caused by all this complexity, and has done well. RISC has done well in the mobile space because those transistors tend to be power-hungry, but everywhere else x86 is today almost the only game in town.

One reason it's especially funny is that "HLT" is one of those legacy instructions that has pretty much no use in a modern system, yet takes up a whole slot in the byte encoding, while common operations like MOV or ADD often require extra prefix bytes to specify the size of the operands.

Hope that helps!

8y agoHN ↗

Segment registers did not evolve from the hacky address space expansion mechanisms. It may look that way looking at nothing but the Intel history, but the descriptor-style segment registers existed in mainframe architectures before the 8086/88 existed. The 8086 has trivial segment registers (which were just scaled offset addresses) which then morphed into mainframe-like descriptors of the successors (registers being indices into tables of segment descriptors). That could have been a plan all along, though.

https://en.wikipedia.org/wiki/Memory_segmentation#History

8y agoHN ↗

One reason it's especially funny is that "HLT" is one of those legacy instructions that has pretty much no use in a modern system

Is HLT no longer used in OS idle loops? Are there now other instructions which are better to use instead?

8y agoHN ↗

It's absolutely used. It's a completely normal and expected instruction to find on any CPU whether new or old.

8y agoHN ↗

HLT is absolutely used in modern systems, ARMs have the WFI and WFE (wait for interrupt, etc). They're essential for dropping in to low power modes, though admittedly HLT wasn't used for that back in the day.

8y agoHN ↗

Also, F4 is The close program function key in Windows....

So everything adds up. CYA!

8y agoHN ↗

It does have a slight advantage over ARM / most other RISC architectures in that the instructions are fairly small, meaning that you can get quite good decoding throughput without going wider. That advantage doesn't get entirely cancelled out by how badly allocated things are, since instructions can decode to multiple "actual" instructions (µops).

I'm still curious as to how Intel thought a mobile x86 chip could ever work.

8y agoHN ↗

Students of computer architecture consider x86 to be one of the least elegant architectures around.

I guess it depends when and where one studied.

Having grown with Z80 and x86, it surely looked kind of alright to me.

I only missed the flat addressing from 68000, but given that I only had access to it on Amigas available at some dev meetings, it wasn't something I bothered much with.

Also I don't remember anyone jumping of joy during the MIPS assignments (using SPIM).

8y agoHN ↗

HLT is still used by kernels when they want to idle the processor until the next interrupt. There are many examples of instructions that aren't actually used much if at all nowadays, like POPAD and PUSHAD, or the binary-coded decimal instructions

8y agoHN ↗

One of my favorite quotes about C:

Dennis Ritchie invents a powerful gun that shoots both forward and backward simultaneously. Not satisfied with the number of deaths and permanent maimings from that invention he invents C and Unix.

8y agoHN ↗

That is demoscene level awesomeness! Kudos to the author. Excellent video as well. And not least, lovely ending <3

8y agoHN ↗

Anyone have a copy of the program? I want to try and run it.

8y agoHN ↗

True, but there are a few gotchas with that version. It won't work with execve, it doesn't cache the binary, it won't work if called with "source", it doesn't set argv[0] properly when the binary is called, and a few other things. It is nice and terse though.

8y agoHN ↗

execve and binary caching are relatively easy to implement, as is argv[0]. Do people actually care about making "source" work?

8y agoHN ↗

I can't decide if that's cute, or eye-bleedingly criminal.

Neat though, and I haven't seen it before.

8y agoHN ↗

Ha, I'd seen the 3 line #if 0 version but not this! If you don't care about the fact that execve won't work, then this is pretty great.

8y agoHN ↗

(execve)...

Challenge accepted. :-) Might be just a matter of a shebang at the beginning and an 'exec' before the final $p.

8y agoHN ↗

Thanks, good stuff. dolmen/Olivier's followup is good too.

I now remember why I used the complicated expr command and make; it's to ensure it works with C and C++.

And any language that happens to accept // as a comment and is supported by "make". (note that no actual Makefile is required)

8y agoHN ↗

That is a cool feature! It's a bit annoying to have separate versions for C and C++.

8y agoHN ↗

Why go to all that trouble when you can just

#!/usr/bin/tcc -run #include <stdio.h> int main() { puts("Hello, World!"); }

8y agoHN ↗

Because most people don't have tcc installed, and the convenience is ruined if you have to install things for this to work. I really like that tcc has a flag for this; GCC and Clang really should copy it.

8y agoHN ↗

When I read the source and started on the comments, I thought: won't be long until someone drops in TCC. But yes, TCC does limit you in this regard a bit.

8y agoHN ↗

It's much simpler:

    $ cat >test.c
    //usr/bin/gcc "$0" -o /tmp/out.exe || exit; exec /tmp/out.exe "$@"
    #include <stdio.h>
    void main(int argc, char **argv) {
        printf("Hello, world!");
    }
    ^D
    $ chmod a+x test.c
    $ ./test.c
    Hello, world!
8y agoHN ↗

Even shorter, works unmodified with both C and C++, and doesn't recompile unless necessary:

  //usr/bin/make -s "${0%.*}"&&exec "${0%.*}" "$@";exit
8y agoHN ↗

Do I see a Sierpinski triangle on page 9? It's the code that, according to the description, changes the value of the AL register.

8y agoHN ↗

No, it is the _data_ that the compiler precomputes to help changing the value of the AL register. It is unused here, in fact it is cropped to 160 columns and it has a caption in the middle so it's wrong even. He included it just because it looks cool.

8y agoHN ↗

The histogram on the last page counts the occurrences of each character in the paper (all of them printable, of course). But because the histogram's counts are made of characters too, the author had to add a few extra numbers to make the histogram "converge". Brilliant.

8y agoHN ↗

I must be missing something, but I don't see how the actual text of the paper originates from the source code. Those C instructions actually compile into the sentences of the paper as well?

8y agoHN ↗

From a quick look at the source[1], it seems the compiler will always generate an executable with the text from the paper (which is read from the "paper/" directory, and some bits hard-coded in the compiler source). Or something. I don't really know SML.

From what I can tell, the .exe file generated by the compiler must be really big anyway (since the relevant sizes in the header can't be small because they have to be printable). So there must be some text, it might as well be the paper.

[1] https://sourceforge.net/p/tom7misc/svn/HEAD/tree/trunk/abc/e...

8y agoHN ↗

Ah so all the x86 bytes that the actual text generates are basically just filler for the actually relevant sections of the paper (i.e. the jumble of bytes that appears)? They're never actually read or executed by the CPU?

8y agoHN ↗

If only i wasn't too lazy I'd buy a hat just to take it for the author.

8y agoHN ↗

Meta literate programs. Not only do you have the code and a descriptive document about the code in the same document, but you also have the executable!

8y agoHN ↗

TIL I wonder if there’s any interesting reason for that.