Simpler "Hello World" Demonstrated In C
An anonymous reader writes "Wondering where all that bloat comes from, causing even the classic 'Hello world' to weigh in at 11 KB? An MIT programmer decided to make a Linux C program so simple, she could explain every byte of the assembly. She found that gcc was including libc even when you don't ask for it. The blog shows how to compile a much simpler 'Hello world,' using no libraries at all. This takes me back to the days of programming bare-metal on DOS!"
Mainframers have been using this most simple of all utilities for decades - literally. The Wikipedia entry on it has a good write-up about this (literal) do-nothing program. It's whole purpose is to provide a mechanisim to to exploit the various functions contained in JCL to create, delete, and otherwise manipulate datasets on mainframes.
The wikipedia entry is here: http://en.wikipedia.org/wiki/IEFBR14
Ken
"An 11k app is not going to make me, or my computer, say 'Good Bye World'"
It is if your computer is a 38-cent Atmel AVR tiny 10, which only has enough space for 512 12-bit instruction words. This chip is about half the size of a sunflower seed, but is faster, and, in several ways, more powerful, than the original $5000 IBM PC from 1981.
Get away from the idea of Gigahertz desktops and $1000 laptops and join the real computer revolution!
For me, if it costs more that $5, it's not a computer that I take seriously. It's just a 20th-century digital processing appliance.
It was uploaded to Reddit 12 hours ago; that's probably why it's just reaching Slashdot now.
#hello world tiny program
.data
.text
.equ SYSCALL, 0x80
.equ SYS_EXIT, 1
.equ SYS_WRITE, 4
.equ STDOUT, 1
.section
hello:
.ascii "hello world!\n"
.section
.globl _start
_start:
movb $SYS_WRITE, %al #put write syscall in eax
movb $STDOUT, %bl #set stream to stdout
movl $hello, %ecx #give address of start of buffer to print
movb $13, %dl #how many characters of buffer to print
int $SYSCALL
movb $SYS_EXIT, %al
int $SYSCALL
The above is a tiny hello world program i wrote myself, it's worth noting that even the resulting binary is larger than it needs to be, I wound up with a 133 byte binary by moving the text string into the ELF header via hex editor, and changing the instruction data to point to the new addresses.
Kind of hard to get it smaller than that while keeping it in ELF format, considering the actual object code in the binary was something like 15 bytes with the data illegally in the header.
c:\ xxx>debug :001D
-a
mov dx, 100
mov cx, 000D
mov bx, 1
mov ah, 40
int 21
mov ah, 4C
int 21
-f 111 "Hello World!"
-a100
mov dx, 0111
-r cx
-n c:\ xxx\ hello.com
-w
-q
c:\ xxx>hello.com
Hello World!
c:\ xxx>dir hello.com
03/18/2011 11:29 AM 29 HELLO.COM
Back in the early 1980s, I was doing development on MS-DOS 2.11 - the first real working version of MS-DOS that resembled Xenix more than CP/M.
I was using a combination of Lattice C and assembly language to do my day job. But I was upset about the libc bloat that Lattice C would drag into the program. Over the Christmas break, I sat down and wrote a tiny version of libc, with the 60% of the calls I actually used. Most of them were either thin wrappers on top of MS-DOS Int21 calls, assembly language implementations (the string functions), or reduced functionality (printf didn't handle strange alignments, floats or doubles), and custom startup/exit code. I also structured the library so that the linker would only link in functions that were actually used. For simple executables, I saw the on-disk file size drop from 10KB-20KB down to 400-600 bytes. Another thing that reduced on-disk file size was to create .com programs, rather than .exe programs.
I was also writing the handful of unix commands that I couldn't do without (ls, cat, cut, paste, grep, fgrep, etc). Since I was implementing dozens of Unix commands, each statically linked to libc, it was very important to reduce the over-all size of each executable. Most of the smaller trivial commands were less than 1KB in size. I think the largest was 4KB. I also had an emacs clone* that was 36KB when compiled and linked against my tiny lib.
For the longest time, I carried around a bootable MS-DOS 2.11 floppy, with my dozens of Unix commands, an emacs-like editor, Lattice C compiler, tiny libc, and some core MS-DOS programs. It allowed my to have my entire development environment on a floppy that I could stick in anyone's machine and make it usable.
* We had a source license for Mince, orphaned by Mark of the Unicorn, a tiny emacs-clone that ran on CP/M, MS-DOS, and Unix. We had enhanced it significantly.
Some people like their code to run on OSes for grownups.
After reading the linked article, I thought underwhelmed. Then I read the second article referenced in the summary:
http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
Now, that was interesting!
The strange thing is that the summary seems to imply that both articles are related, which they are most definitely not. The first one seems to be written by a naive noob, who just discovered a nifty trick in gcc. The second one is written by a real Wizard, who shows you how to conjure up some arcane magic to make ELF your bitch.
-dZ.
Carol vs. Ghost