www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - 438-byte "Hello, world" Win32 EXE in D

reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
I've picked up an older project for using D on barebones Win32 as 
a "better C".

Thanks to recent advances in DMD (-betterC and -m32mscoff), I 
could get a "Hello, world" program on Win32 down to just 438 
bytes when compiled. This is without assembly, linker scripts, 
custom Phobos/Druntime, or manual post-build tweaks.

-betterC allows stripping things like ModuleInfo, and as of 
recently it also strips file/module names used for asserts/range 
check errors (which were emitted even in -release mode). A better 
alternative would be a DMD equivalent to -fdata-sections, though, 
so unneeded variables, constants, and data generated by the 
compiler could be garbage-collected by the linker.

-m32mscoff allows using more linkers. Specifically, the Microsoft 
Linker and Crinkler, which only understand COFF, can both 
generate executables which are much smaller than those created by 
OPTLINK.

The 438-byte "Hello, world" program is achieved using Crinkler, 
which is a COFF linker with aggressive compression and header 
optimization. It was created for compressing 4K demos.

Without compression on header optimization, you can reach 630 
bytes using Unilink, a freeware linker which is compatible with 
both COFF and OMF.

The source code is not much to look at, most of the "magic" is in 
the makefiles:

https://github.com/CyberShadow/SlimD

See samples/01-msgbox for more commentary. The figures above are 
for samples/02-console.

The motivation for this project is mostly hack value and 
aesthetical (a 500 KB EXE with 5 KB worth of actual functionality 
is not pretty).
Sep 07 2014
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
One step down that road: 
https://www.youtube.com/watch?v=RCh3Q08HMfs&list=PLA5E2FF8E143DA58C
Sep 07 2014
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/7/14, 2:03 PM, Vladimir Panteleev wrote:
 I've picked up an older project for using D on barebones Win32 as a
 "better C".

 Thanks to recent advances in DMD (-betterC and -m32mscoff), I could get
 a "Hello, world" program on Win32 down to just 438 bytes when compiled.
 This is without assembly, linker scripts, custom Phobos/Druntime, or
 manual post-build tweaks.
Awesome. Blog post -> reddit -> win. -- Andrei
Sep 07 2014
prev sibling next sibling parent "Dominikus Dittes Scherkl" writes:
On Sunday, 7 September 2014 at 21:03:17 UTC, Vladimir Panteleev 
wrote:
 I've picked up an older project for using D on barebones Win32 
 as a "better C".

 Thanks to recent advances in DMD (-betterC and -m32mscoff), I 
 could get a "Hello, world" program on Win32 down to just 438 
 bytes when compiled. This is without assembly, linker scripts, 
 custom Phobos/Druntime, or manual post-build tweaks.
YES. That's what I expect to be possible with a systems programming language! Very pleasing to see that it is also possible with D, so D seems to be really a systems programming language :-)
Sep 07 2014
prev sibling next sibling parent reply Andrej Mitrovic via Digitalmars-d-announce writes:
On 9/7/14, Vladimir Panteleev via Digitalmars-d-announce
<digitalmars-d-announce puremagic.com> wrote:
 Thanks to recent advances in DMD (-betterC and -m32mscoff), I
 could get a "Hello, world" program on Win32 down to just 438
 bytes when compiled. This is without assembly, linker scripts,
 custom Phobos/Druntime, or manual post-build tweaks.
I guess this is great news for virus writers. :P And, I guess scene devs. ^^
Sep 08 2014
next sibling parent "eles" <eles eles.com> writes:
On Monday, 8 September 2014 at 07:01:19 UTC, Andrej Mitrovic via 
Digitalmars-d-announce wrote:
 On 9/7/14, Vladimir Panteleev via Digitalmars-d-announce
 <digitalmars-d-announce puremagic.com> wrote:
 I guess this is great news for virus writers. :P
A std.virus or core.virus module? ;;) Nothing sweeter than having it as a standard...
Sep 08 2014
prev sibling parent reply "Kagamin" <spam here.lot> writes:
On Monday, 8 September 2014 at 07:01:19 UTC, Andrej Mitrovic via 
Digitalmars-d-announce wrote:
 I guess this is great news for virus writers. :P
Why? Modern viruses are bloatware: https://www.virustotal.com/en/file/73559b15d1f55a9f08a5674fd4320a7ba9ff4e98f0949a1b2a756ec8eafd5caf/analysis/
Sep 08 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Monday, 8 September 2014 at 07:40:29 UTC, Kagamin wrote:
 Why? Modern viruses are bloatware: 
 https://www.virustotal.com/en/file/73559b15d1f55a9f08a5674fd4320a7ba9ff4e98f0949a1b2a756ec8eafd5caf/analysis/
That sucks. «Smallest PE file that downloads a file over WebDAV and executes it: 133 bytes» http://www.phreedom.org/research/tinype/
Sep 08 2014
parent reply "Kagamin" <spam here.lot> writes:
On Monday, 8 September 2014 at 07:59:37 UTC, Ola Fosheim Grøstad 
wrote:
 «Smallest PE file that downloads a file over WebDAV and 
 executes it: 133 bytes»

 http://www.phreedom.org/research/tinype/
But that downloaded file is bloatware, because it has to implement functionality, which is not provided by the system. That tiny pe file doesn't download anything, it's completely done by the system.
Sep 08 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Monday, 8 September 2014 at 08:08:23 UTC, Kagamin wrote:
 But that downloaded file is bloatware, because it has to 
 implement functionality, which is not provided by the system. 
 That tiny pe file doesn't download anything, it's completely 
 done by the system.
Yeah… http://stackoverflow.com/questions/284797/hello-world-in-less-than-20-bytes
Sep 08 2014
parent reply "Don" <x nospam.com> writes:
On Monday, 8 September 2014 at 08:18:32 UTC, Ola Fosheim Grøstad 
wrote:
 On Monday, 8 September 2014 at 08:08:23 UTC, Kagamin wrote:
 But that downloaded file is bloatware, because it has to 
 implement functionality, which is not provided by the system. 
 That tiny pe file doesn't download anything, it's completely 
 done by the system.
Yeah… http://stackoverflow.com/questions/284797/hello-world-in-less-than-20-bytes
My personal best -- At my first job, a customer once made a request for a very simple DOS utility. They did mention that they didn't have much disk space on their machine, so they asked me to try to make the program small. That was a once-in-a-lifetime opportunity. Naturally, I wrote it in asm. The final executable size was 15 bytes. <g> The customer loved it.
Sep 09 2014
next sibling parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Tue, 09 Sep 2014 10:20:43 +0000
schrieb "Don" <x nospam.com>:

 On Monday, 8 September 2014 at 08:18:32 UTC, Ola Fosheim Gr=C3=B8stad=20
 wrote:
 On Monday, 8 September 2014 at 08:08:23 UTC, Kagamin wrote:
 But that downloaded file is bloatware, because it has to=20
 implement functionality, which is not provided by the system.=20
 That tiny pe file doesn't download anything, it's completely=20
 done by the system.
Yeah=E2=80=A6 http://stackoverflow.com/questions/284797/hello-world-in-less-than-20-b=
ytes
=20
 My personal best --
=20
 At my first job, a customer once made a request for a very simple=20
 DOS utility. They did mention that they didn't have much disk=20
 space on their machine, so they asked me to try to make the=20
 program small.
 That was a once-in-a-lifetime opportunity. Naturally, I wrote it=20
 in asm.
 The final executable size was 15 bytes. <g>
 The customer loved it.
Vladimir: Good job! Don: Nice story. What did it do? During my time at a vocation school I wrote some stuff like a tiny Windows media player with some of the ASM in the DOS/PE header area. And an animated GIF player in ASM as a .com executable with the GIF included in it. (Easy since GIF algorithms are 16-bit and they use 8-bit color palettes) --=20 Marco
Sep 10 2014
next sibling parent ketmar via Digitalmars-d-announce <digitalmars-d-announce puremagic.com> writes:
On Wed, 10 Sep 2014 16:02:01 +0200
Marco Leise via Digitalmars-d-announce
<digitalmars-d-announce puremagic.com> wrote:

 The final executable size was 15 bytes. <g>
 The customer loved it.
and they never knows that it took at least 512 bytes anyway. or even more, depending of claster size. heh.
Sep 10 2014
prev sibling parent "Don" <x nospam.com> writes:
On Wednesday, 10 September 2014 at 13:53:32 UTC, Marco Leise 
wrote:
 Am Tue, 09 Sep 2014 10:20:43 +0000
 schrieb "Don" <x nospam.com>:

 On Monday, 8 September 2014 at 08:18:32 UTC, Ola Fosheim 
 Grøstad wrote:
 On Monday, 8 September 2014 at 08:08:23 UTC, Kagamin wrote:
 But that downloaded file is bloatware, because it has to 
 implement functionality, which is not provided by the 
 system. That tiny pe file doesn't download anything, it's 
 completely done by the system.
Yeah… http://stackoverflow.com/questions/284797/hello-world-in-less-than-20-bytes
My personal best -- At my first job, a customer once made a request for a very simple DOS utility. They did mention that they didn't have much disk space on their machine, so they asked me to try to make the program small. That was a once-in-a-lifetime opportunity. Naturally, I wrote it in asm. The final executable size was 15 bytes. <g> The customer loved it.
Vladimir: Good job! Don: Nice story. What did it do?
It blanked the screen in a particular way. It was purely for aesthetic reasons.
 During my time at a vocation school I wrote some stuff like a
 tiny Windows media player with some of the ASM in the DOS/PE
 header area. And an animated GIF player in ASM as a .com
 executable with the GIF included in it. (Easy since GIF
 algorithms are 16-bit and they use 8-bit color palettes)
Nice. That was the only time I ever made a commercial release that was entirely in asm. It only took me about ten minutes to write. It would have been far more difficult in another language. On Wednesday, 10 September 2014 at 14:17:25 UTC, ketmar via Digitalmars-d-announce wrote:
 On Wed, 10 Sep 2014 16:02:01 +0200
 Marco Leise via Digitalmars-d-announce
 <digitalmars-d-announce puremagic.com> wrote:

 The final executable size was 15 bytes. <g>
 The customer loved it.
and they never knows that it took at least 512 bytes anyway. or even more, depending of claster size. heh.
Yeah. Plus the filename took up almost as much space as the executable code. But when they said they wanted it to be small, they actually meant "less than 2 megabytes". When our sales guy saw it, he said, "You got it down to 15kb? That's incredible!" But I won't pollute D.announce any more. :)
Sep 11 2014
prev sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Tuesday, 9 September 2014 at 10:20:44 UTC, Don wrote:
 http://stackoverflow.com/questions/284797/hello-world-in-less-than-20-bytes
My personal best -- At my first job, a customer once made a request for a very simple DOS utility. They did mention that they didn't have much disk space on their machine, so they asked me to try to make the program small. That was a once-in-a-lifetime opportunity. Naturally, I wrote it in asm. The final executable size was 15 bytes. <g> The customer loved it.
:-) Out of curiosity, did you use the debug-section-hack they use for the tiny "hello world!" file in the link? Sometimes when I download bloated apps I keep thinking that if it had been done in an old-school way it would all fit in the CPU cache. I've gotta find my old 8-bit 6510/6800 code some day and take a look at it.
Sep 18 2014
prev sibling next sibling parent "ponce" <contact gam3sfrommars.fr> writes:
On Sunday, 7 September 2014 at 21:03:17 UTC, Vladimir Panteleev 
wrote:
 The 438-byte "Hello, world" program is achieved using Crinkler, 
 which is a COFF linker with aggressive compression and header 
 optimization. It was created for compressing 4K demos.
Pretty cool! Up to now D had little chance to compete in 4k and 64k demo competitions because of the inability to use Crinkler.
Sep 08 2014
prev sibling next sibling parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Sunday, 7 September 2014 at 21:03:17 UTC, Vladimir Panteleev 
wrote:
 The 438-byte "Hello, world" program is achieved using Crinkler, 
 which is a COFF linker with aggressive compression and header 
 optimization. It was created for compressing 4K demos.
Pretty nice! Is the format correct too, or can it break on OS upgrades?
Sep 08 2014
parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Monday, 8 September 2014 at 08:06:37 UTC, Ola Fosheim Grøstad 
wrote:
 On Sunday, 7 September 2014 at 21:03:17 UTC, Vladimir Panteleev 
 wrote:
 The 438-byte "Hello, world" program is achieved using 
 Crinkler, which is a COFF linker with aggressive compression 
 and header optimization. It was created for compressing 4K 
 demos.
Pretty nice! Is the format correct too, or can it break on OS upgrades?
From the Crinkler manual: COMPATIBILITY ------------- The goal of Crinkler is for the produced EXE files to be compatible with all widely used Windows versions and configurations. As of version 1.4, the EXE files produced by Crinkler are, to the best of our knowledge, compatible with Windows XP, Windows Vista, Windows 7 and Windows 8, both 32 bit and 64 bit versions. They are compatible with Data Execution Prevention and with execution hooks that inspect the import or export table of launched executables (graphics drivers are known to do this). It is not a primary goal of Crinkler to anticipate incompatibilities that may arise in the future as a consequence of new Windows versions, graphics drivers or other widespread system changes. Guaranteeing such compatibility would require Crinkler to follow the EXE file format specification to the letter, precluding most of the header hacks that Crinkler utilizes in order to reduce the size overhead of the EXE format as much as possible. Rather, we strive to continually monitor the compatibility situation and release a new, fixed version of Crinkler whenever a situation arises that affects the compatibility severely (such as a new, incompatible version of Windows). This has occurred several times already throughout the history of Crinkler. Each new version of Crinkler not only produces executables that are compatible with the current majority of targeted systems. It also includes a way of fixing old Crinkler executables to have the same level of compatibility. See the section on recompression for more details on this feature. This compatibility strategy ensures that intros made using Crinkler will continue to be accessible to their audience, even if the Windows EXE loader changes in an incompatible way that could not be anticipated at the time the intro was produced.
Sep 08 2014
prev sibling next sibling parent reply "Trass3r" <un known.com> writes:
And how do ldc and gdc do? =)
Sep 09 2014
parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Tuesday, 9 September 2014 at 20:07:33 UTC, Trass3r wrote:
 And how do ldc and gdc do? =)
LDC doesn't do very well. It generates more verbose code, even with -Oz. I'll try GDC next. In other news, I switched from makefiles to a dedicated build tool, as their limitations were becoming constraining.
Sep 20 2014
prev sibling parent reply "dcrepid" <dcrepid none.com> writes:
 -m32mscoff allows using more linkers. Specifically, the 
 Microsoft Linker and Crinkler, which only understand COFF, can 
 both generate executables which are much smaller than those 
 created by OPTLINK.
Hi, I've been experimenting with getting a basic D program consisting of nothing more than "int main() { return 0; }" to compile using -m32mscoff, but I keep getting this error message: fatal error LNK1104: cannot open file 'phobos32mscoff.lib' I don't see that library file anywhere in the D folders, so I'm wondering what I need to do to workaround that problem (or to create that file). I'm using the latest beta (v2.067.0-b1), and using VC2010 linker. Thanks!
Sep 15 2014
parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Monday, 15 September 2014 at 21:18:53 UTC, dcrepid wrote:
 -m32mscoff allows using more linkers. Specifically, the 
 Microsoft Linker and Crinkler, which only understand COFF, can 
 both generate executables which are much smaller than those 
 created by OPTLINK.
Hi, I've been experimenting with getting a basic D program consisting of nothing more than "int main() { return 0; }" to compile using -m32mscoff, but I keep getting this error message: fatal error LNK1104: cannot open file 'phobos32mscoff.lib' I don't see that library file anywhere in the D folders, so I'm wondering what I need to do to workaround that problem (or to create that file). I'm using the latest beta (v2.067.0-b1), and using VC2010 linker. Thanks!
You have to build it yourself, run "make -f win64.mak MODEL=32mscoff" in Druntime and Phobos source directories.
Sep 15 2014
parent reply "dcrepid" <dcrepid none.com> writes:
On Tuesday, 16 September 2014 at 00:11:26 UTC, Vladimir Panteleev 
wrote:
 On Monday, 15 September 2014 at 21:18:53 UTC, dcrepid wrote:
 You have to build it yourself, run "make -f win64.mak 
 MODEL=32mscoff" in Druntime and Phobos source directories.
Thanks for the help. Unfortunately, I didn't want 64-bit library/object files so I had to modify the make files to point to the VC2010 32-bit compilers (Win64.mak points to the amd64 folders, so I'm a bit concerned now - did you really create a win32 or win64 exe?). However, I was able to make the druntime libraries with 32-bit coff libs. The phobos library failed to create though, and I had to manipulate the zlib make files as well to get that lib created. And after all that, now I keep getting these messages: std\stdio.d(35): Error: module std.c.stdio import 'FHND_WCHAR' not found std\stdio.d(35): Error: module std.c.stdio import 'FHND_TEXT' not found I checked all the libraries are there, set DM_HOME, the VC environment variables, put the DMD and DMC bin files in the path, and forced -I includes to point to the right folders, but something is botched somewhere. Bah, I give up!
Sep 16 2014
parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Tuesday, 16 September 2014 at 12:33:26 UTC, dcrepid wrote:
 Thanks for the help.  Unfortunately, I didn't want 64-bit 
 library/object files so I had to modify the make files to point 
 to the VC2010 32-bit compilers (Win64.mak points to the amd64 
 folders, so I'm a bit concerned now - did you really create a 
 win32 or win64 exe?).
Yes, sorry, that was the wrong command. Currently you have to also specify the full paths to the compiler on make's command line. I sent in two pull requests to document and simplify building phobos32mscoff.lib: https://github.com/D-Programming-Language/druntime/pull/960 https://github.com/D-Programming-Language/phobos/pull/2526
Sep 17 2014
next sibling parent reply "dcrepid" <dcrepid none.com> writes:
On Wednesday, 17 September 2014 at 20:49:37 UTC, Vladimir 
Panteleev wrote:
 Yes, sorry, that was the wrong command. Currently you have to 
 also specify the full paths to the compiler on make's command 
 line. I sent in two pull requests to document and simplify 
 building phobos32mscoff.lib:

 https://github.com/D-Programming-Language/druntime/pull/960
 https://github.com/D-Programming-Language/phobos/pull/2526
Thanks, I tried merging the modifications into the 'win32mscoff.mak' files I've made, since it seems like there's too much hacking to get this to work right, and why not just have a 3rd build option that reflects what it really makes? Anyway, I still am encountering the same problem previously described with those error messages. I've narrowed it down to a seeming problem with the way the versioning seems to work? The file stdio.d is importing 'FHND_WCHAR' and 'FHND_TEXT', which are only declared for the CRuntime_DigitalMars version. (The file is importing from druntime.import.core.stdc where those symbols are found.) I tried forcing version=CRuntime_Microsoft in the DMD flags, but it doesn't seem to care. Perhaps this is an issue with the current beta, but I'm not experienced enough with make files or versioning etc to make that determination.
Sep 17 2014
parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thursday, 18 September 2014 at 04:50:52 UTC, dcrepid wrote:
 On Wednesday, 17 September 2014 at 20:49:37 UTC, Vladimir 
 Panteleev wrote:
 Yes, sorry, that was the wrong command. Currently you have to 
 also specify the full paths to the compiler on make's command 
 line. I sent in two pull requests to document and simplify 
 building phobos32mscoff.lib:

 https://github.com/D-Programming-Language/druntime/pull/960
 https://github.com/D-Programming-Language/phobos/pull/2526
Thanks, I tried merging the modifications into the 'win32mscoff.mak' files I've made, since it seems like there's too much hacking to get this to work right, and why not just have a 3rd build option that reflects what it really makes?
You mean yet another makefile? It's onerous enough already to duplicate all makefile changes across the current set. Yet another makefile for a rarely-used configuration wouldn't pull its own weight.
 Perhaps this is an issue with the current beta, but I'm not 
 experienced enough with make files or versioning etc to make 
 that determination.
It sounds like whatever version you have doesn't yet have the necessary Phobos/Druntime changes. You should try building from the git version.
Sep 18 2014
prev sibling parent "Georgy Shepelev" <geo.shepelev gmail.com> writes:
On Wednesday, 17 September 2014 at 20:49:37 UTC, Vladimir 
Panteleev wrote:
 On Tuesday, 16 September 2014 at 12:33:26 UTC, dcrepid wrote:
 Thanks for the help.  Unfortunately, I didn't want 64-bit 
 library/object files so I had to modify the make files to 
 point to the VC2010 32-bit compilers (Win64.mak points to the 
 amd64 folders, so I'm a bit concerned now - did you really 
 create a win32 or win64 exe?).
Yes, sorry, that was the wrong command. Currently you have to also specify the full paths to the compiler on make's command line. I sent in two pull requests to document and simplify building phobos32mscoff.lib: https://github.com/D-Programming-Language/druntime/pull/960 https://github.com/D-Programming-Language/phobos/pull/2526
Hi all there! I've faced the issue with rebuilding druntime/phobos that come with binary distribution of dmd for windows in COFF-format. Firstly, VCDIR and SDKDIR should be specified correctly. It is not a big deal since they can be set as parameters to `make' but I suggest to use environment variables %VCINSTALLDIR% and %WindowsSdkDir% in win64.mak to ease compiling in Visual Studio's command prompt. For example, on my working machine SDK is installed to the D:\WinPrograms path. Second, I suppose your approach with `VCBIN_SUBDIR' for CC, LD, AR/LIB paths is fine. The main trouble is quotes. =) They are the reason why I've got the error 'cl : Command line error D8003 : missing source filename'. And the last thing is zlib. Its win64.mak also has definition of macros CC, LD, etc but the makefile is called from phobos' win64.mak with the same arguments and... quotes! =) So I removed the arguments to zlib's win64.mak. I suppose that the process of building druntime/phobos should be like: 1) open VS command prompt; 2) add dmd to the PATH; 3) cd R:\equired\path; 4) make -f win64.mak MODEL=32mscoff Diff files with my changes for both 67.1 and 68.0 versions are available there: https://drive.google.com/folderview?id=0Bw5iSiWPdccTfm1ZeXVDcW9fSklmc3Z2TjRlVGVpX3RyNnZJM3gxWVBneGNzdWw4dk9Cd1U
Aug 12 2015