Download (GEN, 280 kB)
Not Quite Assembly is an assembler/linker with some high-level constructs, for things like program flow control.
It is capable of generating PE executables for Windows (.EXE and .DLL), as well as .COM files for DOS.
The linker is capable of performing some size-optimizations, like merging sections, and placing code/data within the PE headers. Its source code is included with the download, and might be of interest to someone who's looking for info on the PE format.
A minimal example:
.target win32 -- Set the target to Win32 .entry hello -- Set the entrypoint include windows.inc inclib kernel32.lib inclib user32.lib .code DEFUN hello() MessageBoxA(NULL,"Hello from first.exe!","Message",MB_OK) ExitProcess(0) END hello
A DOS example:
.target com -- Set the target to COM (plain binary) .bits16 -- Set the default operand size to 16 bits .entry hello -- Set the entrypoint .prologue off -- No function prologue (or epilogue) .data BYTE helloString[] = "Hello world!$" .code DEFUN hello() mov dx,&helloString mov ah,9 int 21h ret END hello
Showing a bit of mixed assembly and "HLL":
DEFUN main() GetModuleHandleA(NULL) mov hInstance,eax CreateBasicWindow(hInstance,360,240) ShowWindow(hwnd,SW_SHOWDEFAULT) SetupPalette() -- Allocate room for a 320x200 bitmap, plus a little more LocalAlloc(LMEM_ZEROINIT,65000) mov videoBuffer,eax -- Keep looping until the window is closed while 1 do PeekMessageA(&myMsg,hwnd,0,0,PM_NOREMOVE) if eax then GetMessageA(&myMsg,hwnd,0,0) break when !eax TranslateMessage(&myMsg) DispatchMessageA(&myMsg) else DrawFire() end if end while LocalFree(videoBuffer) DestroyWindow(hwnd) ExitProcess(0) return 0 END main