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?
:biggrin:
There is a simple solution to your problem, write your own. :tongue:
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.
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
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.
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.
64 bit MASM does not use prototypes at all, it simply ignores them.
I was just lazy to remove them for ml64;GetModuleHandleW PROTO :PTR
EXTERN GetModuleHandleW :PROC
...
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.
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:
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?
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
deleted
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
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
deleted
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]