flat assembler
Message board for the users of flat assembler.
Index
> Tutorials and Examples > WindowProc via ScanMap |
Author |
|
TightCoderEx 28 Jun 2013, 00:46
This procedure is a generic handler for windows procedures, sub or super classed. This also allows dynamic changing of application characteristics, just by eliminating an entry point or having it execute a different procedure. This can be accomplished as long as the map resides in writable memory.
The map is quite simple. Code: MMap dd 0 ; Default windows procedure dd ( MMapEnd - $ ) / 6 ; Number of pointers in map ; These will always be 6 byte sets. dw WM_DESTROY dd Quit_App MMapEnd: The entry point should be aligned. Code: align 32 ; -------------------------------------------------------------------------------------------- MainWndProc: mov esi, MMap jmp ScanMap Then the procedure is called. Code: align 8 ; -------------------------------------------------------------------------------------------- ; hWnd Msg wParam & lParam are @ esp + 4 at this point ScanMap: lodsd ; Default proc is window is sub or super class mov ebx, eax lodsd ; # of handlers in map mov ecx, eax ; Scan map for any matching messages @@: lodsw ; Message # cmp [esp + 8], eax ; Is it message currently being processed lodsd ; Get pointer to handler jz .Handle loopnz @B ; Continue till list is exhaused ; Application is not handling this message so execute default processing @@: or ebx, ebx ; EBX = Pointer to windows default proc jnz .Subed jmp [DefWindowProc] ; Not sub or super classed ; Push the extra parameter required by API .Subed: pop eax ; Grab return address push ebx ; lpPrevWndFunc push eax ; Replace return address jmp [CallWindowProc] ; Execute windows default procedure .Handle: lea esi, [esp + 12] ; Points to wParam & lParam call eax ; Execute handler jc @B ; CF = 1 if default processing still required ; Kernel looks after cleaning up stack xor eax, eax ret 16 The only change I'm contemplating in the future is to put all the handlers in numeric order and then bail as soon the one in the map is greater than what we're looking for. For those that follow my posts, you may have noticed I've reverted to 32 bit again. There is no inherent advantage to using 64 bit at this point and I find that convoluted calling mythology just a little to hard to swallow.
|
|||||||||||
28 Jun 2013, 00:46 |
|
TightCoderEx 28 Jun 2013, 02:28
Quote:
Quote:
I think my choice for speed consideration will be to change the message number in map to a 32 bit value instead. Code: MMap dd 0 ; Default windows procedure dd ( MMapEnd - $ ) / 8 ; Number of pointers in map ; These will always be 6 byte sets. dd WM_DESTROY dd Quit_App MMapEnd: Code: @@: lodsd ; Message # cmp [esp + 8], eax ; Is it message currently being processed lodsd ; Get pointer to handler jz .Handle loopnz @B ; Continue till list is exhaused |
|||
28 Jun 2013, 02:28 |
|
uart777 28 Jun 2013, 02:42
Quote: I think my choice for speed consideration will be to change the message number in map to a 32 bit value instead. |
|||
28 Jun 2013, 02:42 |
|
typedef 28 Jun 2013, 03:43
uart777 wrote: "Look, I saved a $1 on toilet paper!" LOL! LOLWTF... You might as well use your hands... |
|||
28 Jun 2013, 03:43 |
|
revolution 28 Jun 2013, 03:55
I have always liked the idea of using tables instead of a long string of 'cmp' instruction. But I have never been satisfied with having to update my code in two places to insert an extra function. I.e. the need to insert the new function and to also update the table to point to it. So perhaps a macro could make it more convenient?
Code: macro AddFunction ID,func,[params] { common proc func,params ;code to add ID to the function table } AddFunction WM_DESTROY,Quit_App,exit_code ;... endp AddFunction WM_PAINT,Paint_App,hwnd,... ;... endp ;code to place the function table PlaceTable |
|||
28 Jun 2013, 03:55 |
|
TightCoderEx 28 Jun 2013, 05:40
Quote:
|
|||
28 Jun 2013, 05:40 |
|
bitRAKE 28 Jun 2013, 08:19
The code path of multiple CMP/JZ pairs can be almost 100% predicted in both memory load and execution path. Whereas, your suggested method uses more memory and cannot be predicted (both the branch and the data load).
|
|||
28 Jun 2013, 08:19 |
|
AsmGuru62 28 Jun 2013, 10:31
I am not sure this smart contraption will make the procedure faster than simple CMP/JE.
Also, can someone find a message which will be coming quick enough to make this optimization worthy? I can think of something repainting every mouse move to be most dense. And mouse moves are not coming every pixel -- maybe every few pixels, so not fast enough IMO. To deal with such case, I would put WM_PAINT and WM_MOUSEMOVE at the top of CMP/JE chain. |
|||
28 Jun 2013, 10:31 |
|
revolution 28 Jun 2013, 10:39
Optimising a WindowProc is not the right way to think about this IMO. I can't think of a case where the main bottleneck would ever be the WindowProc.
|
|||
28 Jun 2013, 10:39 |
|
TightCoderEx 28 Jun 2013, 12:13
bitRAKE, AsmGuru62 and revolution each of your most recent posts are of the same theme and I concur as I most often purport cycles and byte savings as the theory behind what I do. In this case, those consideration took a back seat to aesthetics if you will from a human perspective, but most importantly the ability to dynamically modify application characteristics on the fly. Self modifying code and overlays were a thing I used quite often and maybe that's just something I haven't got my head wrapped around yet with the kind of resources of today.
In 64 bit, it seems the pain is not worth the gain especially considering there is no gain to be had in the first place. |
|||
28 Jun 2013, 12:13 |
|
bitRAKE 28 Jun 2013, 23:17
It does demonstrate a translative quality between code and data. Many programmers don't understand that code is data (data is code) in this sense, and it's inherent to many types of optimization. Jump tables, compiled sprites, and state machines; are all examples of this quality, too.
_________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
28 Jun 2013, 23:17 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.