flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
LocoDelAssembly 31 Mar 2010, 14:36
Code: winProc_default: pop [buf] ;where to jump back (somewhere in dispatch) invoke defWindowProc ;no need of param's, as the are in the stack jmp [buf] ;and now jump back Replace with: Code: winProc_default: jmp [defWindowProc] ;no need of param's, as the are in the stack Code: winProc_creation: ;demonstration piece of code pop eax ;wold this be allowed? I keep the esp up to date: add esp, 16 ;remove unneeded param's jmp eax ;normal jump back (like ret of proc) Yes you are allowed to destroy EAX, ECX and EDX, but why not just "retn 16" in replacement of all that? I don't know if you can get rid of DispatchMessage, maybe in some situations it works but perhaps you could receive messages that are not destined to your main window? It could also process messages itself, for instance WM_TIMER it is documented as that it will call the TimerProc instead of the WindowProc when a pointer is available in the message structure. To be safe, I would use GetMessage (or PeekMessage in case you don't want to get blocked) plus DispatchMessage, I think that the speed gains cannot be noticed after several millions messages (and the human would need to time a very long run to notice the difference that could still be non conclusive due to the "noise" introduced by background processes). |
|||
![]() |
|
LocoDelAssembly 31 Mar 2010, 15:16
OK, decided to also test what I've said:
Code: TIMES equ 50'000'000 format PE GUI 4.0 entry start include 'win32a.inc' section '.data' data readable writeable hWnd dd ? msg MSG buf dd ? wc WNDCLASSEX 48, 0, winProc, 0, 0, ?, ?, ?, 0, 0, class, ? class db 'syrasia-engine', 0 title db 'Syrasia Editor V 0.1', 0 match iter, TIMES { fmt db 'Time with DispatchMessage: %u ms.', 13, 10, 'Time without DispatchMessage: %u ms.', 13, 10, 13, 10, `iter # ' messages used', 0 } szBuf rb 256 WS_STYLE equ WS_VISIBLE or WS_SYSMENU or WS_OVERLAPPED section '.code' code readable executable start: invoke getModuleHandle, 0 mov [wc.hInstance], eax invoke loadIcon, 0, IDI_APPLICATION mov [wc.hIcon], eax mov [wc.hIconSm], eax invoke loadCursor, 0, IDC_ARROW mov [wc.hCursor], eax invoke registerClassEx, wc invoke createWindowEx,0,class,title,WS_STYLE,8000h,8000h,512,512,NULL,NULL,[wc.hInstance],NULL mov [hWnd],eax invoke GetTickCount mov esi, eax mov ebx, TIMES mov [msg.message], WM_CREATE align 16 @@: invoke dispatchMessage, msg dec ebx jnz @b invoke GetTickCount mov edi, eax mov ebx, TIMES align 16 .winProc: ;using custom procedure mov eax, [msg.message] ;read out the message, letting all unaffected cmp eax, WM_DESTROY ;je .winProc_closeWindow cmp eax, WM_CREATE je .winProc_creation cmp eax, 0 je exit .winProc_d'efault: jmp [defWindowProc] ;no need of param's, as the are in the stack .winProc_closeWindow: jmp exit ;direct jump to exit .winProc_creation: ;demonstration piece of code ; ret 16 dec ebx jnz .winProc invoke GetTickCount mov edx, eax sub edx, edi mov ecx, edi sub ecx, esi cinvoke wsprintf, szBuf, fmt, ecx, edx invoke MessageBox, 0, szBuf, title, 0 invoke exitProcess, 0 message_loop: invoke getMessage, msg, 0, 0, 0 cmp eax, 1 jb exit cmp [msg.message], WM_KEYDOWN je exit cmp [msg.message], WM_PAINT ;je paint cmp [msg.message], WM_CLOSE je exit invoke dispatchMessage, msg jmp message_loop exit: invoke exitProcess, 0 winProc: ;using custom procedure mov eax, [esp+8] ;read out the message, letting all unaffected cmp eax, WM_DESTROY ;je winProc_closeWindow cmp eax, WM_CREATE je winProc_creation cmp eax, 0 je exit winProc_default: jmp [defWindowProc] ;no need of param's, as the are in the stack winProc_closeWindow: jmp exit ;direct jump to exit winProc_creation: ;demonstration piece of code ret 16 section '.idata' import data readable library kernel, 'KERNEL32.DLL',\ user, 'USER32.DLL' import kernel,\ getModuleHandle, 'GetModuleHandleA',\ GetTickCount, 'GetTickCount',\ exitProcess, 'ExitProcess' import user,\ registerClassEx, 'RegisterClassExA',\ createWindowEx, 'CreateWindowExA',\ defWindowProc, 'DefWindowProcA',\ getMessage, 'GetMessageA',\ dispatchMessage, 'DispatchMessageA',\ loadCursor, 'LoadCursorA',\ loadIcon, 'LoadIconA',\ postQuitMessage, 'PostQuitMessage',\ MessageBox, 'MessageBoxA',\ wsprintf, 'wsprintfA' Quote: --------------------------- But changing TIMES to something that would be a very pessimistic number of messages per second: Quote: --------------------------- (The second time was less than GetTickCount's resolution, that is why it counts 0 ms. but surely it took at least ~1 ms.) Don't optimize where it it not worth it (unless you have the time and more importantly, the certainty that your optimization is guaranteed to work everywhere). |
|||
![]() |
|
Syrasia 31 Mar 2010, 18:35
thx for the info (especially jmp [defWindowProc]
![]() maybe it is only little speed, but i like it to have it. About dispatchMessage: as I found out, some mesages as WM_KEYDOWN are written directly into the message-structure, som others are not (example: after getMessage you can't use the message to know about WM_CREATE, you will need to dispatch the message to have it). It also was something I wanted to understand, so you helped me out. ![]() |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.