One day I started wondering if I could write a "Hello World" assembly program in Linux, using only ASCII characters in the opcodes. That is, the resulting object code would only have values 0x20-0x7f.

This is possible under DOS, but alas it is impossible under Linux. You can come tantalizingly close though.

Update: at one point I claimed on this page that the sticking point was getting "int 0x80" (ie 0xcd 0x80) into ASCII as well as problems creating "call esp". This was very silly of me, because with some clever self-modifying code tricks you can easily create these values and stick them in the proper place.

Thanks to "Pegasus Epsilon" (pegasus _at_ pimpninjas _dot_ org) for pointing this out. He even went beyond the call of duty and created some code that shows this.

You can see his sample code (in nasm) that creates all-ascii object code here: ascii.asm.

Note, the above code will not work if you have a hardened kernel that does not allow writing to the code segment.

Creating a complete linux ELF executable remains impossible though, primarily because the ELF "magic" signifier has a null (0) character in it. Also, Pegasus Epsilon points out:
> not only is the null terminator in the ELF header a problem, but there
> are several places in the header that would be very rude to push into
> the ascii range (ie: 0x21212121 bytes of memory minimum for the .bss
> is just rude. of course you don't need to have a .bss if you strip -R
> .bss the thing, but still.)

I would be interested in seeing similar ASCII object code for other architectures. I wish I had more free time to investigate things like this...
Back to my Assembly Tricks page