Skip to content

Instantly share code, notes, and snippets.

@skeeto
Last active March 17, 2026 13:57
Show Gist options
  • Select an option

  • Save skeeto/618eadfd970717103f243ecbbb920f35 to your computer and use it in GitHub Desktop.

Select an option

Save skeeto/618eadfd970717103f243ecbbb920f35 to your computer and use it in GitHub Desktop.
// $ cc -nostartfiles -o hello.exe hello.c
// $ ./hello world
// Ref: https://github.com/skeeto/w64devkit/discussions/340
// This is free and unencumbered software released into the public domain.
#include <stdint.h>
#include <uchar.h>
#define nil ((uintptr_t)0)
typedef uintptr_t Syscall(...);
typedef struct {
Syscall *ExitProcess;
Syscall *GetCommandLineW;
Syscall *GetProcAddress;
Syscall *GetStdHandle;
Syscall *LoadLibraryA;
Syscall *WriteConsoleW;
} Kernel32;
typedef struct {
Syscall *CommandLineToArgvW;
} Shell32;
static Kernel32 new_kernel32()
{
Syscall LoadLibraryA, GetProcAddress; // bootstrap
uintptr_t h = LoadLibraryA("kernel32");
return (Kernel32){
.ExitProcess = (Syscall *)GetProcAddress(h, "ExitProcess"),
.GetCommandLineW = (Syscall *)GetProcAddress(h, "GetCommandLineW"),
.GetProcAddress = (Syscall *)GetProcAddress(h, "GetProcAddress"),
.GetStdHandle = (Syscall *)GetProcAddress(h, "GetStdHandle"),
.LoadLibraryA = (Syscall *)GetProcAddress(h, "LoadLibraryA"),
.WriteConsoleW = (Syscall *)GetProcAddress(h, "WriteConsoleW"),
};
}
static Shell32 new_shell32(Kernel32 kernel32)
{
uintptr_t h = kernel32.LoadLibraryA("shell32");
return (Shell32){
.CommandLineToArgvW =
(Syscall *)kernel32.GetProcAddress(h, "CommandLineToArgvW"),
};
}
static ptrdiff_t char16len(char16_t *s)
{
ptrdiff_t len = 0;
for (; s[len]; len++) {}
return len;
}
void mainCRTStartup()
{
Kernel32 kernel32 = new_kernel32();
Shell32 shell32 = new_shell32(kernel32);
char16_t *cmd = (char16_t *)kernel32.GetCommandLineW();
int argc = {};
char16_t **argv = (char16_t **)shell32.CommandLineToArgvW(cmd, &argc);
uintptr_t out = kernel32.GetStdHandle(-11);
for (int i = 1; i < argc; i++) {
kernel32.WriteConsoleW(out, u"hello, ", 7, nil, nil);
kernel32.WriteConsoleW(out, argv[i], char16len(argv[i]), nil, nil);
kernel32.WriteConsoleW(out, u"\n", 1, nil, nil);
}
kernel32.ExitProcess(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment