News:

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

Main Menu

Window6 with new macros.

Started by hutch--, July 06, 2016, 11:24:13 PM

Previous topic - Next topic

hutch--

This version has new macros and some have been renamed and modified. The 2 register call macros have had an argument count guard added that tells you to use "invoke" if the arg count is over 4. Armed with a viable disassembly the stack frame technique is clear using ENTER and LEAVE mnemonics. To maintain spill space with the stack frame if no LOCAL variables are allocated, a dummy LOCAL variable is added using a MACRO ".stack" which can be omitted if any locals are allocated. Interestingly enough the extra LOCAL occurs at no mnemonic cost, it just changes the RBP address. The results are coming close to looking like normal code, the source follows.

NOTE that some of the macros have been modified and you need to use the "macros64.inc" file in the attached zip file.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    OPTION DOTNAME
    option casemap:none

    include \masm64\include\temphls.inc
    include \masm64\include\win64.inc
    include \masm64\include\kernel32.inc
    include \masm64\include\user32.inc
    include \masm64\include\msvcrt.inc

    includelib \masm64\lib\kernel32.lib
    includelib \masm64\lib\user32.lib
    includelib \masm64\lib\msvcrt.lib

    OPTION PROLOGUE:rbpFramePrologue
    OPTION EPILOGUE:rbpFrameEpilogue

    include macros64.inc

    .data
      ClassName db "ML64_Window_Class",0
      AppName   db "ML64 Example Window",0

    .data?
      hInstance dq ?
      hWnd      dq ?
      sWid      dq ?
      sHgt      dq ?
      hIcon     dq ?
      hCursor   dq ?
      hMnu      dq ?

  .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    .stack

  ; -----------------
  ; set global values
  ; -----------------
    mov hInstance, function(GetModuleHandle,0)
    mov hIcon,     function(LoadIcon,hInstance,10)
    mov hCursor,   function(LoadCursor,0,IDC_ARROW)
    mov sWid,      function(GetSystemMetrics,SM_CXSCREEN)
    mov sHgt,      function(GetSystemMetrics,SM_CYSCREEN)

    call main

    void(ExitProcess,0)

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    .stack

    LOCAL wc:WNDCLASSEX

    mov wc.cbSize,          SIZEOF WNDCLASSEX
    mov wc.style,           0
    mrm wc.lpfnWndProc,     OFFSET WndProc
    mov wc.cbClsExtra,      0
    mov wc.cbWndExtra,      0
    mrm wc.hInstance,       hInstance
    mrm wc.hIcon,           hIcon
    mrm wc.hCursor,         hCursor
    mov wc.hbrBackground,   COLOR_BTNSHADOW+1
    mrm wc.lpszMenuName,    0
    mrm wc.lpszClassName,   OFFSET ClassName
    mrm wc.hIconSm,         hIcon

    void(RegisterClassEx, lp(wc))

  ; ------------------------------------------
  ; the following data allocations do not need
  ; to be placed at the start of the procedure
  ; ------------------------------------------
    LOCAL64 lft
    LOCAL64 top
    LOCAL64 wid
    LOCAL64 hgt

  ; ------------------------------------
  ; centred half height and width window
  ; ------------------------------------
    mov rax, sWid
    mov r11, rax
    shr rax, 2
    mov lft, rax

    mov rax, r11
    shr rax, 1
    mov wid, rax

    mov rax, sHgt
    mov r11, rax
    shr rax, 2
    mov top, rax

    mov rax, r11
    shr rax, 1
    mov hgt, rax

    invoke CreateWindowEx,0,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW or WS_VISIBLE,\
           lft,top,wid,hgt,0,0,hInstance,0
    mov hWnd, rax

    mov hMnu, function(LoadMenu,hInstance,100)
    void(SetMenu,hWnd,hMnu)

    call msgloop

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

msgloop proc

    .stack

    LOCAL msg   :MSG

    LOCAL64 _rsi                ; allocate QWORD
    LOCAL64 _rdi                ; allocate QWORD

    mov _rsi, rsi               ; preserve rsi
    mov _rdi, rdi               ; preserve rdi

    xor rsi, rsi                ; zero rsi
    lea rdi, msg                ; load rdi with structure address
    jmp get_msg                 ; jump into loop

  lpstart:
    void(TranslateMessage,rdi)
    void(DispatchMessage,rdi)
  get_msg:
    test rax, function(GetMessage,rdi,rsi,rsi,rsi)
    jnz lpstart

    mov rdi, _rdi               ; restore rdi
    mov rsi, _rsi               ; restore rsi

    ret

msgloop endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

WndProc proc

    .stack

    r2m hWin, rcx
    r2m uMsg, rdx
    r2m wParam, r8
    r2m lParam, r9

    .if uMsg == WM_COMMAND
      .if wParam == 1000
        void(SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL)

      .elseif wParam == 10000
        void(MessageBox,hWin,txt("Example with icon, manifest and menu."),txt("About ML64 Example"),MB_OK)

      .endif

    .elseif uMsg == WM_CLOSE
      void(MessageBox,0,txt("Sending the WM_DESTROY message."),txt("WM_CLOSE here"),MB_OK)
      void(SendMessage,hWin,WM_DESTROY,0,0)

    .elseif uMsg == WM_DESTROY
      void(PostQuitMessage,NULL)

    .endif

    void(DefWindowProc,hWin,uMsg,wParam,lParam)

    ret

WndProc endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end

jcfuller

Steve,
  Curious on why you use cvtres.
The linker I am using 14.00.23506.0 adds the .res file just fine??

James

hutch--

James,

Probably sheer habit. From memory link needs cvtres if you add the RES file instead of converting it so there is no real gain.