Brooks Davis has given a nice talk about what needs to be working to get a C hello world running. Note that his version assumes that the compiler is transforming the printf to puts. The printf function itself is a stress tests for a C compiler (clang could compile all of GNUstep except for GSFormat, which is basically printf for about a year before it could compile all of GNUstep). The locale support and variadic argument handling make this tricky in C and if you use the GNU extensions that allow you to register other format specifiers, it’s even more painful. In C++, the iostream goo is pretty horrific at the source level but doesn’t compile down to anything much worse than the C standard library. Java’s printf ends up invoking the class loader to load locale classes (Sun’s libc did something similar for locales), which ends up invoking pretty much every part of the JVM (file I/O, class loader, security policies, threads, JIT, GC), so is a surprisingly good test - if you can do printf, your JVM probably works.
$ git clone https://github.com/akkartik/mu
$ cd mu
$ ./translate_mu apps/hello.mu
$ ./a.elf
Hello world!
$
The work is done by print-string in layer 405, which takes a screen object and a string to print. If the screen object is null, it prints to the real screen. Fake screens are useful for tests, though they aren’t fully implemented yet.
If the screen is null/real, print-string delegates to print-string-to-real-string, which is implemented in machine code in layer 304:
Brooks Davis has given a nice talk about what needs to be working to get a C hello world running. Note that his version assumes that the compiler is transforming the
printf
toputs
. Theprintf
function itself is a stress tests for a C compiler (clang could compile all of GNUstep except forGSFormat
, which is basicallyprintf
for about a year before it could compile all of GNUstep). The locale support and variadic argument handling make this tricky in C and if you use the GNU extensions that allow you to register other format specifiers, it’s even more painful. In C++, the iostream goo is pretty horrific at the source level but doesn’t compile down to anything much worse than the C standard library. Java’s printf ends up invoking the class loader to load locale classes (Sun’s libc did something similar for locales), which ends up invoking pretty much every part of the JVM (file I/O, class loader, security policies, threads, JIT, GC), so is a surprisingly good test - if you can do printf, your JVM probably works.This looks really great and very much in the same spirit as the post, I will check it out soon, thanks!
Just for kicks, here’s “hello world” in my Mu project:
(link; colorized)
Run it like this: (x86 only. Linux only for now.)
The work is done by
print-string
in layer 405, which takes a screen object and a string to print. If the screen object is null, it prints to the real screen. Fake screens are useful for tests, though they aren’t fully implemented yet.If the screen is null/real,
print-string
delegates toprint-string-to-real-string
, which is implemented in machine code in layer 304:(link; colorized)
The hex at the start of each word goes straight into the binary. The rest is for documentation or error-checking.
The function call
(write 1 *(ebp+8))
is syntax sugar for pushing args, performing acall
, and popping args:write
is implemented at layer 108 to support tests, and delegates to_write
at layer 101 which passes length-prefixed arrays to the Linuxwrite()
syscall.This is a great article. Thanks!
thank you for reading it :)