7 ms·
The art of creating very tiny programs for the 80x86 family of CPUs
- wybiral 8y agoThe smallest "Hello world!" I ever managed was 86 bytes: https://github.com/wybiral/tiny-elf https://github.com/wybiral/tiny-elf Edit: It's only possible by moving the string and some of the opcodes into the ELF header section.
- Scaevolus 8y agox86 registers were designed with purposes in mind, and many of the 1-byte opcodes reflect this-- for example, "A4 MOVS mb,mb: Move byte [SI] to ES:[DI], advance SI,DI": https://www.swansontec.com/sregisters.html https://www.swansontec.com/sregisters.html And it's fundamentally an octal machine: http://www.dabo.de/ccc99/www.camp.ccc.de/radio/help.txt http://www.dabo.de/ccc99/www.camp.ccc.de/radio/help.txt
- pvg 8y ago'Octal machine' seems a little overstated (I know, that's what the ole post says), 'fundamentally' fundamentally so.
- ddingus 8y agoDid you read the linked material? Looking at instruction encoding through an octal lens makes a lot of sense. We should allow some license here. A discussion of, say the ALU, may likely yield a different statement. "Machine", viewed theou various lenses, bit depth, ALU, clock, instructions, registers or lack of, works best in context. Just a thought. :D
- pvg 8y agoDid you read the linked material? Did you read my comment that specifically mentions it? Looking at instruction encoding through an octal lens makes a lot of sense. Sure. But it doesn't make it an 'octal machine', let alone fundamentally so. Lots of binary things exhibit easier-to-see patterns when presented as octal, that's why octal is around. But it's a bit of convenient numerology not some intrinsic aspect of the (very binary) machine.
- akrasuski1 8y agoAnother nice site aggregating many clever tiny x86 programs: https://www.xorpd.net/pages/xchg_rax/snip_00.html https://www.xorpd.net/pages/xchg_rax/snip_00.html
- agumonkey 8y agomaybe not the tiniest but reddit.com/r/tinycode has some
- bitwize 8y agoMeanwhile, the remnants of the Lost Amiga Civilization snicker, and mutter something about 68k instructions, their many address modes, and custom chips between coughs.
- kken 8y agohttps://amycoders.org/ https://amycoders.org/
- mmjaa 8y agoSmallest program I ever sold, for near-5-digit profit, was a "REBOOT.COM" which saved a sysadmin from hand-rebooting 200 machines, daily, and which earned me $9,000 on account that it was my monthly rate at the time, and its all I did that month, by circumstance, anyway ... it was a different time, and I honestly felt I deserved it, then[1]. C:\> debug.com n JMP FFF0 w reboot.com q ^Z (or at least, it was something like that...) [1]- Now, not so much.
- Someone 8y agoReminds me of GO.COM. It was smaller, and made its programmer money, too (http://peetm.com/blog/?p=55 http://peetm.com/blog/?p=55) (Sorry, source code not available)
- weinzierl 8y ago> (Sorry, source code not available) ISWYDT;-) Spoiler: GO.COM is 0 bytes long, yet was incredibly useful back at the time.
- dfox 8y agoYou can do "warmer reboot" in even smaller code: int 19h (assembles into 0xcd 0x19). One surprising thing about that is that it confuses the hell out of ntldr, but to do fast reboot from DOS to linux through grub it works perfectly.
- exikyut 8y agoWhat happens with NTLDR? (I don't have any VMs set up at the moment)
- dfox 8y agoWhen executed from DOS by means of INT 19h and NT MBR it complains that there is not enough free conventional memory. This shows that somebody though that it is good idea to write ntldr as valid DOS program, that actually cares about the state of DOS on which it runs. (ntldr actually is concetanition of 16b MZ EXE and two COFF images, ie. something that DOS is perfectly willing to load and execute)
- ohadpr 8y agoMany folks who used to write 0x86 assembly code love size coding compos, especially demoscene folks. Me and a couple of friends were able to implement the game of Nibbles (Snake on old Nokia phones) in 70 bytes. Someone else managed to accomplish it in 48. http://www.hugi.scene.org/compo/compoold.htm#compo1 http://www.hugi.scene.org/compo/compoold.htm#compo1
- gnulinux 8y agoHow is this possible? I can't even produce "Hello World" program as short as that, do you not use ELF format?
- jaak 8y agoLOL this reminds of old flame wars on Usenet about the smallest possible "Hello World!". Someone would always eventually post "echo Hello World!" and the endless arguments would ensue about whether or not that was actually a program.
- rwmj 8y agoWhy echo it? $ cat /tmp/hello hello\ world $ /tmp/hello /tmp/hello: line 1: hello world: command not found It prints hello world :-)
- vardump 8y agoGreat idea! I improved the "program": $ cat >hello Hello\ World\! $ chmod +x hello $ ./hello ./hello: line 1: Hello World!: command not found V0.2 changelog: * fix: adheres to Hello World! standard now
- userbinator 8y agoIn realmode DOS COM format (flat binary) a "Hello world" is under two dozen bytes, the bulk of it being the string itself.
- dakics 8y agoI remember having great time writing this little 256-byte game: https://github.com/dakics/asm-tie-fighter https://github.com/dakics/asm-tie-fighter Back then, it often made a huge usability difference if you optimized in asm critical inner loops or other time-consuming external methods, which would be called from Clipper, Turbo Pascal/C, Modula-2 or alike. TSR-loaded "Norton Guides" were indispensable. Good times. :)
- ohadpr 8y agoI think my first assembly book was a Norton one :-)
- joe_the_user 8y agoIs there an equivalent for tiny bytecode programs? The general list of tricks seem focused on either reusing code-data by just finding some byte/nibble you need in the code or finding op-codes that happen to accomplish multi-op-code effects. I'd like to what you could get with self-modifying code. But naturally on 80x86, that's suicide since the code very, very heavily cached.
- kragen 8y ago"Use bytecode" is a pretty good tip for making your programs small, but that typically starts to be a win at somewhere around 512 bytes, depending on your CPU. This Wiki is aimed at 256 bytes and under, and at that level, you're mostly limited to micro-optimizations like the ones you mention, or just not doing stuff. It's amazing how far you can get by not doing stuff.
- kccqzy 8y agoThe CPU most definitely still supports self-modifying code. Intel takes compatibility seriously.
- kragen 8y agoOh, yeah, it's supported. But it's also slow.
- ddingus 8y agoHas to be, right? Artifact of modern execute and cache schemes.
- userbinator 8y ago"continuously modifying" code, yes. But do something like modify a constant used in a tight loop once before it, and you will likely get better performance, especially since you now don't have to use a register or an extra memory access to load that constant. That is, after all, how JITs work. One of the best examples is something like an image codec --- input images have diferent widths, heights, bits per channel, channels, coding modes, etc. but they are constants throughout the same image. You can essentially "compile" a decoder specialised to the exact image you're decoding, with all the loop counters replaced with constants and the branches eliminated to directly execute the code they would otherwise jump to.
- kragen 8y agoMy only real effort in this direction was a 64-byte MS-DOS .COM file that draws colored circles on the screen: http://canonical.org/~kragen/sw/dev3/morecircles.s http://canonical.org/~kragen/sw/dev3/morecircles.s 00000000: b013 cd10 c42f 89e8 f72e 0000 89c5 31c6 ...../........1. 00000010: 31d2 89c1 31db 88f7 89df c1fb 0201 df89 1...1........... 00000020: c3c1 fb08 01df 01f7 5b26 883d 4353 89c3 ........[&.=CS.. 00000030: c1fb 0401 da89 d3c1 fb04 29d8 e2d6 ebc6 ..........)..... There's a lot to learn from tiny demos like the ones (I didn't write) dissected in http://canonical.org/~kragen/demo http://canonical.org/~kragen/demo. Oh, I also wrote a Linux HTTP server in assembly with an executable under 2000 bytes: http://canonical.org/~kragen/sw/dev3/server.s http://canonical.org/~kragen/sw/dev3/server.s with some explanation in http://canonical.org/~kragen/sw/dev3/httpdito-readme http://canonical.org/~kragen/sw/dev3/httpdito-readme. I use it occasionally for testing stuff, since it's slightly less hassle than using python -m SimpleHTTPServer. Previous HN discussion at https://news.ycombinator.com/item?id=6908064 https://news.ycombinator.com/item?id=6908064 The demoscene diskmag "hugi" did a series of sizecoding competitions in 1998–2009, with truly astounding results. http://www.hugi.scene.org/compo/hcompo.htm http://www.hugi.scene.org/compo/hcompo.htm Highlights include a working textmode Pong game in 142 bytes, a Brainfuck interpreter in 98 bytes, a Snake game in 48 bytes, and a perfect Tic-Tac-Toe player in 213 bytes. The 8086 is a reasonable design for this kind of nonsense, since it's full of shortcuts and special cases that you can take advantage of. IBNIZ is an architecture really optimized for it, though: http://pelulamu.net/ibniz/ http://pelulamu.net/ibniz/ and in practice I often find that I can get things smaller with ARM Thumb-2 code than with the 8086. For example, https://github.com/kragen/dumpulse https://github.com/kragen/dumpulse is about 350 bytes of code on most architectures, but just over 200 bytes on a big-endian ARM.
- bArray 8y agoShameless plug for an old project, a 512 byte kernel with 512 byte programs (no DOS calls): https://bitbucket.org/danielbarry/saxoperatingsystem/src/master/ https://bitbucket.org/danielbarry/saxoperatingsystem/src/mas...
- jhallenworld 8y agoNice, but I have to complain about bitbucket.. it's so annoying that your html documents do not show up when browsing the bitbucket website. Github has them beat on this one- just rename the htmls to md and it will mostly work. I wrote similar things in the past, but for 6809. My equivalent these days is whenever I have to deal with a new microcontroller, I port my personal CLI + task queue schedular to it. Once I have a UART, timer, and CLI with history running, then the actual application is usually a breeze.
- bArray 8y ago>Nice, but I have to complain about bitbucket.. it's so annoying that your html documents do not show up when browsing the bitbucket website. Github has them beat on this one- just rename the htmls to md and it will mostly work. Yeah it was mostly written before ever coming into contact with Git so wasn't designed for that! Imagine a versioning system that relied on zipping the source code and adding a version number! I'll fix it at some point, but it was more for shelving and sharing. >I wrote similar things in the past, but for 6809. My equivalent these days is whenever I have to deal with a new microcontroller, I port my personal CLI + task queue schedular to it. Once I have a UART, timer, and CLI with history running, then the actual application is usually a breeze. Exactly! One thing I plan to do in the future is run a 8086/8088 VM on something like an Arduino (or whatever is popular at the time). Getting op codes to working fine is easy, getting the BIOS interrupts working is slightly harder.
- gesman 8y agoIn my young and reckless years i loved to [ab]use INT 13 to literally mechanically destroy hard drives with 12 bytes programs.
- peterisza 8y agoI wrote this animated 80-byte heart shaped tunnel and sent it in a text message to a geek girl in high school: http://www.pouet.net/prod.php?which=12270 http://www.pouet.net/prod.php?which=12270
- delian66 8y agoIt is a very nice effect! It still runs under DOSBox: echo "B013CD106800A00789C30FAFDB01D0F7E801C3740C31D266B8C027090066F7F3414929C8243F0420AA89F831D2BB4001F7F32D780081EAA0007FCDF7DAE9C8FF" | xxd -r -p - > heart.com ; dosbox heart.com
- dividuum 8y agoWe have the long tradition of sending encrypted or puzzle-like postcards to our local hackerspace. Three years ago we created this postcard: https://entropia.de/Datei:2015-01-27-back.jpg https://entropia.de/Datei:2015-01-27-back.jpg It's 200 bytes, a valid x85 ELF program with a deceptive 'strings' greeting message and an additional hidden message. Run at your own risk ;-) The machine readable version can be found here: https://entropia.de/Cryptierte_Postcarten https://entropia.de/Cryptierte_Postcarten
- amelius 8y agoThe smaller the problem, the easier it is to brute-force the solution.
- faissaloo 8y agoI created a fan daemon for my Macbook in 864 bytes: https://github.com/faissaloo/mfcd https://github.com/faissaloo/mfcd I also made echo in 153 bytes: https://github.com/faissaloo/echo https://github.com/faissaloo/echo
- sehugg 8y agoYou could even make a chess program in 392 bytes: http://nanochess.org/chess6.html http://nanochess.org/chess6.html
- jhallenworld 8y agoHow about this? A single block boot loader that understands the ext2 filesystem, so can load the kernel without having to "update-grub": https://github.com/jhallen/joes-sandbox/tree/master/boot https://github.com/jhallen/joes-sandbox/tree/master/boot Bonus: it tries to read tracks at a time to make booting off of floppies faster (I wrote it in the 90s..)