logoalt Hacker News

xhrpost10/12/20246 repliesview on HN

Is this what is meant when people say that Windows doesn't have stable APIs? I've not programmed windows/desktop software and have often been confused as to why if you're writing an assembly program, you have to use at least a little C if you want to make Windows system calls[1]. The compiler must be compiling the call into "something" so can't you just write that "something" directly in assembly?

[1]: The classic example being Chris Sawyer writing nearly all of Rollercoaster Tycoon in x86 assembly but requiring just enough C for the system calls.


Replies

xeeeeeeeeeeenu10/12/2024

Unlike Linux, Windows syscalls aren't documented and their IDs constantly change[1]. Instead, you're supposed to call wrapper functions provided by ntdll.dll. That said, most programs use even higher level functions from kernel32.dll and friends.

You don't need C/C++ to call a function from a DLL, but it makes things easier, especially for more complex APIs like DirectX.

[1] - https://j00ru.vexillium.org/syscalls/nt/64/

skissane10/12/2024

> have often been confused as to why if you're writing an assembly program, you have to use at least a little C if you want to make Windows system calls

This isn’t true. The Win32 API is C-based. You can call a C-based API from hand-written assembly just fine. You just have to understand the ABI calling convention so you know how to do it. You can also write some C code to call the API and then get the C compiler to output assembly and then you can copy/paste the relevant portion into your hand-written assembly

> The classic example being Chris Sawyer writing nearly all of Rollercoaster Tycoon in x86 assembly but requiring just enough C for the system calls.

I don’t think he had to do it that way. Maybe he just decided that was the path of least resistance for him.

Ultimately, he has to have assembly call C at some point, since his own assembly code has to call his C function which calls the Win32 API (technically not system calls, as other commenters have pointed out). Maybe, given the Win32 API involves some rather complex data structures, numerous constant definitions, various helper macros, etc, he may have just found it easier to use some of that stuff from C instead of trying to replicate the complexity in hand-written assembly, or having to translate all the C header definitions he needed into corresponding assembler macros

show 1 reply
GoblinSlayer10/12/2024

--- hello_world.asm ---

  bits 64
  default rel

  segment .data
   msg db "Hello world!", 0xd, 0xa, 0

  segment .text
  global main
  extern ExitProcess

  extern printf

  main:
   push    rbp
   mov     rbp, rsp
   sub     rsp, 32

   lea     rcx, [msg]
   call    printf

   xor     rax, rax
   call    ExitProcess
---

nasm -f win64 -o hello_world.obj hello_world.asm

link hello_world.obj /subsystem:console /entry:main /out:hello_world_basic.exe

show 1 reply
userbinator10/12/2024

You don't need to use C if you want to call Win32 functions, although the calling convention is based on C. The stable API is not the user-kernel boundary but instead a set of DLLs (kernel32, user32, gdi32, etc.), which makes sense if you look at the history: Windows started out as a GUI on top of DOS. The actual system call mechanism is very different between the DOS-based lineage and the NT-based ones, but the Win32 API remains nearly the same.

carom10/12/2024

Windows system call numbers aren't stable. It is done through their system libraries. So rather than invoking a syscall number as you do on Linux, if you want your code to be portable you import the DLL with that functionality and call the function. You can do this all from ASM without needing C, though the system libraries were likely written in a higher level language like C. You can also invoke system calls by number directly, it is just liable to not work on another version of Windows.

dist-epoch10/12/2024

Windows is legendary for having the most stable APIs of any major OS. Windows software compiled in 1997 will still run on it.

show 1 reply