News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Can someone explain this program to me ?

Started by sunshine33, April 15, 2018, 01:36:59 AM

Previous topic - Next topic

sunshine33

I was looking for example programs to learn about window based application with Assembly language

Then i found this

Since this is the first time i am trying to make a window based application , I don't even know where to start .


Can someone explain this program to me ?


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

.386
.model flat, stdcall
option casemap :none   

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

include windows.inc
include user32.inc
include kernel32.inc

includelib user32.lib
includelib kernel32.lib

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

szText macro name, text:vararg
local lbl
jmp lbl
name db text, 0
lbl:
endm

WinMain proto :dword, :dword, :dword, :dword
WndProc proto :dword, :dword, :dword, :dword

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

.data

hInstance dd ?
lpszCmdLine dd ?

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

.code

start:

invoke GetModuleHandle, NULL
mov hInstance, eax

invoke GetCommandLine
mov lpszCmdLine, eax

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


; ------------------------------------------------------------------------
; WinMain
;
; Main program execution entry point
; ------------------------------------------------------------------------
WinMain proc hInst :dword,
hPrevInst :dword,
szCmdLine :dword,
nShowCmd :dword

local wc :WNDCLASSEX
local msg :MSG
local hWnd :HWND

szText szClassName, "BasicWindow"
szText szWindowTitle, "First Window"

mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL

push hInst
pop wc.hInstance

mov wc.hbrBackground, COLOR_BTNFACE + 1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName

invoke LoadIcon, hInst, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax

invoke LoadCursor, hInst, IDC_ARROW
mov wc.hCursor, eax

invoke RegisterClassEx, addr wc

invoke CreateWindowEx, WS_EX_APPWINDOW, addr szClassName, addr szWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL

mov hWnd, eax

invoke ShowWindow, hWnd, nShowCmd
invoke UpdateWindow, hWnd

MessagePump:

invoke GetMessage, addr msg, NULL, 0, 0

cmp eax, 0
je MessagePumpEnd

invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg

jmp MessagePump

MessagePumpEnd:

mov eax, msg.wParam
ret

WinMain endp


; ------------------------------------------------------------------------
; WndProc
;
; Handles all of the messages sent to the window
; ------------------------------------------------------------------------
WndProc proc hWin :dword,
uMsg :dword,
wParam :dword,
lParam :dword

.if uMsg == WM_DESTROY

invoke PostQuitMessage, 0

xor eax, eax
ret

.endif

invoke DefWindowProc, hWin, uMsg, wParam, lParam

ret

WndProc endp

end start

jj2007

Google for RegisterClassEx CreateWindowEx GetMessage to see 154,000 pages explaining how it works.
Of course, somebody could sit down and write another tutorial especially for you. How much are you willing to pay?

sunshine33

Sorry about that , i have to google a lot of things in that program
Thanks for the keywords .

Vortex

Hi sunshine33,

You would like to study Iczelion's Tutorial 3, A Simple Window, that's what you are looking for :

http://win32assembly.programminghorizon.com/tut3.html

zedd151

#4
Quote from: Vortex on April 15, 2018, 03:10:25 AM
Hi sunshine33,

You would like to study Iczelion's Tutorial 3, A Simple Window, that's what you are looking for :

Excellent idea.

Full selection of iczelions tutorials found here. I suggest you start with "The Basics" tut 1, under the heading "Win 32 Assembly"

edit = removed broken link. iczelions tutorials no longer there.


Some of the material is rather dated, but still valid for learning x86 (32 bit) windows assembly programming.

sunshine33


hutch--

Sunshine,

Have a look in the example code of MASM32 "exampl01\generic\generic.asm" for a fully commented simple window. The style is a little old dating from 1999 but it addresses the low level basics of creating a window.

sunshine33

hutch--

This one , right ?

; #########################################################################
;
;             GENERIC.ASM is a roadmap around a standard 32 bit
;              windows application skeleton written in MASM32.
;
; #########################################################################

;           Assembler specific instructions for 32 bit ASM code

      .386                   ; minimum processor needed for 32 bit
      .model flat, stdcall   ; FLAT memory model & STDCALL calling
      option casemap :none   ; set code to case sensitive

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

      ; ---------------------------------------------
      ; main include file with equates and structures
      ; ---------------------------------------------
      include \masm32\include\windows.inc

      ; -------------------------------------------------------------
      ; In MASM32, each include file created by the L2INC.EXE utility
      ; has a matching library file. If you need functions from a
      ; specific library, you use BOTH the include file and library
      ; file for that library.
      ; -------------------------------------------------------------

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

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

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

; ------------------------------------------------------------------------
; MACROS are a method of expanding text at assembly time. This allows the
; programmer a tidy and convenient way of using COMMON blocks of code with
; the capacity to use DIFFERENT parameters in each block.
; ------------------------------------------------------------------------

      ; 1. szText
      ; A macro to insert TEXT into the code section for convenient and
      ; more intuitive coding of functions that use byte data as text.

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

      ; 2. m2m
      ; There is no mnemonic to copy from one memory location to another,
      ; this macro saves repeated coding of this process and is easier to
      ; read in complex code.

      m2m MACRO M1, M2
        push M2
        pop  M1
      ENDM

      ; 3. return
      ; Every procedure MUST have a "ret" to return the instruction
      ; pointer EIP back to the next instruction after the call that
      ; branched to it. This macro puts a return value in eax and
      ; makes the "ret" instruction on one line. It is mainly used
      ; for clear coding in complex conditionals in large branching
      ; code such as the WndProc procedure.

      return MACRO arg
        mov eax, arg
        ret
      ENDM

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

; ----------------------------------------------------------------------
; Prototypes are used in conjunction with the MASM "invoke" syntax for
; checking the number and size of parameters passed to a procedure. This
; improves the reliability of code that is written where errors in
; parameters are caught and displayed at assembly time.
; ----------------------------------------------------------------------

        WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
        WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
        TopXY PROTO   :DWORD,:DWORD

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

; ------------------------------------------------------------------------
; This is the INITIALISED data section meaning that data declared here has
; an initial value. You can also use an UNINIALISED section if you need
; data of that type [ .data? ]. Note that they are different and occur in
; different sections.
; ------------------------------------------------------------------------

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



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

; ------------------------------------------------------------------------
; This is the start of the code section where executable code begins. This
; section ending with the ExitProcess() API function call is the only
; GLOBAL section of code and it provides access to the WinMain function
; with the necessary parameters, the instance handle and the command line
; address.
; ------------------------------------------------------------------------

    .code

; -----------------------------------------------------------------------
; The label "start:" is the address of the start of the code section and
; it has a matching "end start" at the end of the file. All procedures in
; this module must be written between these two.
; -----------------------------------------------------------------------

start:
    invoke GetModuleHandle, NULL ; provides the instance handle
    mov hInstance, eax

    invoke GetCommandLine        ; provides the command line address
    mov CommandLine, eax

    invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
   
    invoke ExitProcess,eax       ; cleanup & return to operating system

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

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

        szText szClassName,"Generic_Class"

        ;==================================================
        ; 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      ; address of WndProc
        mov wc.cbClsExtra,     NULL
        mov wc.cbWndExtra,     NULL
        m2m wc.hInstance,      hInst               ; instance handle
        mov wc.hbrBackground,  COLOR_BTNFACE+1     ; system color
        mov wc.lpszMenuName,   NULL
        mov wc.lpszClassName,  offset szClassName  ; window class name
          invoke LoadIcon,hInst,500    ; icon ID   ; resource icon
        mov wc.hIcon,          eax
          invoke LoadCursor,NULL,IDC_ARROW         ; system cursor
        mov wc.hCursor,        eax
        mov wc.hIconSm,        0

        invoke RegisterClassEx, ADDR wc     ; register the window class

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

        mov Wwd, 500
        mov Wht, 350

        invoke GetSystemMetrics,SM_CXSCREEN ; get screen width in pixels
        invoke TopXY,Wwd,eax
        mov Wtx, eax

        invoke GetSystemMetrics,SM_CYSCREEN ; get screen height in pixels
        invoke TopXY,Wht,eax
        mov Wty, eax

        ; ==================================
        ; Create the main application window
        ; ==================================
        invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,
                              ADDR szClassName,
                              ADDR szDisplayName,
                              WS_OVERLAPPEDWINDOW,
                              Wtx,Wty,Wwd,Wht,
                              NULL,NULL,
                              hInst,NULL

        mov   hWnd,eax  ; copy return value into handle DWORD

        invoke LoadMenu,hInst,600                 ; load resource menu
        invoke SetMenu,hWnd,eax                   ; set it to main window

        invoke ShowWindow,hWnd,SW_SHOWNORMAL      ; display the window
        invoke UpdateWindow,hWnd                  ; update the display

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

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0         ; get each message
      cmp eax, 0                                  ; exit if GetMessage()
      je ExitLoop                                 ; returns zero
      invoke TranslateMessage, ADDR msg           ; translate it
      invoke DispatchMessage,  ADDR msg           ; send it to message proc
      jmp StartLoop
    ExitLoop:

      return msg.wParam

WinMain endp

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

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

; -------------------------------------------------------------------------
; Message are sent by the operating system to an application through the
; WndProc proc. Each message can have additional values associated with it
; in the two parameters, wParam & lParam. The range of additional data that
; can be passed to an application is determined by the message.
; -------------------------------------------------------------------------

    .if uMsg == WM_COMMAND
    ;----------------------------------------------------------------------
    ; The WM_COMMAND message is sent by menus, buttons and toolbar buttons.
    ; Processing the wParam parameter of it is the method of obtaining the
    ; control's ID number so that the code for each operation can be
    ; processed. NOTE that the ID number is in the LOWORD of the wParam
    ; passed with the WM_COMMAND message. There may be some instances where
    ; an application needs to seperate the high and low words of wParam.
    ; ---------------------------------------------------------------------
   
    ;======== 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_CREATE
    ; --------------------------------------------------------------------
    ; This message is sent to WndProc during the CreateWindowEx function
    ; call and is processed before it returns. This is used as a position
    ; to start other items such as controls. IMPORTANT, the handle for the
    ; CreateWindowEx call in the WinMain does not yet exist so the HANDLE
    ; passed to the WndProc [ hWin ] must be used here for any controls
    ; or child windows.
    ; --------------------------------------------------------------------

    .elseif uMsg == WM_CLOSE
    ; -------------------------------------------------------------------
    ; This is the place where various requirements are performed before
    ; the application exits to the operating system such as deleting
    ; resources and testing if files have been saved. You have the option
    ; of returning ZERO if you don't wish the application to close which
    ; exits the WndProc procedure without passing this message to the
    ; default window processing done by the operating system.
    ; -------------------------------------------------------------------
        szText TheText,"Please Confirm Exit"
        invoke MessageBox,hWin,ADDR TheText,ADDR szDisplayName,MB_YESNO
          .if eax == IDNO
            return 0
          .endif

    .elseif uMsg == WM_DESTROY
    ; ----------------------------------------------------------------
    ; This message MUST be processed to cleanly exit the application.
    ; Calling the PostQuitMessage() function makes the GetMessage()
    ; function in the WinMain() main loop return ZERO which exits the
    ; application correctly. If this message is not processed properly
    ; the window disappears but the code is left in memory.
    ; ----------------------------------------------------------------
        invoke PostQuitMessage,NULL
        return 0
    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam
    ; --------------------------------------------------------------------
    ; Default window processing is done by the operating system for any
    ; message that is not processed by the application in the WndProc
    ; procedure. If the application requires other than default processing
    ; it executes the code when the message is trapped and returns ZERO
    ; to exit the WndProc procedure before the default window processing
    ; occurs with the call to DefWindowProc().
    ; --------------------------------------------------------------------

    ret

WndProc endp

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

TopXY proc wDim:DWORD, sDim:DWORD

    ; ----------------------------------------------------
    ; This procedure calculates the top X & Y co-ordinates
    ; for the CreateWindowEx call in the WinMain procedure
    ; ----------------------------------------------------

    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


Thanks for the reply



hutch--

Yep, that's the one. Have a look through it as it explains what the different parts of it do. Once you get this base window code, adding more to it becomes a lot easier. The basic window construction code and architecture is operating system defined so you must get it right but once you have mastered that there is a massive range of options that you can do with a basic window.

Lonewolff

Always good to check the value of EAX after the RegisterClassEx and CreateWindowEx.

If the return value is zero, the call failed for the reason stored in EAX.

sunshine33

Thanks a lot for all the replies .
I wish i could code a little program that input numbers and displays the sum output inside that windows program somehow .  :biggrin:

felipe

Quote from: sunshine33 on April 15, 2018, 02:46:15 PM
Thanks a lot for all the replies .
I wish i could code a little program that input numbers and displays the sum output inside that windows program somehow .  :biggrin:

You also can start with simple console programs.

sunshine33


LordAdef

Hey Sunshine, that's the way to go and learn Assembly, the beast over all languages!!!!!  Congrats for your initiative!

These guys are top Masm programmers that will be glad to show you the right way. Everything I learned I learned from them, you couldn't be better. Forget you reverse eng. friends, this is a lot more fun and right.

Lonewolff

Amen to that, brother!  8)

I have only really been doing it for a week or two now, but I can vouch that these guys know their stuff and are a friendly crew to work with.