32 Bit MASM
 Warning Danger Zone
High speed software

Download MASM32v7
MASM32 version 7 is a working development environment for programmers who choose to either learn or write 32 bit Microsoft assembler (MASM). Installation is an automated process that will install on the local drive of your choice. MASM32 will not install on a network drive.

MASM32 comes with its own editor that is preset with additional tools and accessories. There is an extensive body of example code to use as reference for many different coding techniques. A code wizard is supplied that will create working application skeletons in a few minutes or less that can be used for prototyping or application development. There is an additional plugin that allows user designed template support. A new debug watch window is supplied with MASM32 to make debugging live values in an application easier and more accurate.

MASM32 has a wide range of help files available as reference that run directly from the editor and the overview is written in HTML format so it can be read in a web browser. MASM32 aslo includes a subset of Iczelion's excellent tutorials which are designed to assist programmers become familiar with assembler prtogramming under 32 bit windows.

MASM32 is not intended as a programming beginners package, it is squarely aimed at experienced programmers who are familiar with windows API programming with compilers and have done some work in assembler. The package assumes that the programmer already knows enough to start working in assembler and is designed with this level in mind. Any programmer is welcome to use MASM32 but unless they have the experience level that is assumed in the design of MASM32, concepts like register sizes to data types, register usage, assembler mnemonics, API calls, calling conventions and other similar technical data will be very difficult to grasp. Programming beginners are better served by learning a higher level language first and when they are familiar enough with the technical concepts involved, they can come back to assembler later.

All of the files and programs in MASM32 are copyright software owned by a range of different people and companies. The user should become familiar with the different copyrights and be willing to comply with the rights and responsibilities afforded to the user under copyright by the different copyright holders. MASM32 is true freeware, it is not for sale and cannot be sold or  included in or bundled with any form of commercial software.

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.

Back to Home Page

Why Write in 32 bit assembler ?

Assembler affords the programmer looking for additional performance a three pronged approach to performance based solutions. MASM can build very small high performance executable files that are well suited where size and speed matter. When additional performance is required for other languages, MASM can enhance the performance of these languages with small fast and powerful dynamic link libraries. For programmers who work in Microsoft Visual C/C++, MASM builds modules and libraries that are in the same format so the C/C++ programmer can build modules or libraries in MASM and directly link them into their own C/C++ programs.

This allows the C/C++ programmer to target critical areas of their code in a very efficient and convenient manner, graphics manipulation, games, very high speed data manipulation and processing, parsing at speeds that most programmers have never seen, encryption, compression and any other form of information processing that is processor intensive.

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/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 code for a window that has a menu, toolbar, common dialog support for file open and close,  is drag and drop enabled and builds at 7680 bytes. It was created in about 20 seconds with the Prostart code Wizard. The familiarity to SDK C is both obvious and intentional so that programmers from other language backgrounds will find writing assembler for 32 bit Windows is not as traumatic as many expect.

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

      .486                      ; create 32 bit code
      .model flat, stdcall      ; 32 bit memory model
      option casemap :none      ; case sensitive

      include Project.inc       ; local includes for this file
      include dbmacros.asm
      include errormac.asm

.code

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

start:

      invoke InitCommonControls

    ; ------------------
    ; set global values
    ; ------------------
      invoke GetModuleHandle, NULL
      mov hInstance, eax

      invoke GetCommandLine
      mov CommandLine, eax

      invoke LoadIcon,hInstance,500    ; icon ID
      mov hIcon, eax

      invoke LoadCursor,NULL,IDC_ARROW
      mov hCursor, eax

      invoke GetSystemMetrics,SM_CXSCREEN
      mov sWid, eax

      invoke GetSystemMetrics,SM_CYSCREEN
      mov sHgt, eax

      call Main

      invoke ExitProcess,eax

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

Main proc

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

    STRING szClassName,"Prostart_Class"

  ; --------------------------------------------
  ; register class name for CreateWindowEx call
  ; --------------------------------------------
    invoke RegisterWinClass,ADDR WndProc,ADDR szClassName,
                       hIcon,hCursor,COLOR_BTNFACE+1

  ; -------------------------------------------------
  ; macro to autoscale window co-ordinates to screen
  ; percentages and centre window at those sizes.
  ; -------------------------------------------------
    AutoScale 75, 70

    invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES,
                          ADDR szClassName,
                          ADDR szDisplayName,
                          WS_OVERLAPPEDWINDOW,
                          Wtx,Wty,Wwd,Wht,
                          NULL,NULL,
                          hInstance,NULL
    mov hWnd,eax

  ; ---------------------------
  ; macros for unchanging code
  ; ---------------------------
    DisplayMenu hWnd,600
    DisplayWindow hWnd,SW_SHOWNORMAL

    call MsgLoop
    ret

Main endp

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

RegisterWinClass proc lpWndProc:DWORD, lpClassName:DWORD,
                      Icon:DWORD, Cursor:DWORD, bColor:DWORD

    LOCAL wc:WNDCLASSEX

    mov wc.cbSize,         sizeof WNDCLASSEX
    mov wc.style,          CS_BYTEALIGNCLIENT or \
                           CS_BYTEALIGNWINDOW
    m2m wc.lpfnWndProc,    lpWndProc
    mov wc.cbClsExtra,     NULL
    mov wc.cbWndExtra,     NULL
    m2m wc.hInstance,      hInstance
    m2m wc.hbrBackground,  bColor
    mov wc.lpszMenuName,   NULL
    m2m wc.lpszClassName,  lpClassName
    m2m wc.hIcon,          Icon
    m2m wc.hCursor,        Cursor
    m2m wc.hIconSm,        Icon

    invoke RegisterClassEx, ADDR wc

    ret

RegisterWinClass endp

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

MsgLoop proc

  ; ------------------------------------------
  ; The following 4 equates are available for
  ; processing messages directly in the loop.
  ; m_hWnd - m_Msg - m_wParam - m_lParam
  ; ------------------------------------------

    LOCAL msg:MSG

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

    mov eax, msg.wParam
    ret

MsgLoop endp

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

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

    LOCAL var    :DWORD
    LOCAL caW    :DWORD
    LOCAL caH    :DWORD
    LOCAL Rct    :RECT
    LOCAL buffer1[128]:BYTE  ; these are two spare buffers
    LOCAL buffer2[128]:BYTE  ; for text manipulation etc..
    LOCAL szDropFileName[260]:BYTE

    .if uMsg == WM_COMMAND
    ;======== toolbar commands ========
        .if wParam == 50
            invoke MessageBox,hWin,SADD("WM_COMMAND ID 50"),
                              ADDR szDisplayName,MB_OK

        .elseif wParam == 51
            invoke MessageBox,hWin,SADD("WM_COMMAND ID 51"),
                              ADDR szDisplayName,MB_OK

        .elseif wParam == 52
            invoke MessageBox,hWin,SADD("WM_COMMAND ID 52"),
                              ADDR szDisplayName,MB_OK

        .endif

    ;======== menu commands ========

        .if wParam == 1001
          ; --------------------------------------
          ; szFileName is defined in Filedlgs.asm
          ; --------------------------------------
            mov szFileName[0],0     ; set 1st byte to zero
            invoke GetFileName,hWin,SADD("Open A File"),
                                    SADD("All files",0,"*.*",0)
            cmp szFileName[0],0     ; zero if cancel pressed in dlgbox
            je @F
          ; ---------------------------------
          ; perform your file open code here
          ; ---------------------------------
            invoke MessageBox,hWin,ADDR szFileName,ADDR szDisplayName,MB_OK
            @@:

        .elseif wParam == 1002
          ; --------------------------------------
          ; szFileName is defined in Filedlgs.asm
          ; --------------------------------------
            mov szFileName[0],0     ; set 1st byte to zero
            invoke SaveFileName,hWin,SADD("Save File As ..."),
                                     SADD("All files",0,"*.*",0,0)
            cmp szFileName[0],0     ; zero if cancel pressed in dlgbox
            je @F
          ; ---------------------------------
          ; perform your file save code here
          ; ---------------------------------
            invoke MessageBox,hWin,ADDR szFileName,ADDR szDisplayName,MB_OK
            @@:

        .endif

        .if wParam == 1010
            invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL

        .elseif wParam == 1900
            ShellAboutBox hWin,hIcon,\
                "About Prostart 3 Template#Windows Application",\
                "Prostart 3 Template",13,10,"Copyright © MASM32 2001"
        .endif
    ;====== end menu commands ======

    .elseif uMsg == WM_DROPFILES
        invoke DragQueryFile,wParam,0,ADDR szDropFileName,sizeof szDropFileName
      ; -------------------------------------------------------
      ; perform the action you want with "szDropFileName" here
      ; -------------------------------------------------------
        invoke MessageBox,hWin,ADDR szDropFileName,SADD("WM_DROPFILES"),MB_OK

    .elseif uMsg == WM_CREATE
        invoke Do_ToolBar,hWin
        invoke Do_Status,hWin

    .elseif uMsg == WM_SYSCOLORCHANGE
        invoke Do_ToolBar,hWin

    .elseif uMsg == WM_SIZE
        invoke SendMessage,hToolBar,TB_AUTOSIZE,0,0
        invoke MoveWindow,hStatus,0,0,0,0,TRUE

    .elseif uMsg == WM_PAINT
        invoke Paint_Proc,hWin
        return 0

    .elseif uMsg == WM_CLOSE

    .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

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

Paint_Proc proc hWin:DWORD

    LOCAL hDC      :DWORD
    LOCAL btn_hi   :DWORD
    LOCAL btn_lo   :DWORD
    LOCAL Rct      :RECT
    LOCAL Ps       :PAINTSTRUCT

    invoke BeginPaint,hWin,ADDR Ps
    mov hDC, eax

  ; ----------------------------------------

    invoke GetSysColor,COLOR_BTNHIGHLIGHT
    mov btn_hi, eax

    invoke GetSysColor,COLOR_BTNSHADOW
    mov btn_lo, eax

  ; ----------------------------------------

    invoke EndPaint,hWin,ADDR Ps

    ret

Paint_Proc endp

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

end start