|
Author |
Thread |
 |
|
yeohhs
Joined: 19 Jan 2004
Posts: 166
Location: N 5.43564° E 100.3091°
|
Iczelion's Tutorial #2b Win64 fasm format
Code: |
format PE64 GUI 5.0
entry start
include 'win64a.inc'
section '.text' code readable executable
start:
push rbp
mov rbp,rsp
sub rsp,30h
invoke GetModuleHandle,NULL
mov [x1],rax
invoke LoadIcon,NULL,IDI_APPLICATION
mov [x2],rax
invoke LoadCursor,NULL,IDC_ARROW
mov [x3],rax
mov rax,x1
mov [rsp+20h],eax
lea ecx,[buffer]
lea edx,[fmt]
mov r8,x3
mov r9,x2
call [wsprintf]
invoke MessageBox,NULL,buffer,MsgCaption,MB_OK
invoke ExitProcess,NULL
section '.data' data readable writeable
MsgCaption db "Iczelion's Tutorial #2b",0
fmt db "hCursor = %08Xh",0Ah,"hIcon = %08Xh",0Ah,"hInstance =%08Xh",0
n = $ - fmt + 12
buffer db n dup(?)
x1 dq ?
x2 dq ?
x3 dq ?
section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'
|
|
|
04 Jan 2018, 05:50 |
|
yeohhs
Joined: 19 Jan 2004
Posts: 166
Location: N 5.43564° E 100.3091°
|
Hi Mikl___,
So far, I've done only examples 2, 2a, and 2b. I'm beginning to learn Win64. And I don't know much about masm. If you can help, yes, that would be awesome!
Thanks!
_________________ “It’s not that we have a short time to live, but that we waste a lot of it.”
-Lucius Annaeus Seneca
|
09 Jan 2018, 09:16 |
|
Mikl___
Joined: 30 Dec 2014
Posts: 77
|
Hi, yeohhs!
then a few questions to you... writing a program in assembler is almost the same as collecting a yacht (expensive car) for a specific customer. Do you know what the program "Iczelion's Tutorial #2b" is for? To find the constants that return functions GetModuleHandle, LoadIcon, LoadCursor. These constants will be different for different versions of Windows, but for your computer until you change the version of Windows these constants will always be the same. But you do not need to call at the beginning of each program functions GetModuleHandle, LoadIcon, LoadCursor. Attach the image that the program "Iczelion's Tutorial #2b" shows on the screen
|
10 Jan 2018, 01:48 |
|
yeohhs
Joined: 19 Jan 2004
Posts: 166
Location: N 5.43564° E 100.3091°
|
 Yes, I see. That's very interesting.
_________________ “It’s not that we have a short time to live, but that we waste a lot of it.”
-Lucius Annaeus Seneca
|
10 Jan 2018, 08:55 |
|
Mikl___
Joined: 30 Dec 2014
Posts: 77
|
Hi, yeohhs!
I see the topic has ceased to be interesting for you, since I asked to attach a picture that the program "Iczelion's Tutorial #2b" shows on the screen, but you ignored my request
Saya dapati topik itu tidak lagi menarik minat anda, kerana saya meminta untuk melampirkan gambar yang ditunjukkan oleh program "Iczelion's Tutorial # 2b", tetapi anda tidak mengendahkan permintaan saya
|
13 Jan 2018, 15:43 |
|
|
Mikl___ wrote: |
Saya dapati topik itu tidak lagi menarik minat anda, kerana saya meminta untuk melampirkan gambar yang ditunjukkan oleh program "Iczelion's Tutorial # 2b", tetapi anda tidak mengendahkan permintaan saya
|
|
Some high-quality translations you have there.
I re-wrote yeoh's interpretation of Tutorial #2b, but this time I use a minimalist approach, FASM-style, 64-bit - flat and fastcall.
Code: |
format PE64 GUI 5.0
include 'win64a.inc'
sub rsp,8
fastcall [GetModuleHandle],NULL
mov rbx,rax
fastcall [LoadIcon],NULL,IDI_APPLICATION
mov rdi,rax
fastcall [LoadCursor],NULL,IDC_ARROW
mov rsi,rax
fastcall [wsprintf],buffer,fmt,rsi,rdi,rbx
fastcall [MessageBox],NULL,buffer,MsgCaption,MB_OK
fastcall [ExitProcess],NULL
MsgCaption db "Iczelion's Tutorial #2b",0
fmt db "hCursor = 0x%p",0Ah,"hIcon = 0x%p",0Ah,"hInstance = 0x%p",0
n = $ - fmt
buffer db n dup(?)
data import
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'
end data
|
|
Output
hcursor = 0x0000000000010003
hIcon = 0x000000000001002B
hInstance = 0x0000000000400000
Is the output acceptable? My proposition: Do you have any intention to fully translate all your work to FASM 64-bit instead of MASM64? As you can see here, FASM is extremely flexible and in many cases, better than MASM. Btw, keep up the good work. We could use a person of your technical knowledge for Win64 development on this board.
|
13 Jan 2018, 22:07 |
|
yeohhs
Joined: 19 Jan 2004
Posts: 166
Location: N 5.43564° E 100.3091°
|
Mikl___ wrote: |
Hi, yeohhs!
I see the topic has ceased to be interesting for you, since I asked to attach a picture that the program "Iczelion's Tutorial #2b" shows on the screen, but you ignored my request
|
|
Hi Mikl___, I must confess I lost interest after reading more MASM code. It feels like I'm reading Java. As for ignoring your request, I apologize. Due to my severely retarded social skills, I usually cannot respond appropriately.
Sincerely,
yeohhs
_________________ “It’s not that we have a short time to live, but that we waste a lot of it.”
-Lucius Annaeus Seneca
|
13 Jan 2018, 23:50 |
|
yeohhs
Joined: 19 Jan 2004
Posts: 166
Location: N 5.43564° E 100.3091°
|
fasmnewbie wrote: |
I re-wrote yeoh's interpretation of Tutorial #2b, but this time I use a minimalist approach, FASM-style, 64-bit - flat and fastcall.
|
|
Terima kasih! 
_________________ “It’s not that we have a short time to live, but that we waste a lot of it.”
-Lucius Annaeus Seneca
|
13 Jan 2018, 23:54 |
|
Mikl___
Joined: 30 Dec 2014
Posts: 77
|
Hi, yeohhs and fasmnewbie!
There is Iczelion's Tutorial #3 with fasmnewbie constant. I repeat these constants will be different for different versions of Windows
Code: |
format PE64 GUI 5.0
entry WinMain
include 'd:\fasm\include\win64a.inc'
section '.text' code readable writeable executable
;----------------------------------------------------------------------
proc WinMain
local msg:MSG
frame
xor ebx,ebx
mov esi,400000h ;hInstance
mov edi,ClassName
mov eax,1002Bh ;hIcon
push rax ;hIconSm
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOWTEXT;hbrBackground
push 10003h ;hCursor
push rax ;hIcon
push rsi ;hInstance
push rbx ;cbClsExtra & cbWndExtra
db 68h
dd WndProc ;lpfnWndProc
push sizeof.WNDCLASSEX;cbSize & style
invoke RegisterClassEx,esp ;addr WNDCLASSEX
push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
sub esp,20h
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
xor ecx,ecx
invoke CreateWindowEx,,edi,edi
lea edi,[msg]
@@: xor edx,edx
xor r8d,r8d
xor r9d,r9d
invoke GetMessage,edi
invoke DispatchMessage,edi
jmp @b
WndProc:cmp edx,WM_DESTROY
je wmDESTROY
jmp [NtdllDefWindowProc]
wmDESTROY:xor ecx,ecx
invoke RtlExitUserProcess
endf
endp
;-----------------------------------
ClassName db "Iczelion's Tutorial #3",0
;------------------------------------------------------------------------
section '.idata' import data readable writeable
library ntdll,'ntdll.DLL',\
user,'USER32.DLL'
import ntdll,\
RtlExitUserProcess,'RtlExitUserProcess',\
NtdllDefWindowProc,'NtdllDefWindowProc_A'
import user,\
RegisterClassEx,'RegisterClassExA',\
CreateWindowEx,'CreateWindowExA',\
GetMessage,'GetMessageA',\
DispatchMessage,'DispatchMessageA'
|
|
size of exe-file 1536 byte in fasm, in masm this size is smaller (992 bytes)
Description: |
|
Filesize: |
6.65 KB |
Viewed: |
1176 Time(s) |

|
|
|
14 Jan 2018, 00:24 |
|
|
@Mikl
I don't quite understand your point. My point was that it is easier to do Windows things in FASM if compared to MASM in many ways. What is it with MASM people and their obsessions of PROC and invoke? Does MASM64 support invoke anymore? AFAIK, MASM64 even dropped .if / .endif altogether along with INVOKE, PROTO and other high-level stuff. That should at least tell you something about the direction MASM64 is taking. And the good news is, those high-level stuff are still available in FASM 64-bit. I can see you're using them a lot, although I don't quite understand why would you use invoke on 64-bit WinAPI. I could be wrong since I am not good at WinAPI programming though.
But still why not use FASM instead? Why deny yourself a good opportunity of using an excellent assembler? 
|
14 Jan 2018, 01:20 |
|
Mikl___
Joined: 30 Dec 2014
Posts: 77
|
hi, fasmnewbie!
one dialect (masm) of the language of assembler is not at all worse than another dialect (fasm) and what is not provided by the compiler (ml64.exe) may be added using macros (invoke, .if, .while, .for etc.)
Last edited by Mikl___ on 14 Jan 2018, 04:23; edited 1 time in total
|
14 Jan 2018, 03:57 |
|
|
@Mikl
I am not even talking about third-party macros. I was referring to how MASM is bad to the core.
Here's your equivalent example for #2b in MASM 'dialect'
Code: |
OPTION DOTNAME
option casemap:none
include temphls.inc
include win64.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib
OPTION PROLOGUE:rbpFramePrologue
.code
WinMain proc
push rbp
mov rbp,rsp
sub rsp,30h
invoke GetModuleHandle,NULL
mov x1,rax
invoke LoadIcon,NULL,IDI_APPLICATION
mov x2,rax
invoke LoadCursor,NULL,IDC_ARROW
mov x3,rax
mov rax,x1
mov [rsp+20h],eax
lea ecx,buffer
lea edx,fmt
mov r8,x3
mov r9,x2
call wsprintf
invoke MessageBox,NULL,&buffer,&MsgCaption,MB_OK
invoke ExitProcess,NULL
WinMain endp
MsgCaption db "Iczelion's tutorial #2b",0
fmt db "hCursor = %08Xh",0Ah,"hIcon = %08Xh",0Ah,"hInstance =%08Xh",0
n = $ - fmt + 12
buffer db n dup(?)
x1 dq ?
x2 dq ?
x3 dq ?
end
|
|
Here's one problem:
push rbp
mov rbp,rsp
This is basically a standard call prologue, on top of a fastcall entry point! What's the purpose of a fastcall if everybody is going back to using a standard call prologue and epilogue? It beats the whole purpose and design philosophy of 64-bit fastcall. As if you're not enough, you even preceded it with
OPTION PROLOGUE:rbpFramePrologue
So altogether, plus the PROC hidden code, you're doing 3 stack setup redundancy.
Here's 2nd problem with ML64 core features;
OPTION DOTNAME
This is what exactly? This shows that ML/ML64 PROC cannot contain the behavior of its own local labels / variables? This is not a problem for a small code, but for a large codes, you'll find yourself using lots of @@ and "lblxx", with a very slim chance of a self-documenting source, not to mention ugly-looking source code.
I know you're good at WinAPI. I am not denying that. Only that your choice of assembler is incorrect, IMO. Many people will appreciate your efforts more if you switched to FASM 
|
14 Jan 2018, 04:22 |
|
Mikl___
Joined: 30 Dec 2014
Posts: 77
|
Quote: |
I was referring to how MASM is bad to the core
|
|
push rbp/mov rbp,rsp/sub rsp,XX == enter XX,0 I usually use this construction
OPTION PROLOGUE:rbpFramePrologue /OPTION DOTNAME I usually hide everything that is superfluous in included file win64a.inc
I know quite a few superficially several dialects NASM, TASM, FASM, MASM, GoAsm and each has its own advantages
Large programs are written in C/C++/С#, and assembler is used as inserts for critical sections of the program
|
14 Jan 2018, 04:41 |
|
|
Mikl___ wrote: |
Quote: |
I was referring to how MASM is bad to the core
|
|
push rbp/mov rbp,rsp/sub rsp,XX == enter XX,0 I usually use this construction
OPTION PROLOGUE:rbpFramePrologue /OPTION DOTNAME I usually hide everything that is superfluous in included file win64a.inc
I know quite a few superficially several dialects NASM, TASM, FASM, MASM, GoAsm and each has its own advantages
Large programs are written in C / C ++, and assembler is used as inserts for critical sections of the program
|
|
That's a standard call prologue. For 64-bit WinAPI which is ironically designed by MS, those are really not necessary. The purpose of FASTCALL is to avoid heavy stack frame setup in the first place in order to increase performance and less dependency on microcodes of stack programming.
SUB RSP,40
is the basic fastcall stack setup, which is again, ironically recommended by MS. SUB is not a stack instruction, a PUSH is. While they both move the stack, one involves only simple arithmethic (SUB), while the other one (PUSH) involves stack programming microcodes.
Seems like you been spending most of your time on the wrong forum board. You need to ditch your current membership of the other board, and spend your time exclusively with us ;D
|
14 Jan 2018, 04:59 |
|
|
I think most forum members here will agree with me that you should stick to FASM-only tutorials.
Too bad this board don't have "agree" or "like" button, or else you know what I am talking about.
Who's with me? ;D
|
14 Jan 2018, 05:12 |
|
Mikl___
Joined: 30 Dec 2014
Posts: 77
|
Quote: |
you should stick to FASM-ONLY tutorials
|
|
fasmnewbie,
you are too categorical in your judgments - only black or only white. And besides black and white there are a million shades of gray 
|
14 Jan 2018, 05:37 |
|
Mikl___
Joined: 30 Dec 2014
Posts: 77
|
There is Iczelion's Tutorial #4 with fasmnewbie constant.
Code: |
format PE64 GUI 5.0
entry WinMain
include 'd:\fasm\include\win64a.inc'
section '.text' code readable writeable executable
;----------------------------------------------------------------------
proc WinMain
local msg:MSG
frame
xor ebx,ebx
mov esi,400000h
mov edi,ClassName
mov eax,1002Bh ;hIcon
push rax ;hIconSm
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOW;hbrBackground
push 10003h ;hCursor
push rax ;hIcon
push rsi ;hInstance
push rbx ;cbClsExtra & cbWndExtra
db 68h
dd WndProc ;lpfnWndProc
mov rax,((CS_HREDRAW or CS_VREDRAW)shl 32)+sizeof.WNDCLASSEX
push rax;cbSize & style
invoke RegisterClassEx,esp ;addr WNDCLASSEX
push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
sub esp,20h
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
xor ecx,ecx
invoke CreateWindowEx,,edi,edi
lea edi,[msg]
@@: xor edx,edx
xor r8d,r8d
xor r9d,r9d
invoke GetMessage,edi
invoke DispatchMessage,edi
jmp @b
;----------------------------
WndProc:
hWnd equ rbp+10h
ps equ rbp-sizeof.PAINTSTRUCT
expRect equ ps-sizeof.RECT
enter sizeof.PAINTSTRUCT+sizeof.RECT+28h,0
mov [hWnd],rcx
cmp edx,WM_DESTROY
je wmDESTROY
cmp edx,WM_SIZE
je wmSIZE
cmp edx,WM_PAINT
je wmPAINT
leave
jmp [NtdllDefWindowProc]
wmDESTROY:xor ecx,ecx
invoke RtlExitUserProcess
wmSIZE: mov r8d,TRUE
xor edx,edx
invoke InvalidateRect;send WM_PAINT if size changes
jmp wmBYE
wmPAINT:lea edx,[ps]
invoke BeginPaint
lea edx,[expRect]
invoke GetClientRect,qword[hWnd]
mov edx,expTxt
lea r9d,[expRect]
or r8,-1
invoke DrawText,qword[ps+PAINTSTRUCT.hdc],,,,DT_SINGLELINE or DT_CENTER or DT_VCENTER
lea edx,[ps]
invoke EndPaint,qword[hWnd]
wmBYE: ret
endf
endp
;-----------------------------------
ClassName db "Iczelion's Tutorial #4 Painting with Text",0
expTxt db 'Win64 assembly with FASM is great and easy',0
;------------------------------------------------------------------------
section '.idata' import data readable writeable
library ntdll,'ntdll.DLL',\
user,'USER32.DLL'
import ntdll,\
RtlExitUserProcess,'RtlExitUserProcess',\
NtdllDefWindowProc,'NtdllDefWindowProc_A'
import user,\
RegisterClassEx,'RegisterClassExA',\
CreateWindowEx, 'CreateWindowExA',\
GetMessage, 'GetMessageA',\
BeginPaint, 'BeginPaint',\
GetClientRect, 'GetClientRect',\
DrawText, 'DrawTextA',\
EndPaint, 'EndPaint',\
InvalidateRect, 'InvalidateRect',\
DispatchMessage,'DispatchMessageA'
|
|
Description: |
|
Filesize: |
8.59 KB |
Viewed: |
1083 Time(s) |

|
|
|
14 Jan 2018, 06:20 |
|
Mikl___
Joined: 30 Dec 2014
Posts: 77
|
Quote: |
FASM is extremely flexible and in many cases, better than MASM
|
|
fasmnewbie,
if I use invoke or fastcall in FASM I get the procedure framed "sub rsp,20h" and "add rsp,20h" even where I do not need it, when several procedures are called sequentially for example
Code: |
invoke MessageBox,NULL,buffer,MsgCaption,MB_OK
invoke ExitProcess,NULL
|
|
code to be generated
Code: |
add rsp,20h
mov r9,0
lea r8,[MsgCaption]
lea rdx,[buffer]
mov rcx,0
call MessageBox
add rsp,20h
sub rsp,20h
mov rcx,0
call ExitProcess
add rsp,20h
|
|
for which addition with the contents of the register RSP, if the following command produces a subtraction of exactly the same value? for which a subtraction after call ExitProcess if process destroyed? for which first paramter of procedure is NULL or 0 or MB_OK code to be generated mov rcx,0 (48C7C100000000=7 bytes) and not xor ecx,ecx (31C9=2 bytes)?
To avoid unnecessary additions and subtractions from the register, I use the construction frame/endf but in begin of procedure I get
Code: |
push rbp
mov rbp,rsp
sub rsp,30h <-- local msg:MSG
sub rsp,20h <-- frame
|
|
why is not sub rsp,50h ? with MASM compiler this does not happen 
|
14 Jan 2018, 09:25 |
|
|
Quote: |
if I use invoke or fastcall in FASM I get the procedure framed "sub rsp,20h" and "add rsp,20h" even where I do not need it, when several procedures are called sequentially for example
|
|
Then don't use them. FASM has been enjoying the freedom to NOT use any high-level statements. MASM are not so lucky and flexible. Like your recent example of stacking up PROC + LOCAL and then FRAME...ENDF! Why would you even do that? Do you have a problem with aligning the stack and shadow space? Stacking up PROC with FRAME...ENDF? Where's your common sense? What are you trying to achieve with that?
Now there's your problem right there -- you're trying to convince people that you're writing FASM code but you're doing it with MASM high-level approach. That will be misleading to the unsuspecting audience. You're even confused yourself! ;D
|
14 Jan 2018, 11:01 |
|
|
|
Forum Rules:
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|
|
|
|
|
|
|
|