Live data from Hacker News

HelloAssembly: The smallest possible complete Windows application (2021)

github.com

51–53 of 53 posts

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#52

Earlier quoted context omitted.

Officially, one should not use KERNEL32.dll for instance but go via crt. In practice, most interfaces are stable.

KERNEL32.DLL (in spite of the name) provides user-mode system services for the Windows API. The CRT provides the C99 API. There are many entry points to the same thing on Windows; you can do any of `malloc`/`HeapAlloc`/`new`/`VirtualAlloc` to get a void* memory buffer. `malloc` is from the CRT; `HeapAlloc` is from KERNEL32.DLL, and `new` is from the C++ runtime.

Many many different ways to allocate memory. malloc, new, HeapAlloc, LocalAlloc, GlobalAlloc, CoTaskMemAlloc, etc. GlobalAlloc and LocalAlloc are pretty much obsolete. "malloc" sometimes redirects to HeapAlloc with the default process heap, but only sometimes, it depends entirely on which compiler and CRT is used.

It just causes one big headache that a DLL can't simply return a pointer and have the caller use "free", because malloc/free can be incompatible across modules.

This just led to the COM standard, featuring reference-counted objects that don't care what underlying way was used to allocate the memory. For the situations where you do need memory buffers, COM enforces the use of CoTaskMemAlloc/CoTaskMemFree.

Re: HelloAssembly: The smallest possible complete Windows application (2021)

#53
post #47

You can get a sub 20kb executable with C in MSVC and no weird tricks, i.e. just setting a particular combination of compiler/linker flags, like /NODEFAULTIB, /MERGE, /FILEALIGN:512 etc. Small enough that it's basically nothing, downloads in a couple of seconds over 56k dialup, and you get to use normal tooling. This is the compromise that makes the most sense to me, for products you're actually shipping. If you want…

Then you load User32.dll, and you get 2MB of commit and 1MB of private bytes. Throw in a Message Box, and it's 272KB more private bytes and 388K more commit. Windows 10 makes it literally impossible to write something that uses low memory and uses an actual window.

True, the project where I used the approach above was a TUI, so windows terminal sort of eats the impact of stuff like user32 and dwrite for you.

One trick I know of to make user32 a bit more lightweight is to call ImmDisableIme prior to creating your first window. This disables a lot of the TSF integration, which is notably quite slow. Not sure if it impacts memory footprint but worth a try. It of course does what the name says and disables IME support, so not a viable option if you have users who need IME

Post reply on HN