The MASM Forum

General => The Campus => Topic started by: Mayuresh Kathe on September 12, 2019, 02:26:06 PM

Title: How to program GUI applications using MASM but without MASM-SDK?
Post by: Mayuresh Kathe on September 12, 2019, 02:26:06 PM
I saw the article at; https://software.intel.com/en-us/articles/introduction-to-x64-assembly

The first example is in x64 assembler, but it does not look like it uses the MASM-SDK, yet it seems to be using the Win32 libraries to generate a GUI.

How is that possible?

And, if that is possible, what is the added benefit of the MASM-SDK?
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: hutch-- on September 12, 2019, 02:44:10 PM
 :biggrin:

There is a simple solution to your problem, write your own.  :tongue:
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: jj2007 on September 12, 2019, 06:06:20 PM
Quote from: Mayuresh Kathe on September 12, 2019, 02:26:06 PM
I saw the article at; https://software.intel.com/en-us/articles/introduction-to-x64-assembly

QuoteFinally, read the forums at masm32.com for a lot of material.
:biggrin:

The advantage of the SDK is that you get all the needed header files and static libraries, and a bunch of useful macros. For example, print "hello world" in "naked" assembler without the SDK would be very cumbersome.
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: TimoVJL on September 12, 2019, 07:01:43 PM
If you mean ml64.exe, not so comfortable
option dotname
option epilogue:none
option prologue:none

ifdef __POASM__
ret equ retn ; poasm needs this with option prologue:none
endif

WM_DESTROY    equ 2
WM_CLOSE      equ 10h
WM_INITDIALOG equ 110h

GetModuleHandleW PROTO :PTR
ExitProcess PROTO :DWORD
INCLUDELIB kernel32.lib
DialogBoxIndirectParamW PROTO :PTR,:PTR,:PTR,:PTR,:QWORD
EndDialog PROTO :PTR,:PTR
PostQuitMessage PROTO :DWORD
MessageBoxW PROTO :PTR,:PTR,:PTR,:DWORD
INCLUDELIB user32.lib
;----------------------
DlgProc PROTO :PTR,:DWORD,:QWORD,:QWORD
WMInitdialog PROTO :QWORD
WMDestroy    PROTO
WMClose      PROTO :QWORD

.drectve segment byte info
db '/SUBSYSTEM:WINDOWS,5.2 '
.drectve ends

.data
DlgBox  dw  1   ; dlgVer
    dw  0FFFFh   ; signature
    dd  0       ; helpID
    dd  0       ; exStyle
    dd  10CA0800h   ; style
    dw  0       ; cDlgItems
    dw  0       ; x
    dw  0       ; y
    dw  200     ; cx
    dw  100     ; cy
    dw  0       ; empty menu
    dw  0       ; empty windowClass
    ;dw "Test",0    ; title POAsm
    dw  'T','e','s','t',0   ; title

;sMsg dw  "OK to close",0
sMsg dw  'O','K',' ','t','o',' ','c','l','o','s','e',0

.code
; parameters RCX, RDX, R8 and R9
WinMainCRTStartup PROC
    sub     rsp,38h ; 5 params (5+2)*QWORD
    xor     ecx,ecx
    call    GetModuleHandleW
    ;INVOKE  GetModuleHandleW,0
    mov     rcx,rax
    xor     eax,eax
    mov     qword ptr [rsp+20h],rax
    mov     r9,offset DlgProc
    xor     r8d,r8d
    mov     rdx,offset DlgBox
    call    DialogBoxIndirectParamW
    ;INVOKE  DialogBoxIndirectParamW,rcx,ADDR DlgBox,0,ADDR DlgProc,0
    ;INVOKE  ExitProcess, rax
    call    ExitProcess
    ret
WinMainCRTStartup ENDP
align 8
DlgProc PROC hWnd:PTR,uMsg:DWORD,wParam:QWORD,lParam:QWORD
;    mov QWORD PTR [rsp+30h],rcx ; hWnd
;    mov ,edx ; uMsg
;    mov QWORD PTR [rsp+40h],r8 ; wParam
;    mov QWORD PTR [rsp+48h],r9 ; lParam
    sub  rsp,28h
;    .if uMsg==WM_INITDIALOG
cmp  edx,WM_INITDIALOG
jnz  @F
call WMInitdialog
jmp  @ret
;        INVOKE  WMInitdialog, hWnd
;    .elseif uMsg==WM_CLOSE
@@: cmp  edx,WM_CLOSE
jnz  @F
call WMClose
jmp  @ret
;        INVOKE  WMClose, hWnd
;    .elseif uMsg==WM_DESTROY
@@: cmp  edx,WM_DESTROY
jnz  @F
call WMDestroy
jmp  @ret
;        INVOKE  WMDestroy 
;    .else
@@:
     xor eax,eax
;    .endif
@ret:
    add  rsp,28h
    ret
DlgProc ENDP
align 8
WMInitdialog PROC hWnd:QWORD
;    sub  rsp,28h
;   mov     qword ptr [rsp+30h],rcx ; hWnd
    mov     rax,1
;    add  rsp,28h
    ret
WMInitdialog ENDP
align 8
WMDestroy PROC
    xor  ecx,ecx
    call PostQuitMessage
;    INVOKE  PostQuitMessage,0
    mov     rax,1
    ret
WMDestroy ENDP
align 8
WMClose PROC hWnd:QWORD
    sub  rsp,28h
    mov  QWORD PTR [rsp+30h],rcx
    mov  r9,21h
    xor  r8d,r8d
    mov rdx,offset sMsg
    call MessageBoxW
;    INVOKE  MessageBoxW,hWnd,ADDR sMsg, 0, 21h
;    .if rax == 1
      cmp eax,1
      jne  @ret
        mov  rcx,QWORD PTR [rsp+30h] ;hWnd
        xor  edx,edx
        call EndDialog
;        INVOKE  EndDialog,rcx,0
;    .endif
@ret:
    add  rsp,28h
    ret
WMClose ENDP

END
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: aw27 on September 13, 2019, 01:02:05 AM
There is another way of looking at it: You better first understand how things work behind the scenes before using time-saving SDKs/Frameworks or any "shortcuts" invented for the sole purpose of making your life easier.

Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: Caché GB on September 13, 2019, 01:19:09 AM
Hi TimoVJL

Using Visual Studio, it seems that x64 does not require forward declaration of functions that are in the same file module.

This

;; DlgProc          proto :ptr, :dword, :qword, :qword
;; WMInitdialog  proto :qword
;; WMDestroy    proto
;; WMClose       proto :qword

still assembled and worked.

Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: hutch-- on September 13, 2019, 01:38:31 AM
64 bit MASM does not use prototypes at all, it simply ignores them.
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: TimoVJL on September 13, 2019, 02:29:29 AM
I was just lazy to remove them for ml64;GetModuleHandleW PROTO :PTR
EXTERN GetModuleHandleW :PROC
...
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: hutch-- on September 13, 2019, 02:34:48 AM
After years of writing prototypes for different languages, I enjoy the freedom of not having to do it any longer in 64 bit and fortunately the dialect of BASIC that I use from time to time is the same.
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: aw27 on September 13, 2019, 02:37:03 AM
The MASM programming manual from 1992 says:
"Declaring procedure prototypes is good programming practice, but is optional."
It has never been compulsory, except when using the x86 MASM Invoke and when the called function is after the caller.

I like to use prototypes even with ML64.  :thumbsup:

Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: daydreamer on September 13, 2019, 02:48:31 AM
Quote from: hutch-- on September 13, 2019, 01:38:31 AM
64 bit MASM does not use prototypes at all, it simply ignores them.
added an extra assembly pass I guess in ml64,but isnt prototyping still a habit of C/C++ programmers?
now I got curious:
if I delete all nececary prototypes in a .cpp file and compile it for 32bit(x86 mode compiling) and get errors because of that
and I switch it to compile 64bit(x64) mode compiling,would those errors disappear?
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: daydreamer on September 13, 2019, 03:06:15 AM
Quote from: AW on September 13, 2019, 02:37:03 AM
The MASM programming manual from 1992 says:
"Declaring procedure prototypes is good programming practice, but is optional."
It has never been compulsory, except when using the x86 MASM Invoke and when the called function is after the caller.

I like to use prototypes even with ML64.  :thumbsup:
I have mostly used jmp to main or winmain first and PROC's above main loop,placed them in the right order instead
but switched to use several source files,where its easy to just simple move includes up or down when that problem the above problem occur
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: nidud on September 13, 2019, 03:28:58 AM
deleted
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: hutch-- on September 13, 2019, 01:54:40 PM
You are right with local procedures, they must have changed something in ML64 as this did not work a few versions ago. None the less YOU can ignore prototypes and it still works correctly.

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

    include \masm32\include64\masm64rt.inc

    msgbox PROTO :QWORD,:QWORD,:QWORD,:QWORD

    .code

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

entry_point proc

    rcall msgbox,0,"MASM64 Pure and Simple"," How D Awl",MB_OK

    .exit

entry_point endp

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

msgbox proc a1:QWORD,a2:QWORD,a3:QWORD,a4:QWORD

    rcall MessageBox,a1,a2,a3,a4

    ret

msgbox endp

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

    end
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: TimoVJL on September 13, 2019, 05:26:57 PM
A cleaned version for ml64.exe, no traces for invoke usage.
Tested with several ml64 versions from 8.00; ml64.exe TestGUI64.asm
option dotname
option epilogue:none
option prologue:none

WM_DESTROY    equ 2
WM_CLOSE      equ 10h
WM_INITDIALOG equ 110h

EXTERN GetModuleHandleW :PROC
EXTERN ExitProcess :PROC
INCLUDELIB kernel32.lib
EXTERN DialogBoxIndirectParamW :PROC
EXTERN EndDialog :PROC
EXTERN PostQuitMessage :PROC
EXTERN MessageBoxW :PROC
INCLUDELIB user32.lib

.drectve segment byte info
db '/SUBSYSTEM:WINDOWS,5.2 ',0
.drectve ends

.data
;align 4
DlgBox  dw  1   ; dlgVer
    dw  0FFFFh   ; signature
    dd  0       ; helpID
    dd  0       ; exStyle
    dd  10CA0800h   ; style
    dw  0       ; cDlgItems
    dw  0       ; x
    dw  0       ; y
    dw  200     ; cx
    dw  100     ; cy
    dw  0       ; empty menu
    dw  0       ; empty windowClass
    dw  'T','e','s','t',0   ; title

sMsg dw  'O','K',' ','t','o',' ','c','l','o','s','e',0

.code
; parameters RCX, RDX, R8 and R9
WinMainCRTStartup PROC
    sub     rsp,38h ; 5 params (5+2)*QWORD
    xor     ecx,ecx
    call    GetModuleHandleW
    mov     rcx,rax
    xor     eax,eax
    mov     qword ptr [rsp+20h],rax
    mov     r9,offset DlgProc
    xor     r8d,r8d
    mov     rdx,offset DlgBox
    call    DialogBoxIndirectParamW
    mov     rcx,rax
    call    ExitProcess
    ret
WinMainCRTStartup ENDP
align 8
DlgProc PROC ;hWnd:PTR,uMsg:DWORD,wParam:QWORD,lParam:QWORD
    sub  rsp,28h
cmp  edx,WM_INITDIALOG
jnz  @F
call WMInitdialog
jmp  @ret
@@: cmp  edx,WM_CLOSE
jnz  @F
call WMClose
jmp  @ret
@@: cmp  edx,WM_DESTROY
jnz  @F
call WMDestroy
jmp  @ret
@@:
     xor eax,eax
@ret:
    add  rsp,28h
    ret
DlgProc ENDP
align 8
WMInitdialog PROC ;hWnd:QWORD
;    sub  rsp,28h
;   mov     qword ptr [rsp+30h],rcx ; hWnd
    mov     rax,1
;    add  rsp,28h
    ret
WMInitdialog ENDP
align 8
WMDestroy PROC
    xor  ecx,ecx
    call PostQuitMessage
    mov     rax,1
    ret
WMDestroy ENDP
align 8
WMClose PROC ;hWnd:QWORD
    sub  rsp,28h
    mov  QWORD PTR [rsp+30h],rcx
    mov  r9,21h
    xor  r8d,r8d
    mov rdx,offset sMsg
    call MessageBoxW
      cmp eax,1
      jne  @ret
        mov  rcx,QWORD PTR [rsp+30h] ;hWnd
        xor  edx,edx
        call EndDialog
@ret:
    add  rsp,28h
    ret
WMClose ENDP

END
So no includes or macros, but still needs import libraries kernel32.lib user32.lib.

EDIT: Visual Studio masm template, just notes.
create a new Empty Project, File -> New -> Project
Project -> Build Customizations... add masm targets
Export Template
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: nidud on September 13, 2019, 09:11:24 PM
deleted
Title: Re: How to program GUI applications using MASM but without MASM-SDK?
Post by: hutch-- on September 13, 2019, 09:30:09 PM
You can make local prototypes as they are matched against the "proc" line of a procedure but it does not work with external API function calls. I bothered to make a macro that manages the prototype from the TYPEDEF and got it to work (IE:not show an error) but the prototype done this way still does not work in terms of argument count. While this example below runs correctly, you can add a series of extra arguments which show up in the dis-assembly and no error is reported. It still runs but the extra arguments are ignored.

The only method I have got to work is with the commented out macro as the pre-processor checks the argument count.

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

    include \masm32\include64\masm64rt.inc

  ; ************************************************

    PPROTO MACRO func_addr:REQ,arglist:VARARG
      LOCAL var
      .const
      var TYPEDEF PROTO arglist
      EXITM <equ <(TYPE QWORD PTR var) PTR func_addr>>
    ENDM

    msgbox PPROTO(__imp_MessageBoxA,:QWORD,:QWORD,:QWORD,:QWORD)

;     msgbox MACRO a1,a2,a3,a4
;       rcall __imp_MessageBoxA,a1,a2,a3,a4
;     ENDM

    .code

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

entry_point proc

    rcall msgbox,0,"Text Message","Title",MB_OK

    .exit

entry_point endp

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

    end

; .text:0000000140001008 48C7C100000000             mov rcx, 0x0
; .text:000000014000100f 488B1557100000             mov rdx, qword ptr [0x14000206d]
; .text:0000000140001016 4C8B0569100000             mov r8, qword ptr [0x140002086]
; .text:000000014000101d 49C7C100000000             mov r9, 0x0
; .text:0000000140001024 FF15D2100000               call qword ptr [MessageBoxA]