Smallest Possible ELF Executable?
taviso writes "I recently stumbled across this paper (google cache), where the author investigates the smallest possible ELF executable on linux, some interesting stuff, and well worth a read. The author concludes, 'every single byte in this executable file can be accounted for and justified. How many executables have you created lately that you can say that about?'
It isn't amazing until its also palindromic!
The only good weather is bad weather.
I just heard the news on slashdot -- Frodo Baggins, the smallest elf, was just executed! No other details were available.
Last time I read this on slash dot was less than a year ago. I imagine in 4 or 5 months we'll see it again.
The article is great. It really is a good intro to refresh that assembly / understand ELF / do neat stuff. I still have the tiny assembler installed on my machine from the last go round.
I've heard of a guy who is trying to make the world's smallest 'cat' program. I wonder how many other utilities have been similiarly "optimized"
I seem to remember making some damn small Turbo Pascal .COM files. Under 4096 bytes, IIRC.
Shutting down free speech with violence isn't fighting fascism. It IS fascism!
I was gonna post the google cache and make a lame joke, but fuck it, that's just not funny.
:)
In any case, it is very cool too see a google cache link in the article brief - let's see more of that!
Robots are everywhere, and they eat old people's medicine for fuel.
What's the largest? Windows.exe?
is it as efficient as the linux kernel? every byte in there is so efficient because it was made by linus torvaldos
... wanting to execute the smallest possible elf. You Americans and your bloodsports. Barbarians.
If you guys go ahead with your cold-hearted plan to execute this elf, the Olsen twins better watch their backs next time they're in Ireland, if you catch my drift.
- SMJ - (It's not just a name: it's a bad aftertaste.)
Does this guy have too much free time, or what?
in assembly: RET
:(
All this one byte program does is terminate execution. If it's infected by a virus you'll see soon enough if the size has increased.
ofcourse with todays macroviruses this doesn't work anymore
Privacy is terrorism.
You have to worry about hitting a copyright now with such a short program. And software patents are preventing something more elegant. Am I right?
Linux software is horribly bloated, like even "ls" is above 30k, thats just insane for a program thats supposed to just list files in a directory. About time someone did something about it.
This makes my new 100-gig hard drive seem WAY too big.
I've always wondered what all the glibc overhead (compared to f.i. uClibc) does. I've never noticed any functional difference when setting up a initrd image by using uClibc instead of glibc.
#!/bin/bash
ls
There isn't much practical here more than it is an ELF education. But it was a very interesting read... and being able to stuff a payload into the header. Nicely done. But given that, in most cases, disk space is vast, and memory is plentiful, there isn't much in the way of usefulness. Maybe in some niche' applications running on tight hardware... but running Linux.
Basically what the other is saying is that by default, C is somewhat bloated (you need to include massive libraries just to use one function). Writing system level calls in assembly can replace the unnecesary bloat of a library that's only being used by one function.
I remember this trick wehn I was learning x86 assembly. I wrote a hello world program in assembly. Assembled, it came to something like 35 bytes. In C++, it took over 10K.
Now, also see the statement that he is abandoning portability, because he's using linux-specific system calls. So, in a nutchell, C++ makes big code that's portable, assembly makes tiny code that's static.
Did I miss something or was this a long winded article about why assembly is better than C++?
There is no reasonable defense against an idiot with an agenda
:wq
Well, someone will point it out soon, so I might as well do it myself.
nasm is the name of the assembler, not tiny.
You can make a 45 byte version of the 'true' and 'false' utilities by changing the output to 1 or 0 respectively. Some shells implement these as builtin functions, but it does show a pratical (albeit odd) way to save a few bytes of disk space.
This guy clearly doesn't get the point!
67% of Americans are overweight. They can't account for most of the bites they use. By developing software that is just as bloated, the users feel good about themselves.
This kind of skinny programming is very insensitive to the fatass society we Americans live in! Hopefully the U.S. Congress hears of this soon, so that they may legislate this kind of software right off the face of the earth.
Masque, head of the Sensitive Programming Foundation*
[*A division of Maxtor Corporation; come check out our new 320GB drives, featuring room for tomorrow's applications...today.]
Cas, or StorageReview.com's forums, created a 324 bytes Windows 2000 PE executeable. It completely blew away all of mine, the smallest of which were about ~700 bytes.
Computer Science is no more about computers than astronomy is about telescopes. --E. W. Dijkstra
#!/bin/sh
ls
every single byte in this executable file can be accounted for and justified
The author's sanity, however, cannot.
moto411.com
My sincere apologies,
I read this article months ago, but it was not a Slashdot link. It was a link from another tech news source.
I think there are quite a few. It's seen as a challenge, and does have practical uses. Have a look at Toms Rootboot disk - it includes a web server, a telnet server, a telnet client, an nfs client, wget, gzip, bzip2, vi, a whole load of network drivers, and a tonne of other stuff, all compressed down onto one floppy disk. Only I've never quite been able to find the source code for any of it despite spending a small amount of time looking - possibly someone would be able to put me right on that one.
There are also lots of interesting articles on linuxassembly.org.
Andrew
If it's much smaller than 512 bytes, it's a total waste of time.
But I'd like to see them get a Breakout clone in 1K
None are more hopelessly enslaved than those who falsely believe they are free. Johann Wolfgang von Goethe.
While the program would be completely useless.
You could make it even shorter by having it return absolutely nothing (Just having it execute and finish.)
It could be useful to catch when anything starts to modify programs on your computer, because if the "thing" just modifies programs, it will recognize it as a program, and increase the size notably.
I really like the 45 byte program though, too bad that after you passed 100 bytes, it became totally non-compliant.
~ kjrose
Harddrive sizes being what they are now, the smallest sector size I see is 512 bytes. If the file stored in that sector is smaller than 512, it still takes up 512 bytes. Very intersting article however.
Soon I realized that smaller programs are not the end-all goal of programming. If a slightly bigger program is easier to understand for the next person who modifies/maintains it, then that is the new "Right Thing" for that application... and I realized the efficient progamming of the PDP days was a biproduct of necessity more than anything else. It's seldom needed with today's blazing hardware capabilities.
This isn't to say that many of today's programs are over-bloated, but just to reinforce the trade-off between small and easy to understand.
Reminds me of one of Bill Gates' first programs - Micro-Soft's 1975 Altair BASIC. Unfortuantly the page I wanted to link to has gone, but this is something from the register at the time: http://www.theregister.co.uk/content/4/18949.html
. org.uk/altair/4k/index2.html
:p )
Finally found a web archive of the page I wanted: http://web.archive.org/web/20011031094552/www.rjh
A real pity that standards have slipped so much since then.
(I refuse to post anonymously even though I have mentioned Microsoft in a thread about Small Exes. So there
We really need more efficiant programming in OSes today. Look at the system requirements for OSes over the past few years. It's gone crazy. Check out the requirements for NT Workstation 4.0, Windows XP Pro and Windows 2000 Pro.
Doesn't something seem messed up? What have we really gained since 4.0 that causes 4x the memory, 3x the procecssor, and almost 15x the harddrive space? Is USB and Firewire support really that big? And have you ever tried to run XP on the min system? It doesn't work so well. I remember being able to tweak a system to run Windows 95 on a 386 with 5mb memory and a 45mb harddrive. It wasn't pretty but it could run. Today if you aren't going 1ghz+, then they want to leave you behind.
They are just using really fast hardware as an excuse for bloating the code.
Even Linux (redhat moreso) is guilty of this.
Remember when awesome games could fit on a handful of floppies? I think that could fly today if they tried. Look at the Demo scene. 64k can do alot of graphics. The most awesome games like Betrayal at Krondor were only a few floppies. Sure, if you have big hardware use it, but don't waste it. Programmers are just getting slack and including (literally) everything in the world, and not writing anything for themselves. They aren't looking to optimize stuff, just to kick it out and make money (obviously open source isn't guilty of the money or the fast kickout thing)...
Tibbon
tibbon.com
You know -- the bullshitters that say: "Optimizing C compilers write small/better/faster code than hand-tuned assembly."
Hand-tuned assembler is always faster/smaller/better than C code, except when it comes to portability.
And this just goes to show that fact again!
the largest EXEs are the install programs for Counter Strike and Tactical Ops. The largest EXE that has anything to do with Windows is USER.EXE and weighs in at 537K. Just to let you know.
I/O, I/O, its off to disk I go, with a read and a write, and a bit and a byte, I/O, I/O, I/O, I/O
...wouldn't it be slightly smaller if it returned a number smaller than 42? i.e., 1 or 0 or nothing?
Advice: on VPS providers
Now, the author has to shrink the cluster size of his hard drive, and make up some new indexing structure that is more efficient so any shrinking of the executable actually matters.... It doesn't help if the executable is 32 bytes or 4096 bytes if you only have 4k clusters, you're still eating the same amount of space.
Karma: SELECT `karma` FROM `users` WHERE `userid`=138474;
Com files are different. They don't have any of the overhead of a format like ELF or EXE. It's just raw machine code from the very first byte.
The nasm assembly compiler site that he mentions in the article seems /.'d, theres a sourgeforge project site instead.
I remember writing a 112 bytes executable (including headers) in 68000 assembly language that could draw mandlebrot fractals. I am pretty sure you can't get it smaller than that (at least on the 68000), I'd done the register coloring dependency graph by hand.
One of the smallest yet greatest thing I ever wrote.
I win
nt
Doesn't it make you feel good to know that our freedoms are protected by politicans, lawyers and journalists.
w
The colon on the first line is an older version of the #! line, but only works for sh. And of course, `w' is one character less than `ls'.
On systems that automatically use /bin/sh on unknown files, the smallest possible shell script is:
wYes, a single character.
WWTTD?
It's kind of cheating if you are going to include self executing archives on the list.
but apart from that, it's of little use. No sane programmer will code a big app in this way.
We should be working on a new faster, smaller executable format, implement it in to the linux kernel, and update compliers for it. A one or two byte program just MIGHT be possible for linux.
Nero-burning ROM for Linux!
I remember years ago writting a run-length decompressor in Z80 asm that was 32 bytes. I think the compressor was 50 something bytes!
I also recall adding up the clock cycles for all of this to try and find the fastest implementation!
I'm over it now though!
I'm just glad to forget those cassette-tape based, hand coded assembler days, but it is kind of a shame to see how bloated code has got. If only I'd had a macro-assembler on my Sinclair ZX Spectrum (Timex something or other in the US) in those days... oh the world could've been mine!!
Linus wept.
linuxdoc.org
Chapter 11
Verse 35
You've got an easy breezy wind at your back...most of the time.
Could some one put up a mirror (its only 45 bytes after all)
Nero-burning ROM for Linux!
testing
If he managed to get to 42 bytes the universe would probably end...
pfft thats nothing, i once wrote an application that was 8 bytes, of course its only purpose was to jump to another memmory location and it had no headers or anything .globl start .text
.long 0x8C00E000
start:
mov.l boot2,r0
jsr @r0
boot2:
Better not answer the door today, Mr. Raiter. Could be Flowers By Irene.
Is this thing on? Hello?
Nero-burning ROM for Linux!
The current state of elf proccessors demands an astounding amount of system resources. When combined with dwarf co processor, it provides for unparalleled carnie access.
Its not so much the executable size that really matters (when talking about bloat), its the memory consumption of the program that really matters.I could write a very small program size wise that would drain your memory and crash your system, or make it slow down to a crawl.
-- "Perceptions create reality. By changing your perceptions you change your reality."
On a similar topic, MenuetOS is a full OS written in assembly and fits on a floppy. Yeah, lots of OS's used to fit on floppies, but it's still cool. It's amazing what all you can fit into a small space if you're careful.
Who said Freedom was Fair?
Well this reminds me the golden days of DOS (not Denial Of Service but Disk Operating System... well, anyway it didn't made a difference). Back then people fought for every bit of code. And assembler was as popular as C or Pascal.
However, using assembler this way is not the most optimal resource. Frankly this piece of code is only useful if you need some real tiny program and you are running out of space and speed. But, today, 99.99...% of tasks don't need it. The optimal way to use such tricks is to concentrate in tasks that really need "the best and fastest code ever". These are drivers and situations where speed's price costs gold. Usually this is done by injecting the necessary asm directives into C or any other language. Writing everything in pure Assembler is unpractical and the result may become harder to understand than the Rosetta Stone.
However the article is making a point - how unoptimised are the present compilers. For example, GCC is mostly C in C. It makes it highly portable, but, if anyone decided to repeat Turbo Pascal feat (most of its base code was Assembler), I know that binary code would shrink to the impossible. Right now we may not be feeling this drawback as bloatness still doesn't clog everything. In the future this situation may change if speed and reliability turn to higher priorities.
Some note for the bloat FUDders: This is not a reason for Linux distros being bloat. First learn to be rational on your needs and don't install everything in one box. Second, learn a little bit of administration, maybe some programming and kick that (mega_kernel) + (some_highly_featured_libs) + (several_unuseful_apps) out of your box. Then you will know that Linux can help fry eggs on your processor with lightning speed. Till then, keep the flame for yourself and read "Why I switched from Mac to Windows".
> echo 42
42
Doesn't require any program at all!
SO... mabey 640K is more then anyone will ever need.
lose
Is a hack!
Of course, and I highly suspect it, I may be talking out of my ass. -oqti
I don't think a virus that copied over "windows.exe" into memory would infect many dialup computers, can you say "Too frigen big". ;)
But something based on this optimized code that maybe did? rm -rf / hmmm...
it may not be all TOO practical, since a lot of people try to ensure that their program runs on multiple architectures and platforms, but I also miss the old (DOS) days when the demo scene tried to optimize their intros to fit a half an hour of entertainment into 64k, with full sound blaster support. the registers of the vga cards were abused to no end, lightening fast assembler procedures were optimized either for size, or for speed by unrolling loops, etc.
:)
while that isn't practical anymore these days, a LOT of code has become very sloppy. More than once have i stumbled over some college kids c app that was supposed to demonstrate linked lists, and instead, it was using one class with an array.
programming is an art, like acting. many try and are good enough for some purposes, but only a selected few are masters. sounds pretty damn philosophical, don't read too much into it
On Red Hat 8.0 I get:
/bin/true /bin/true
$ wc -c
9752
That's thousands of extra bytes - eek.
Looking through the comments here I see two main threads : (1) Squeezing out the last few overhead in a program leads to hard to understand / maintain program and thus is not worth the effort. (2) Whats the big deal anyway in this era of 100 GB disks and 2GHz processors?
While both these criticisms are valid, they miss the point. Firstly, it wasnt the objective of the author to squeeze the last few bytes out of that program to save resources. He was just putting his hard-earned knowledge to use. He was doing it because he could! This is the same motivation for people who climb mountains : because the mountain is there, and because they can climb it. Indeed, if the author were seriously looking into saving resources, he'd hardly be wasting his time on a trivial program, would he?
Secondly, one of the authors intentions was to demonstrate the limits to which austerity could be taken to. Certainly, this was a trivial program - but the same principles could be used to shrink larger non-trivial programs, and it those cases, the savings could possibly be larger. Of course, it those cases, the largest savings would come from a good optimizing compiler rather than crunching the headers together. More importantly, the author has exposed whole new ideas and lines of possibilities to programmers.
There is no such thing as luck. Luck is nothing but an absence of bad luck.
strip upx They work wonders.
That's it. I'm no longer part of Team Sanity.
Beyond some point, the article is really just silliness, interesting or not. Below 512 bytes, your not going to save anything on any system. Ok, there are filesystems that compress things further for squeezing into flash memory and such, so maybe there are some marginally useful applications, but still the header overlapping is a bit much to be worth considering.
Some of the 4K demos I've seen written for ASM competitions completely blow my mind... check out this one, it's basically a flythrough of the first level of Descent, with texture mapping, source lighting, animated lava and recharger field, a MIDI soundtrack, etc... all in 4095 bytes!!!
Here is Sanction's home page, it contains a couple more very impressive 4K demos.
"Mind, as manifested by the capacity to make choices, is to some extent present in every electron." -Freeman Dyson
You don't get shorter than that golden oldie...
To be compared with the non-optimized gcc version at 3,998 bytes.
I wonder how small you can make a Windows EXE..
Beware: In C++, your friends can see your privates!
... so said our illustrious nemesis.
...but I coded a program to display "Hello World!" in assembly, including its own routine to display the text, and it's 45 bytes too, and I'm just an assembly newbie. Of course, this is for Commodore 64, an architecture that only needs a two-byte program header (load address)... =)
PCs these days need way huge file headers... but I suppose it's worth it. =)
wc -c /bin/echo
12024 echo
12 kilobytes just to write a program to write text to the screen. Boy, you linux zealots must love shelling out for those 320 gb hard drives.
Nero-burning ROM for Linux!
In fact, just apply this fact iteratively and you'll find that any program can be written in zero bytes!
You wasted two bytes! Looking at the HTML source, your message reads: . You can save two bytes by using this code:
:)
Remember to get rid of your whitespace!
Ok, what I MEANT to say was
;)
You wasted two bytes! Looking at the HTML source, your message reads: "<b> <i> </i></b>". You can save two bytes by using this code: "<b><i></i></b>"!
I'll use preview next time, I promise!
; tiny.s
bit, but compiles without it with the error message:
tiny.s:0: Warning: end of file not at end of a line; newline inserted
Anyone's got any clues?
I think I've actually seen this a couple years earlier. There's actually a site, http://www.scene.org that will have contests to see who can make the best demo squeezed into 64k. There's tons of these available in the archives; here's an example.
Did you ever notice that *nix doesn't even cover Linux?
"Ah, kamisama! Ore no atama ni ono ga arimasu yo!."
This is not a criticism or "correction", but I am genuinally interested because I am learning Japanese:
Shouldn't it be "Ore no atama ni wa ono ga arimasu yo!"
And does it mean "Oh, God! There really is an axe in my head!" (or "There IS an axe in my head!" - I'm having trouble translating the "yo" without knowing the context).
Ah, come to think of it, it isn't a quote from "Battle Royale" is it ? I cracked up when that guy had an axe sticking in his head and the hero just goes "Daijobu desu ka?" ("Are you all right?").
graspee
http://sed.free.fr/624/
A horse can't be sick, you know, even if he wants to.
www.linuxassembly.org/ - Go there, its free and fun :-)
I stumbled on this paper years ago at linuxassembly.org get with the times slashdot!
http://linuxassembly.org/asmutils.html
Check it out, download it and assemble it.
They create the smalles set of binaries for the basic linux tools that I have found and they employ a good portion of the stuff mentioned in this paper.
They make busybox look bloated by comparison.
Another neat trick is to use the ld options "-Wl, gc-sections" when linking a static binary -- it tries to weed out all the unused portions of the libraries it links against.
The last trick I usually use is to link against uClibc or dietlibc rather then glibc. Makes a noticeable difference. RedHat has been working on a program called "newlib" which is supposed to do the same thing as uClibc or dietlibc but better (for embedded stuff).
where's your spoiler alert?!!?!?
after executing it you obtain: nothing (as you guess), but it is a funny completness property of system (null operator).
I saw this in one of the first
International Obfuscated C Code Contests.
Tiny, compact code is neat but I don't care about it. Folks here complain about bloat constantly but unless a program's size is actively interfering with your ability to do work and the program's functionality (and I don't mean taking an extra 2 seconds to load) who really cares? If it won't run on your machine, that is one thing. If it's just big, there are probably more important things to worry about. For example I don't really care that Mozilla is big compared to some other browsers. My machine can handle that and it's speed is adequate to my needs. I do care that the program is functional, reliable, easy to use and maintainable, which fortunately it is.
This article was vastly interesting.
Imagine paying a large number of highly trained developers to work out an operating system for a modern x86 from machine code alone.
Staggering thought, isn't it?
Its not the size that counts.
"The most sucessful operating system is not one who can eliminate its competitors, but live with them."
Just because a program or executable file is smaller, doesn't necessarily mean it's more efficient. For instance, some compiler optimizations actually produce larger executables. If you unroll a loop, it actually generates code for each iteration of the loop, but saves time because it's faster to keep going forward than to branch backwards to run through the code again.
Similarly, you can have inline functions that insert the inline function directly into the function calling it. Every function that calls an inline function would get a copy of it, which produces larger code, but saves a lot of time since it doesn't need to push the arguments on the stack, branch to the new function, and return with the value.
Finally, the biggest speed gains you can get are generally algorithmic in nature. You can do a bubble sort with just a few lines of code. It's a lot simpler code and smaller than the larger and more complicated quick sort or merge sort. I know which one I'd rather wait for with a million items to sort.
So remember, just because something is bigger, doesn't mean it's more bloated, and just because something is smaller doesn't mean it's faster or more efficient.
Looking for a computer support specialist for your small business? Check out
Um, no. It is actually mydick.exe.
At least, that's what your mother said last night.
I recently attempted putting RedHat 7.0 onto a 133 MHZ pentium with 32 mb ram (toshiba laptop). The setup/installer informed me I do not have enough ram to continue.
Lighten up, man.
Patrick Doyle
I mod down every jackass who puts his moderation policy in his sig. Oh, wait a sec....
"Reclaim America"?? More like "Conquer America for conservative religious bigots!"
that made me spill my coffee !!
not an elf.
Rumors of his being a fairy persist, however.
KFG
The first few examples are quite noteworthy, but when the author starts to put code inside the ELF header, it gets really ugly..
Saying that these bytes are "only padding anyway for future extensions" doesn't feel that good. :-)
This remembers me of early attempts on AmigaOS to shorten and fasten executables where people could be sure that all available Amigas would only use the lower 24 bits of 32 bit address registers since the machines could only address 24 bits physically. So they put application data into the upper 8 bits of registers. Worked fine.
Then came newer machines which really used the full set of 32 address lines and all those dirty programs crashed without obvious reason..
The author says "if we leave compatibility behind.." but what he's doing is not only leaving inter-OS compatibility behind - what he creates isn't even an ELF executable anymore. It's just something that happens to work with this special Linux version.
So since this isn't even an ELF executable any more, there's no reason not just to write "exit 42" in bash (which would be an amazing 8 bytes in size *g*).
Don't misunderstand me, I really like those hacks. But I myself will never, ever again code something that is prone to break in the future just because I didn't follow standards.
One could say that this is what programming is about. :-)
No offence meant.
42. Easy. What is 32 + 8 + 2?
the real reason to obfuscate through efficiency! :)
(context for mods) let's see... ELF... elves... races in fantasy and science fiction:
No. Trolls
Look at that troll. Isn't it Qt?
are completely different creatures from hobbits and elves.
let's see... among (semi) intelligent roughly-humanoid races, the fantasy multiverse has at least humans, dwarves, elves, hobbits, ents, weebles, smurfs, cyclopes, gnomes (pronounced g; 90 cm tall), gnomes (silent g; 15 cm tall), trolls, orcs, merfolk, selkies, marsh-wiggles, nerdlucks, jawas, tuskens, wookiees, ewoks, teeks, borrowers, morlocks, and eloi.
Saturday, Saturday, Saturday! Watch the Race Race at the Motor Speedway!
Be there.
--
define MAX_CHRISTS 5
Will I retire or break 10K?
40k? luxury! try 256 bytes ;)
256 bytes? luxury! farbrausch has a 16-byte DOS demo.
Will I retire or break 10K?
$ cat >a.pl
./a.pl
#!/usr/bin/perl
exit(42);
$ chmod +x a.pl
$
$ echo $?
42
$ ls -l a.pl
-rwxr-xr-x 1 bcrowell bcrowell 26 Oct 19 12:41 a.pl
Only takes up 26 bytes on my hard disk!
Find free books.
Well, you know, opinions are like assholes... everybody has one.
CPU is cheap, hard disk is cheap.
Maybe on PCs, but not on embedded systems, handheld systems, or game consoles. The Game Boy Advance, for instance, has only 384 KB of RAM, and all but 32 KB are 16-bit bus width with muchos wait states. Many microcontrollers inside such things as microwave ovens are as powerful as an Atari 2600 VCS, with 128 bytes of RAM and about 12 bytes of VRAM (if that).
Will I retire or break 10K?
The author concludes, 'every single byte in this executable file can be accounted for and justified. How many executables have you created lately that you can say that about?'
Heck, Microsoft fits that profile. Every byte accounted for? "One enormous pile of garbage."
May we never see th
"get out the binary editor and code the hexadecimal values by hand" I'm not sure if this is really doable, even as a fun, pointless little exercise. Have any /.ers tried this or even done a little binary coding? That would really impress me!
Leave out any stories about "We used to do that all the time" Just show us an example
http://en.wikipedia.org/wiki/Signature_bloc
I saw this years ago. Sometime in the late 90's. It's very interesting and cool stuff, thouhg.
--
If I actually could spell I'd have spelled it right in the first place.
The whole point of the paper was drawing newbie hackers' attention to that mysterious number, 42.
#!/bin/sh exit 42 $ ./kuku ; echo $?
42
$ wc -m kuku
18 kuku
18 bytes !!
Rather than hunting down the smallest elf, we would prefer you execute the largest elf. Doing so would help reduce our horrible obesity problem. Secondly, we damand humane executions, ie lethal injection. your proposed methods seem more like electrocution which was outlawed in the Really Tiny Creature War Crimes pact of 1982 along with inadvertantly stepping on us. Did you ever think about who's going to make your next generation .13 micron processors if you kill us?
How could you spend 35 bytes?
C:\tmp>debug
-a 100
168D:0100 mov ah,9
168D:0102 mov dx,108
168D:0105 int 21
168D:0107 ret
168D:0108 db 'Hello World!$'
168D:0115
-r cx
:15
-n hello.com
-w
-q
(1) Returning a number is not exactly a good choice testing executable size. It's a start, but the program doesn't really _do_ anything.
.com files are extremely compact by comparison as they do not have any OS overhead - .com files are raw memory dumps that are loaded at a pre-determined offset into a 16-bit 64k segment and are executed directly.
.com program - as opposed to 45 bytes for Linux ELF executables (because you have to actually call a system function to exit).
(2) The author of this comment may very well have not been talking about Linux. DOS
As another comment above stated, the 'RET' instruction (1 byte) is the smallest possible DOS
A "Hello world" program generated with this API takes only 267 bytes.
Before it took 8 Million years and a computer the size of a city to get the same answer. Now we can do it all with 45 bytes.
-- 'The' Lord and Master Bitman On High, Master Of All
You may say, yeah but how often will you printf more than 1024 bytes? Exactly,- practically never. Which is why this sort of crap is not showing up in testing and DOES show up when people are trying to crack it.
1) The increase in OS requirements is partially due to the increase in OS functions. XP provides a lot more eye candy than NT, which needs more processor power to handle. You may not think it's a good idea, but most people like it.
2) The increase in OS requirements is mainly due to an increase in software requirements as a whole. An OS is worthless if you can't run anything on it, so you need to set your requirements with software in mind. MS made this mistake with Windows 95. Yes, technically IT would run with 4MB of ram, but that wasn't enough to load anything else. XP's stated minimum isn't the actual minimum, but a practical one wheny ou account for applications.
3) As others have mentioned, compact code comes at the price of maintainability. Sure, I can write a program in 100% assembly, and then if I'm realyl good tweak the machine code to make sure it is as efficient as possable. Now try and maintain that. This is hard enough if it's a tiny app, but if it is something large like, say, Mozilla even the orignal programmer would find matenence very difficult and anyone else would find it almost impossable.
4) Along those line, portability requires that you code in a higher level language, and often that you make some changes that increase your code size. If you do everything in optimised assembly, well it's a one platform thing. I can gaurentee that you have to do a massive rewrite of an assembly Windows app if you want to make it run on x86 Linux just because of the API differences. If you are talking another hardware platform, then it's a total and complete rewrite.
5) Your 64k demo thing I'm assuming is refering to the now infamous Farbrausch demos. It is simply stunning what they can get done in 64k BUT it comes at a huge price. First there is the memory usage, look at your task manager sometime when one of those is running, they use like 80MB. Because of their tiny disk usage they can to decompress to memory. Second their compatibility is horrable, their newer one FR22 works properly on my sytstem at work, but not at home, the only big difference being at home a have a geForce 4 at work I have a GeForce 3. Finally, these thigns are only made possable by the "bloated" Windows framework with things like DirectX to simplfy low level access.
6) Most people see little point in trying to make things run well on a 386 when you can get an entire system running at over 1ghz for about $500.
I remember in the "good old days" (tm) on the Amiga, when some (well, quite a lot actually :) people managed to make small intros with sine-scrolling multi-colored text in less than 512 bytes, all done in the bootblock which also had a loader for whatever game/demo was on the disk.
/ The Arrow
"How lovely you are. So lovely in my straightjacket..." - Nny
The good human can recognize when the algorithm should be tweaked. For example, gzip_x86 decompresses 5% to 45% faster than gzip by focusing on the negative number of bits remaining, and allocating the registers accordingly. A person can ask enough questions to determine that incrementing both sides of a less than preserves the relationship (and then apply transitivity), while the careful compiler is stuck with the possibility of overflow.
Humans also can have a wider range of adaptation to external constraints, for example small space limits on boot loaders. And no compiler known to me has ever on its own initiative recognized and used dynamic code (runtime code generation) where appropriate.
What's that? Doesn't everyone use rpms? :)
echo -en '\xcd\x20' > void.com
.com file exit function returning with an exitcode of 0.
This will only call the DOS
in assembly:
int 0x20
Smallest possible DOS executable that could be somehow usefull:
echo -en '\xcd\x05\xcd\x20' > prtscr.com
This will also call int 5, the print screen interrupt handler.
Flaimbait? I was only taking the flamebait the AC poster left. Hilarious.
I'm running Redhat 7.2 on a 486DX with 32MB of RAM (It's a router/firewall). The trick is to use the text-based installation rather than the GUI.
6 years back i wrote a 96 BYTE machine code program under DOS, using nothing but "debug" (machine code, as in i hand assembled my assembly), which calculated factorials of numbers upto abt 32000...i still give it a go when i am bored, under bochs :)
i count tht as the most beautifull of my code
ghoul2
Sigura Non Grata
Wired 1995 Surprize coding compo :
.com program that does the following :
:-)
:-)
Write the smallest possible
1, Input a number from the keyboard, call it N
2, Go in mode 13 (vga), draw N 3x3 squares without the central pixel (N * 8 pixels to draw), no square should be adjascent to another.
3, Wait for Enter
4, Exit
Results were
1: Walken/Impact Studios, 48 bytes
1: (ex aequo) Paranoia, 48 bytes
2: KLF, 51 bytes
For info, Walken's version was drawing the squares at different positions every time his program was ran (don't ask me how)
Our own attempt (aegis) yielded 52 bytes, but we were disqualified because we did not support the key "0"
ahh... fun...
lone, dfx.
Elf Up
Ok, I have a stupid question. Why is GCC not optimizing out things like this? For instance, why does the size drop from 1340 to 372 by simply not using the stdlib? What exactly is it that is adding ~1000 bytes? Is that *ALL* unnecessary initialization overhead? Is it calling into a precompiled library object or is it just including the source for exit()? If it is just including the source for exit(), how can this end up larger than just manually including the instructions? The only thing I can think of is "unnecessary" initializations
It's 10 PM. Do you know if you're un-American?
$ cat>a.sh ./a.sh ; echo $?
#!/bin/sh
exit 42
$ chmod +x a.sh
$
42
$ wc -c a.sh
18 a.sh
flossie
Write now. Defend liberty
I love it. This is a one-floppy Linux distribution which contains all the power tools you really need to demolish any computer.
When I feel sadistic, I'll boot up some co-worker's Windoze box with it, and they arrive facing an "ls" listing and an "# " prompt. Panic usually follows.
And why the hell you'd want to install some wonky assembler when binutils already includes a perfectly decent one, I don't know. The Debian nasm package says "Size: 1344826". I thought the goal here was to REDUCE bloat, not increase it! :)
:)
People who are too lazy to learn the STANDARD assembly syntax for their system should stick to C (or BASIC), imo.
Where exactly did you pull this from? My VC.NET compiler does not have use this printf.
There is a big difference between example code and the code they actually use, you know.
I've no strong opinions regarding assembler syntax, but using a large assembler doesn't equate to bloat. You don't generally need to distribute the assembler along with the executable.
flossie
Write now. Defend liberty
...nobody has yet said whether the smallest elf is executable or not? I would imagine that unless he's a water bear, we're probably still going to be able to execute him.
45 bytes is not that difficult to code manually. Emacs+hexl-mode+nasm -l will show you most of what you need.
http://saveie6.com/
So I'll just place my trojan horse code into that extra space that you are currently wasting by aligning all your programs to 4KB disk pages.
.ZIP or .ARJ file. That way, you'll just think I was sloppy, not malicious!!
If I understand correctly, there is NO standard for padding unused disk files with RET / NOP calls AFTER a block has been used once, so your virus scanner will never bother to look past the end of block (EOB) marker!
To make this even more nasty, I'll spread my mischief across multiple files in a
Zappy5000
I wrote a fearly full-featured ls for embutils (http://www.fefe.de/embutils/); it has large file support and even does colors.
/opt/diet/bin/ls /opt/diet/bin/ls /opt/diet/bin/ls /opt/diet/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
$ ls -l
-rwxr-xr-x 1 root root 17256 Aug 31 17:22
$ file
$
It's this small because of the diet libc, of course (http://www.fefe.de/dietlibc/).
Yes- comparing somebody with an asshole is pretty much always flamebait.
LOL - nuff said.
What has this got to do with anything being discussed? The registry is a useless crock, and it has nothing to do with understanding anything about an ELF executable.
they'll have to write a functioning program thats only 1 byte long.
That wasn't flamebait, it was more like "+2 informative."
"Reclaim America" is a not-so-thinly-veiled attempt to impose a narrow minority view on the entire country. You can't reclaim something you never had!
Seriously, if you think "Reclaim America" is a positive force for our nation, you probably also think "The Handmaid's Tale" is a utopian novel.
This may solve the overcrowded prison problem at the north pole.
I hate to mention it, but old DOS COM files can be MUCH smaller :-)
I even participated in a contest to build a 2 player game under 256 bytes! (mine was 189 bytes long).
I fired up the old 512K the other day. You stick in a 400K floppy that's got the entire OS, including 8 fonts, MacWrite 1.0 - which still does about 90% of what people use WORD for, and it's got room for a few documents.
Boots in 3.5 seconds too!
I've read that Herzfeld and the others played exactly the kind of tricks in this article to get the original MacOS and a program to run on 128K of Ram.
--Hi. I'm in Portland and it's raining. This appears to be a permanent condition.
right in your ass - just like a toaster!
Bob: Ass Toast never tasted so good.
Bill: That's not toast silly - it's MenuetOS!
This one went around the internet a thousand times already, but in case you haven't seen it:
True in a Nutshell
What fucking EOB marker? There's no such thing on a disk. Filesizes are stored in their goddamned directory entries.
There's a site [256b.com] that is dedicated for demos and intros under 256 bytes large--or small, that is.
It's not the smallest, but it will do:9 80990198124070670434221461126054012716884237789403 54374658995543008294292443701415731177681723440925 09864981039984833129500995832063412513786368235058 112064522788P | dc > small.com
echo 4184132202879349347527748384791433495069215642122
Note, however, that the method used to pack those extra bytes no longer works in Linux 2.4.19, and maybe slightly earlier.
Make it even smaller by doing this:
/usr/bin/perl /p
cp
and editing your shabang to be #!/p
Sorry, I know it's sometimes not to straight forward to get to the parent post on /. so I should have included a quote.
h oo d/default.aspx [microsoft.com]
Please note though that I started with OT (Off Topic)...
Basically I replied to a post that said:
Try libctiny:
http://msdn.microsoft.com/msdnmag/issues/01/01/
It has been posted here before. Lot more than a year ago mind.
My favourite is a 4-byte DOS .com file which performs a, well, DOS attack, on the computer if it's a bad Pentium. Here it is:
F00FC7C8
Run it, and it freezes your Pentium. Enjoy.
While it's true that quite a few optimizations not only improve the runtime but also reduce the code size, this is not generally true. An important optimization, for instance, is loop unrolling - which more than doubles the codesize of a loop. Its purpose is to reduce the number of branches, as jumps in superscalar out-of-order processors are performance killers.
Small executables are important for machines where the program is stored in flash (like microcontrollers). The compilers for those architectures are optimized to produce small code (as a matter of fact some of them are gcc-based). When storage is cheap, program size is rather irrelevant (keep in mind that OSs do paging, they only keep a working set of the program in memory).
The Raven.
The Raven
While nostalgic, this kind of minimalism is misplaced in modern operating systems. When you write an application, even a small application, think of everything that goes on behind the scenes:
1. Using a single function in shared library brings in the entire library.
2. You're at the mercy of the code in shared libraries and drivers. Even if you write code in hand-optimized assembly language, what's the point when you have to call the OS or a driver in order to do graphics and I/O?
3. There's a relatively large cluster size under most filesystems, so saving a few bytes or even a few K can often be irrelevant.
4. Even simple things like memory access can cause interrupts during which the virtual memory system intervenes.
All the posts about "returning to the days of performance" and all that rubbish are completely off the mark.
These guys have windows executables having size of 256 bytes ! And believe me, those programs generate amazing graphics.
The point was that if you have binutils installed, you already have gas, and practically anyone using a Linux box for development will have bintuils installed, so why bother with nasm?
Mine takes 0 bytes:
:)
$ perl -e 'exit(42)'; echo $?
42
$
-$|{
Sorry for the late post on the issue, but I did not see any mention of binary rewriting developments that have yielded significant code size reductions based upon whole program size optimizations: squeeze++++, a proof-of-concept program compactor
These guys are obtaining 33%-70% size reductions on alpha platforms.
Only 2" tall, dead under a toadstool. One bullet wound to the head at close range. Yuck!
I resent the whole programmers are getting lazy argument, back in the good old days making programs for a 48k spectrum it's easy and important to be as efficient as possible. However nowadays projects generally run into tens of thousands of lines of code, and have to run on various platforms. I'm in games so thats PC, PS2, GC and XBOX now I'm sorry but something has to give and I agree with the new school of thought that (and I'm paraphrasing here) something like 5 percent of your code runs 90 percent of the time and thats where you should concentrate your efforts. Coupled with the law of diminishing returns like that seen in the article size down by 1/2 then 1/4 then 1/8 etc. means it's better to profile carefully and go for the big wins then move on. Not that these skills aren't useful alot of the people who made games for the snes are now enjoying doing the same for the GBA.
God only knows why Bill thought 640k would be enough for anyone though I'm betting windows 1.0 took up more than that !!!
A beowulf cluster of these things!
Speaking as a compiler developer, who as a contractor has done major compiler work in recent years for HP, Microsoft, SGI, etc, I strongly disagree.
The speed of generated code is very important to hardware vendors (because it is essential to the speed of their hardware), to software developers (because the easiest way to get faster code is with zero effort -- buy a compiler that generates better code), and to compiler developers because they sell to the other two camps. (Or often, are also one of the other camps.)
Sure, we all know that programmers in general don't care about speed of generated code the way we did back when it was truly critical to literally count every cpu cycle burned. But don't blame us compiler guys -- we're the good guys!
On the other hand, you've a more legitimate complaint in talking about no one caring about the size of generated code. If you check the literature, you'll find that the almost the only famous reference on the subject of compilers minimizing code size was the landmark Bliss compiler, circa 1970.
It's almost never been a concern. (I know there have always been exceptions to that, but I can't remember any exceptions that were famous, whereas issues of code speed are extremely famous.)
Professional Wild-Eyed Visionary
nice.
This is OLD. I was using this back in 1999 for my own ELF learning purposes. Get a clue slashbie.