/nqa



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