32 Bit MASM
 
Warning Danger Zone
High speed software
 
Go this way and your software may be arrested for speeding !
Serious penalties exist for programs that run faster than VB, VC, BC, Delphi etc...
You will be penalised with more disk space, less loading time and the only bugs
you will be able to experience are the ones you must rewrite yourself. (grin)
 
masm32v4.zip
This is the NEXT STEP in rapid assembler code development, Version 4 has its own code generator to create basic front ends in less than a minute, it has it own extendable library with full source code for efficient modular code design, it includes WINDOWS.INC version 1.12 that Iczelion has just upgraded and MASM32.HLP has a new section for pentium optimisation from an anonymous author on the net as well as the reference for the procedures contained in MASM32.LIB.
 
This version has its own LIB.EXE, DUMPBIN.EXE and EDITBIN.EXE with source code so that the full capacity of LINK.EXE can be realised. Clive Turvey has given permission to include his latest version of DUMPPE.EXE with MASM32v4 which is set up to disassemble your EXE file directly from the editor. All you need to do is unzip DUMPPE.ZIP in the BIN directory.
 
This version is fully self contained and it includes a full set of include files and libraries. The ONLY way you can mess up the installation so it does not work is to put it in the wrong directory. It MUST be put in a directory called MASM32, directly off the root directory. Put it anywhere else and it will not work !!!!!
 
 Iczelion's Tutorials
Don't miss the best set of MASM tutorials on the Internet, Iczelion has slightly modified this brilliant set of 24 tutorials so that they will work with MASM32. This puts the best available in a convenient and easy to install manner for your reference. Just put this file in a directory straight off the MASM32 directory and run it and it will write a full set of directories, one for each tute, which are then ready to run.
 
 Examples1.Exe
This is an add on pack of 3 examples for MASM32v4, It has  new dialog box example that works properly in NT4 with the assistance of Viro, an MDI skeleton for extending into an MDI app and an example of how to do bitmap and icon buttons using either one or two images for each button. It also has a version of RESOURCE.H to be used with the Microsoft resource compiler which should be added to the INCLUDE directory of MASM32v4.
 
res_h.zip
The file RESOURCE.H is available for separate download.
 
examples2.exe
This is another addon pack for MASM32v4. It contains 3 examples, the first is a windows that draws its own border, the second is a self modifying code example and the third is an example of how to make a splash screen for a program using a seperate window and a time delay.
 
dberror.zip
This is a DLL & macro to assist in debugging windows API calls. It is easy and fast to use and it displays the error string defined in winerror.h in a dialog box. To find out how to use it, there is a readme.txt file that has the syntax for using it.
 
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