The Esstu Pack

Index

S2Macros

For my OS/2 programming, and also as a lesson in macro writing for the NASM preprocessor, I wrote a set of handy macros which I now use extensively. In the hope that someone else is writing OS/2 programs in pure assembly using NASM, I am releasing this to the world in the hope that someone will send me an email saying how much they like it.

To use the S2Macros, simply %include the file at the top of your ASM. I have a top-level ASM directory, in which I place S2MACROS.ASM, and subdirectories for various projects (one for RxDraw, one for Pigeon, one for BMPDraw, etc), so .ASM files %include "..\S2MACROS.ASM". If you place this file in a different location, feel free to change any downloaded source to point to it.

The macros provided are:

func
Very simple, but handy when writing exported functions. Just code 'func FunctionName' and FunctionName will be declared global and exported, defines the label, and prepares the stack frame with push ebp/mov ebp,esp. This was my first attempt at making a useful macro.
callos2
A very useful macro! callos2 calls an OS/2 API function, pushing the arguments (in reverse order), calling the function (first declaring it extern), and cleans up the stack afterwards. The return value is left in eax. Coding example: 'callos2 DosBeep,eax,[Dur]' will beep at a frequency as specified in eax, for a duration specified in the memory location Dur (which should be defined as 'Dur dd 250' or similar). Parameters are always pushed as dwords - anything which isn't a dword will have to be handled carefully. This macro assumes 32-bit programming, and would be useless in a 16-bit program because the calling convention is different (see Assembly Tips, Tricks and Traps for more on this).
switch, case, default, endswitch
A set of four macros to implement vaguely C-like switch processing. This is not easy to describe, so just have a look at the example below.

mov eax,[ebp+12]
switch eax
case 0x01 ;WM_CREATE
;code for WM_CREATE

case 0x23 ;WM_PAINT
callos2 WinBeginPaint,[ebp+8],0,Paint.Rectl
mov [Paint.hps],eax
;Painting code
callos2 WinEndPaint,[Paint.hps]

case 0x20 ;WM_COMMAND
mov ax,[ebp+16] ;Yes, AX not EAX - get LOUSHORT
switch ax
case 101 ;Exit (F3)
callos2 WinPostMsg,[ebp+8],0x2A,0,0 ;0x2A = WM_QUIT

default
callos2 WinDefWindowProc,[ebp+8],[ebp+12],[ebp+16],[ebp+20]
mov esp,ebp
pop ebp
ret
endswitch
xor eax,eax

case 0x29 ;WM_CLOSE
callos2 WinPostMsg,[ebp+8],0x2A,0,0 ;0x2A = WM_QUIT

default
callos2 WinDefWindowProc,[ebp+8],[ebp+12],[ebp+16],[ebp+20]
mov esp,ebp
pop ebp
ret
endswitch
This code is part of the basic window procedure code as used in my PM programs. It uses switch to look at the msg parameter ([ebp+12]) but note that each case statement has a comparison directly involving the switched value - so use AL, AX, or EAX for best performance, and avoid memory locations if possible. callos2 is also used several times, and the final result bears sufficient resemblance to C code to be easily convertible to and from it.
msg/say
A simple pair of macros which make displaying of constant messages easy. Just use msg in your data segment, and say in your code segment, and when say is executed the msg will be displayed. Great for little debugging messages, error messages, opening display, or anything of the sort.
In your code segment:
say hello
In your data segment:
msg hello,"Hello, World!",13,10
The first argument to msg becomes a label, and all the rest are placed after "db". Another label, ".len", is defined with equ to be the length of the string.

say takes its first argument as a string pointer, and {first arg}.len as the length, and passes the appropriate data to DosWrite, via the callos2 macro.

File: S2MACROS.ZIP
Requires: OS/2, NASM
Installation: Unzip, %include in .ASM file.
Operation: Use macros.
De-installation: Delete.
Distribution: Open Source.