32 Bit MASM
 Warning Danger Zone
High speed software

mlogo.jpeg

masm32v6.zip
MASM32 is a working development environment for programmers who want to write 32 bit Microsoft Assembler (MASM). It comes ready to run and with an installation program that should not cause any problems. It installs in a directory directly of the root directory of the chosen installation drive. It will not install on a network drive.

MASM32 has its own tools and editor, it has an extensive range of working example code, it has additional library functions and it has Iczelion's excellent series of tutorials. MASM32 comes with a code generator called PROSTART to create projects in a minute or so. It is an excellent learning tool as it creates correct API based code that works from fully documented API function calls and it is well suited for prototyping and testing ideas on the fly without having to manually write a front end.

MASM32 has a range of winhelp format help files that run directly from the editor to make useful information available in a fast and convenient way. The overview of MASM32 is now in HTML format so that it can be read with a web browser. The WINDOWS.INC file is now over 800k and has a very extensive set of equates and structures. It is a shared project with Iczelion.

MASM32 is not intended as a learners package, it is aimed squarely at experienced programmers who are familiar with windows API coding, have written code in compilers and have done some work in assembler. While it has a suitable range of facilities to write assembler applications, it does not address the learners market. Any programmer is welcome to use MASM32 but unless the experience in compilers and API based coding is adequate, concepts such as data types, registers, assembler mnemonics and API function calls will be very difficult to grasp.

v6sp1.zip
Service pack 1 for version 6 of MASM32. It contains later binaries for Quick Editor and TheGun, extra example code, additional library functions and it has two specialised libraries written for MASM32. Ray Filiatreault has written a complete mixed integer library with its own example code and Ernie Murphy has written a version of his Component Object Model library for MASM32. This is NOT an automatic installation, it must be installed manually according to the readme.txt file.

v6sp2.zip
Service pack 2 for MASM32v6 has a new version of the Prostart code wizard, an optimised set of library modules and additional library modules. It has a new version of the subclass wizard, the latest version of WINDOWS.INC, new help files and extra example code. Ernie Murphy has upgraded his comlib package to version 1.1 which has been included in the service pack. Note that this service pack must be installed manually according to the README.TXT file.

clparam.zip
This is an accessory for Quick Editor that allows the programmer to run an executable file from the editor and append command line arguments to it. The secret to making this tiny program work properly is to actually read the text file that comes with it.

l2incA & l2incU
These are a pair of identical executable files except that the A version produces ANSI functions prototypes and the U version produces UNICODE prototypes. These versions are slightly faster than the previous one, they are designed to be used with the PLATFORMSDK import libraries but have also been tested with the VS98 set of libraries and work OK. They test if a library is only a static library or if it contains no imports and will not write an empty include file.

masmflip.zip
This is the masm version of Mike Bibby's original example of how to use Direct Draw. It has been slightly modified with the author's permission so that it will build in the MASM32 environment. Mike has supplied the necessary include files for the Direct Draw interface.

dc-ddraw.zip
This is a Direct Draw plasma demo by Ewald Snel & Gatt. It requires a 32 bit colour monitor to run it but it displays some very clever programming techniques drawn from C programming. The include file by Ewald Snel is particularly good and Gatt has written a small text tutorial to explain how it works. It has been slightly modified with the authors permission so it will build from the MASM32 environment.

Why Write in 32 bit assembler ?

For programmers who are not familiar with 32 bit Windows assembler, there is speed and performance available that you may never have seen before and contrary to popular legend, if you can write a Windows application in C, Basic, Pascal or other similar compiler based languages, you can write it in MASM with very similar looking code if you bother to learn the MASM high level syntax.

MASM32 has been designed to be familiar to programmers who have already written API based code in Windows. The invoke syntax of MASM allows functions to be called in much the same way as they are called in a high level compiler.

The traditional notation for calling a function is as follows,

        push par4
        push par3
        push par2
        push par1
        call FunctionName
        mov retval, eax

With the MASM "invoke" syntax, you code as follows,

        invoke FunctionName,par1, par2, par3, par4
        mov retval, eax

Apart from much clearer coding, there is another important advantage in that the "invoke" syntax is type checked against function prototypes so that parameter number and size errors are caught at assembly time.

MASM uses the notation for addresses in the invoke syntax of ADDR. This will resolve to an address in the correct form at assembly time. To call a function that uses a zero terminated string as a parameter, you use,

        invoke FunctionName,ADDR szString

MASM32 also uses a high level simulation of branching code in the WndProc of its example code that is very similar to a standard C switch block.

        .if par1 == num
            code
            code
        .elseif par2 == num
            code
            code
        .else
            code
            code
        .endif

Combined with the invoke syntax, this allows for very clear coding of otherwise unreadable and error prone WndProc and similar functions. Code written in this way has a similar "feel" to writing in a compiler using inline assembler but the difference is that with pure assembler, there are no problematic runtime libraries and the size and speed when written correctly is beyond the capacity of compilers.

Below is the source code for a basic window with an icon and menu supplied with MASM32. It assembles at 5120 bytes. This should be enough to convince the programmer who still works in other languages that modern assembler has many advantages over the compilers that they are using in terms of both speed and size. Examine the code and it has much of the familiarity of writing C but without the problems associated with using the often very uneven C runtime libraries.

; #########################################################################

      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive

; #########################################################################

      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc

      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib

; #########################################################################

      ;=============
      ; Local macros
      ;=============

      szText MACRO Name, Text:VARARG
        LOCAL lbl
          jmp lbl
            Name db Text,0
          lbl:
        ENDM

      m2m MACRO M1, M2
        push M2
        pop  M1
      ENDM

      return MACRO arg
        mov eax, arg
        ret
      ENDM

        ;=================
        ; Local prototypes
        ;=================
        WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
        WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
        TopXY PROTO   :DWORD,:DWORD

    .data
        szDisplayName db "Template",0
        CommandLine   dd 0
        hWnd          dd 0
        hInstance     dd 0

    .code

start:
        invoke GetModuleHandle, NULL
        mov hInstance, eax

        invoke GetCommandLine
        mov CommandLine, eax

        invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
        invoke ExitProcess,eax

; #########################################################################

WinMain proc hInst     :DWORD,
             hPrevInst :DWORD,
             CmdLine   :DWORD,
             CmdShow   :DWORD

        ;====================
        ; Put LOCALs on stack
        ;====================

        LOCAL wc   :WNDCLASSEX
        LOCAL msg  :MSG

        LOCAL Wwd  :DWORD
        LOCAL Wht  :DWORD
        LOCAL Wtx  :DWORD
        LOCAL Wty  :DWORD

        ;==================================================
        ; Fill WNDCLASSEX structure with required variables
        ;==================================================

        mov wc.cbSize,         sizeof WNDCLASSEX
        mov wc.style,          CS_HREDRAW or CS_VREDRAW \
                               or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc,    offset WndProc
        mov wc.cbClsExtra,     NULL
        mov wc.cbWndExtra,     NULL
        m2m wc.hInstance,      hInst
        mov wc.hbrBackground,  COLOR_BTNFACE+1
        mov wc.lpszMenuName,   NULL
        mov wc.lpszClassName,  offset szClassName
          invoke LoadIcon,hInst,500    ; icon ID
        mov wc.hIcon,          eax
          invoke LoadCursor,NULL,IDC_ARROW
        mov wc.hCursor,        eax
        mov wc.hIconSm,        0

        invoke RegisterClassEx, ADDR wc

        ;================================
        ; Centre window at following size
        ;================================

        mov Wwd, 500
        mov Wht, 350

        invoke GetSystemMetrics,SM_CXSCREEN
        invoke TopXY,Wwd,eax
        mov Wtx, eax

        invoke GetSystemMetrics,SM_CYSCREEN
        invoke TopXY,Wht,eax
        mov Wty, eax

        szText szClassName,"Template_Class"

        invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,
                              ADDR szClassName,
                              ADDR szDisplayName,
                              WS_OVERLAPPEDWINDOW,
                              Wtx,Wty,Wwd,Wht,
                              NULL,NULL,
                              hInst,NULL
        mov   hWnd,eax

        invoke LoadMenu,hInst,600  ; menu ID
        invoke SetMenu,hWnd,eax

        invoke ShowWindow,hWnd,SW_SHOWNORMAL
        invoke UpdateWindow,hWnd

      ;===================================
      ; Loop until PostQuitMessage is sent
      ;===================================

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp StartLoop
    ExitLoop:

      return msg.wParam

WinMain endp

; #########################################################################

WndProc proc hWin   :DWORD,
             uMsg   :DWORD,
            wParam :DWORD,
             lParam :DWORD

    .if uMsg == WM_COMMAND
    ;======== menu commands ========
        .if wParam == 1000
            invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
        .elseif wParam == 1900
            szText TheMsg,"Assembler, Pure & Simple"
            invoke MessageBox,hWin,ADDR TheMsg,ADDR szDisplayName,MB_OK
        .endif
    ;====== end menu commands ======

    .elseif uMsg == WM_CLOSE
        szText TheText,"Please Confirm Exit"
        invoke MessageBox,hWin,ADDR TheText,ADDR szDisplayName,MB_YESNO
          .if eax == IDNO
            return 0
          .endif
    .elseif uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
        return 0
    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam

    ret

WndProc endp

; ########################################################################

TopXY proc wDim:DWORD, sDim:DWORD

    shr sDim, 1      ; divide screen dimension by 2
    shr wDim, 1      ; divide window dimension by 2
    mov eax, wDim    ; copy window dimension into eax
    sub sDim, eax    ; sub half win dimension from half screen dimension

    return sDim

TopXY endp

; ########################################################################

end start