News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Most elegant lParam to POINT conversion

Started by jj2007, April 02, 2008, 02:45:29 PM

Previous topic - Next topic

jj2007

Some Windows messages (e.g. WM_MOUSEMOVE) give x, y coordinates in lParam. To be used, they must be converted by ScreenToClient, the latter expecting a POINT structure. I have been playing with some alternatives and wonder whether anybody knows better ones, in terms of size (speed can be neglected for this kind of messages).

xx proc .... lParam:DWORD
LOCAL pt:POINT

movzx eax, word ptr lParam ; 7
; mov pt.x, eax
mov eax, lParam ; 6
sar eax, 16 ; 3 ->7+6+3=16 bytes
; mov pt.y, eax

movzx eax, word ptr lParam ; 7
; mov pt.x, eax
movzx eax, word ptr lParam+2 ; 7 ->7+7=14 bytes
; mov pt.y, eax

mov eax, lParam ; 6
mov ecx, eax ; 2
sar ecx, 16 ; 3
; mov pt.y, ecx
cwde ; 1 ->6+2+3+1=12 bytes
; mov pt.x, eax

mov eax, lParam ; 6
push eax ; 1
sar eax, 16 ; 3
; mov pt.y, eax
pop eax ; 1
cwde ; 1 ->6+1+3+1+1=12 bytes
; mov pt.x, eax

xmetal

For a start, you could replace:


mov eax,dword ptr [lParam]
sar eax,16


with


movsx eax,word ptr [lParam+2]

asmfan

Sometimes movsx is wrong solution if word-size parameter must be treated as unsigned - movzx is right.
Russia is a weird place

u

But in this case movsx is right. (in the case of receiving mouse-coordinates - they will be negative when you drag).

Also, WM_MOUSE messages don't make you use ScreenToClient. The only proc to make you use ScreenToClient is GetCursorPos. So, you don't actually need to put x:y into a POINT.
Please use a smaller graphic in your signature.

jj2007

Quote from: Ultrano on April 03, 2008, 12:34:04 PM
But in this case movsx is right
Thanx, I had overlooked that.
Quote
Also, WM_MOUSE messages don't make you use ScreenToClient. The only proc to make you use ScreenToClient is GetCursorPos. So, you don't actually need to put x:y into a POINT.
I checked, and it's correct for WM_MOUSEMOVE, but not for WM_NCMOUSEMOVE (I use the latter...).
Thanx to all of you.

Ossa

Hi,

are you sure that you've got those calculations correct? Here's what I get when I disassemble that (with the totals after the lines) - the top two are the movements to the POINT structure for both local and globals:

:00401024 A314304000              mov dword ptr [00403014], eax ; 5 (Global)
:00401029 8945F8                  mov dword ptr [ebp-08], eax   ; 3 (Local)

:0040102C 0FB74510                movzx eax, word ptr [ebp+10]  ; 4 +
:00401030 8B4510                  mov eax, dword ptr [ebp+10]   ; 3 +
:00401033 C1F810                  sar eax, 10                   ; 3 = 10

:00401036 0FB74510                movzx eax, word ptr [ebp+10]  ; 4 +
:0040103A 0FB74512                movzx eax, word ptr [ebp+12]  ; 4 = 8

:0040103E 8B4510                  mov eax, dword ptr [ebp+10]   ; 3 +
:00401041 8BC8                    mov ecx, eax                  ; 2 +
:00401043 C1F910                  sar ecx, 10                   ; 3 +
:00401046 98                      cwde                          ; 1 = 9

:00401047 8B4510                  mov eax, dword ptr [ebp+10]   ; 3 +
:0040104A 50                      push eax                      ; 1 +
:0040104B C1F810                  sar eax, 10                   ; 3 +
:0040104E 58                      pop eax                       ; 1 +
:0040104F 98                      cwde                          ; 1 = 9


Your totals would be correct if lParam were a global, but I assume that it will be a parameter to the procedure in your code.

Ossa

[edit] No, I think that they'd still be wrong actually [/edit]
Website (very old): ossa.the-wot.co.uk

jj2007

I am afraid you are right, and I am wrong! I had tested "lParam" in a box, and assumed it would not make a difference if it was an argument or a local variable. In fact, it makes a big difference:


00404D87  |. 0FB785 B0FCFFF>MOVZX EAX,WORD PTR SS:[EBP-350] lParam as LOCAL
00404D8E  |. 0FB785 B2FCFFF>MOVZX EAX,WORD PTR SS:[EBP-34E] 7+7=14

00404D97  |. 0FBF45 0C      MOVSX EAX,WORD PTR SS:[EBP+C]        lParam as argument
00404D9B  |. 0FBF45 0E      MOVSX EAX,WORD PTR SS:[EBP+E]        4+4=8

I keep learning - thanks a lot!