The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: dedndave on March 19, 2011, 06:40:55 AM

Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 06:40:55 AM
i fail to see how my method has anything to do with dos
nor have you really showed how there has anything wrong with it

but - i am interested in finding out what works and what doesn't on these non-English machines
so, i will simply call you Hutch "Bloat" Hutchesson and leave you be   :lol

i say we let Jochen run it through the mill
he has enough experience writing test code - and a machine that exhibits the problem
it would be nice if he would detail the behaviour and inform us
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 19, 2011, 06:42:48 AM
 :bg

When you can improve on the 4 byte orred result, let me know.  :P
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 06:44:17 AM
ICC_FLAGS = ICC_WIN95_CLASSES
;comment out the ones you do not want
ICC_FLAGS = ICC_FLAGS or ICC_ANIMATE_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_BAR_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_COOL_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_DATE_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_HOTKEY_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_INTERNET_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_LISTVIEW_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_PAGESCROLLER_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_PROGRESS_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_TAB_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_TREEVIEW_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_UPDOWN_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_USEREX_CLASSES

       .DATA
icc INITCOMMONCONTROLSEX <sizeof INITCOMMONCONTROLSEX,ICC_FLAGS>

       .CODE
       INVOKE  InitCommonControlsEx,offset icc
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: donkey on March 19, 2011, 06:58:26 AM
No data section structure, just the call:

push 03FFh ; all classes
push 8 ; size
invoke InitCommonControlsEx,esp
add esp,8
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: jj2007 on March 19, 2011, 07:05:50 AM
Quote from: donkey on March 19, 2011, 06:58:26 AM
No data section structure, just the call:

push 03FFh ; all classes
push 8 ; size
invoke InitCommonControlsEx,esp
add esp,8


Thanks, Edgar - that should make both Dave and Steve B. Hutchesson happy :bg

Quote from: dedndave on March 19, 2011, 06:40:55 AM
i say we let Jochen run it through the mill
he has enough experience writing test code - and a machine that exhibits the problem

There is no problem, actually. The dialog won't work if you never mention InitCommonControls. But 1. the Ex is not needed, and 2. even this works:
.code
pop dword ptr InitCommonControls  ; pop=trying hard to provoke a GPF in AVIRA's heuristic scanner
start:
mov hInstance, FUNC(GetModuleHandle,NULL)
call main
invoke ExitProcess, eax
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 19, 2011, 07:15:21 AM
Dave,

1 DWORD.


    mov icce.dwICC, 00000001h or 00000002h or 00000004h or 00000008h or 00000010h or 00000020h or \
                    00000040h or 00000080h or 000000FFh or 00000100h or 00000200h or 00000400h or \
                    00000800h or 00001000h or 00002000h or 00004000h or 00008000h


What I do need apart from the trivialities of byte cpounting is a few folks with other language Windows versions to test the test piece to see if it displays the standard controls when the style flags are set to zero.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 07:20:03 AM
it is one dword - ICC_FLAGS
and - no MOV instruction
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 19, 2011, 07:26:49 AM
And an initialised DATA section entry.


       .DATA
icc INITCOMMONCONTROLSEX <sizeof INITCOMMONCONTROLSEX,ICC_FLAGS>
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 07:35:43 AM
that is 8 bytes for data, 10 bytes for code
18 bytes in the PE file

push sizeof INITCOMMONCONTROLSEX
pop icc.dwSize
push AnyValue
pop icc.dwICC
invoke InitCommonControlsEx,offset icc

that looks like about 26 bytes in code - and 8 bytes in uninitialized data
might be 24 bytes in code if AnyValue is small enough
and - that does not count all those OR instructions

you must have worked for microsoft in a previous life   :P
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: jj2007 on March 19, 2011, 07:44:06 AM
Edgar's code is correct and does it in 16 bytes, data included.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 07:46:36 AM
show me - i can't find Edgar's code - well - not the 16 byte version

i count 8 bytes for data and 10 bytes for the invoke

oh - this code
push 03FFh ; all classes
push 8 ; size
invoke InitCommonControlsEx,esp
add esp,8


so - this would be the same size, then...
ICC_FLAGS = ICC_WIN95_CLASSES
;comment out the ones you do not want
ICC_FLAGS = ICC_FLAGS or ICC_ANIMATE_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_BAR_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_COOL_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_DATE_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_HOTKEY_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_INTERNET_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_LISTVIEW_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_PAGESCROLLER_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_PROGRESS_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_TAB_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_TREEVIEW_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_UPDOWN_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_USEREX_CLASSES

push ICC_FLAGS
push sizeof INITCOMMONCONTROLSEX
invoke InitCommonControlsEx,esp
add esp,8


i am gonna use it   :U
i was counting bytes wrong when i looked at doing it that way
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 19, 2011, 07:56:42 AM
 :bg

Microsoft orthodoxy gives you this.


    mov icce.dwSize, SIZEOF INITCOMMONCONTROLSEX        ; set the structure size
    mov icce.dwICC, 00000001h or 00000002h or 00000004h or 00000008h or 00000010h or 00000020h or \
                    00000040h or 00000080h or 000000FFh or 00000100h or 00000200h or 00000400h or \
                    00000800h or 00001000h or 00002000h or 00004000h or 00008000h
    invoke InitCommonControlsEx,ADDR icce               ; initialise the common control library

0040101D C745E008000000         mov     dword ptr [ebp-20h],8
00401024 C745E4FFFF0000         mov     dword ptr [ebp-1Ch],0FFFFh
0040102B 8D45E0                 lea     eax,[ebp-20h]
0040102E 50                     push    eax
0040102F E898030000             call    jmp_InitCommonControlsEx

23 bytes.


You guys are worried about what you can save off 23 bytes, come on, pull the other leg.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 07:57:53 AM
Quotecome on, pull the other leg

:lol

really - it's a matter of developing good practice
if you get into the habit of writing small code, it will add up in the overall size of a program
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 19, 2011, 08:07:19 AM
Close range byte counting usually ends up with crappy code for no gain. Instruction count matters in some speed critical algos, the rest is accuracy and reliability.

I have been hearing guys trying to relive the old DOS days of byte counting in an 8088 where it may have mattered, on anything after an i486 is just does not matter but often the old style code is hard to read, harder to modify and maintain and slower for some trivial size gain. The humour is it tends to get lost in the procedure alignment and section alignment with the assembled binary.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 08:09:50 AM
you don't wanna suck all the fun out of it   :P
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 07:28:32 PM
15 bytes   :bg
ICC_FLAGS = ICC_WIN95_CLASSES
;comment out the ones you do not want
ICC_FLAGS = ICC_FLAGS or ICC_ANIMATE_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_BAR_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_COOL_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_DATE_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_HOTKEY_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_INTERNET_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_LISTVIEW_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_PAGESCROLLER_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_PROGRESS_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_TAB_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_TREEVIEW_CLASSES
ICC_FLAGS = ICC_FLAGS or ICC_UPDOWN_CLASS
ICC_FLAGS = ICC_FLAGS or ICC_USEREX_CLASSES

push ICC_FLAGS
push sizeof INITCOMMONCONTROLSEX
invoke InitCommonControlsEx,esp
pop ecx
pop edx
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: jj2007 on March 19, 2011, 07:48:02 PM
Quote from: dedndave on March 19, 2011, 08:09:50 AM
you don't wanna suck all the fun out of it   :P

15  :U
:cheekygreen:

One more piece of awfully optimised non-maintainable code:
Quote   push edx
   mov edx, esp   ; shorter because it avoids a global variable
   invoke
WriteFile, hWrite, edi, eax, edx, 0   ; invoke WriteFile, hWrite, bufStart, bufCt, ptrBytesRead, 0
   pop eax   ; contains bytes written
[/color]
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 08:05:14 PM
that's an old one Jochen - lol
you should see my os info program   :P

here is a sample   :bg  just to make Hutch's day
the comments have been intentionally removed  - lol
        pushad
        jmp short mLoop1

mLoop0: INVOKE  TranslateMessage,esp
        INVOKE  DispatchMessage,esp

mLoop1: mov     eax,esp
        INVOKE  GetMessage,eax,edi,edi,edi
        neg     eax
        shr     eax,1
        jnz     mLoop0

        pop     eax
        JMP     ExitProcess
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 09:19:17 PM
how 'bout this one....
instead of
        INVOKE  DefWindowProc,hWnd,uMsg,wParam,lParam
        ret

do this...
        leave
        JMP     DefWindowProc

(hint: the RETurn address and 4 parms are already on the stack)

can't seem to get a rise out of Hutch, today
must be "Blondes on Bikes Day" in Oz   :bg
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: jj2007 on March 19, 2011, 09:37:47 PM
Quote from: dedndave on March 19, 2011, 09:19:17 PM
        leave
        JMP     DefWindowProc


Cute, but don't forget the proc uses esi edi ebx :bg
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 09:39:09 PM
mine doesn't   :bg
and - if you do - do so manually so that you can pop them in the right order
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: jj2007 on March 19, 2011, 09:40:28 PM
Can you imagine how much pushin' & poppin' can be avoided that way... and it's faster, too :green2
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 19, 2011, 09:49:02 PM
not sure about speed - but count the bytes
another thing i managed to do was to use the same code for horz and vert scroll
also, rather than creating the main menu in resource, i have it in 64 bytes of code and 330 bytes of data
those are probably the biggest space savers
oh - i use a loop to create all my child windows   :P
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: jj2007 on March 19, 2011, 09:58:43 PM
Quote from: dedndave on March 19, 2011, 09:49:02 PM
not sure about speed

Hey, three or four cycles less is an eternity, especially if you jump to DefWindowProc :green

By the way, I just sent some photos to a friend. Thunderbird needs about one minute per 1.2MB, say: 20000 bytes per second. And I really mean needs because the CPU is at 80%, and TB is the culprit...

CPU has 1.6GHz = 1600000000 cycles/second
Sending speed = 20000 bytes/second

Cycles per byte sent: 1600000000/20000=80000

Congrats to the C++ World :U

Quote from: dedndave on March 19, 2011, 09:49:02 PM
oh - i use a loop to create all my child windows   :P

Haha, the old stosd trick :green2
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: donkey on March 19, 2011, 11:39:12 PM
15 btyes also:

00401000 >/$ 66:68 FF03     PUSH 3FF
00401004  |. 6A 08          PUSH 8
00401006  |. 54             PUSH ESP                                 ; /pInitEx
00401007  |. E8 80510000    CALL <JMP.&COMCTL32.InitCommonControlsEx>; \InitCommonControlsEx
0040100C  |. 83C4 06        ADD ESP,6


pushw 03FFh ; all classes
push 8 ; size
invoke InitCommonControlsEx,esp
add esp,6
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 20, 2011, 12:44:01 AM
add esp,6 ????   :bg
not sure that PUSHW is legal

replace that with POP ECX, POP DX and you have it in 14, Edgar   :P
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: donkey on March 20, 2011, 01:19:49 AM
Hey Dave,

pop DX requires a 66h override in 32 bit mode:

66:5A

So its still 15 bytes, but yes, half stack operations should be perfectly legal. I haven't looked at the state of the stack after the pushw, it could be that the high word has garbage in it.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: Antariy on March 20, 2011, 02:28:04 AM
Quote from: donkey on March 20, 2011, 01:19:49 AM
Hey Dave,

pop DX requires a 66h override in 32 bit mode:

66:5A

So its still 15 bytes, but yes, half stack operations should be perfectly legal. I haven't looked at the state of the stack after the pushw, it could be that the high word has garbage in it.

No, calling API with unaligned stack is dangerous. If *planned* exception will occur, then SEH will not work - program will have terminated abnormally.
Also it will cause unexcepted behaviours of the API (even if it will not crash).

Try this code:

.nolist
include \masm32\include\masm32rt.inc
.686
.xmm
.code
start:
add esp,-2
invoke MessageBox,0,CTXT("Hello"),CTXT("Hi"),MB_ICONINFORMATION
pop ax
invoke ExitProcess,eax
end start


This is the image what I get on XP SP2 (crazy behaviour of MessageBox with unaligned stack):


(http://www.masm32.com/board/index.php?action=dlattach;topic=16285.0;id=8973)
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 20, 2011, 02:31:56 AM
yah - that also violates the definition of the INITCOMMONCONTROLSEX structure
it wants to see 2 dwords - although - the upper 16 bits may be ignored
they may use them in the future, i suppose
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: Antariy on March 20, 2011, 02:35:18 AM
Quote from: dedndave on March 20, 2011, 02:31:56 AM
yah - that also violates the definition of the INITCOMMONCONTROLSEX structure
it wants to see 2 dwords - although - the upper 16 bits may be ignored
they may use them in the future, i suppose

Try to compile app in my previous post. What do you get?
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: donkey on March 20, 2011, 02:38:13 AM
Hi Jochen,

Yup, no error from InitCommonControlsEx on the half stack operation and it appears to work OK but you're right the PUSHW would probably cause some trouble and the return address would be misaligned. At 15 bytes I guess Dave's POP REG version is the smallest possible then.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 20, 2011, 02:47:48 AM
when i first run it, it looks like the image on the left
after i click the Start menu, it looks like the image on the right   :lol

(http://www.masm32.com/board/index.php?action=dlattach;topic=16285.0;id=8974)
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: Antariy on March 20, 2011, 02:50:05 AM
Quote from: dedndave on March 20, 2011, 02:47:48 AM
when i first run it, it looks like the image on the left
after i click the Start menu, it looks like the image on the right   :lol

(http://www.masm32.com/board/index.php?action=dlattach;topic=16285.0;id=8974)

Cool :lol

Take notice, that there is no theming at all, as well as co-ordinates are crazy.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 20, 2011, 02:50:35 AM
 :bg


0040101D 6A00                   push    0
0040101F 6A08                   push    8
00401021 54                     push    esp
00401022 E89B030000             call    jmp_InitCommonControlsEx
00401027 83C408                 add     esp,8


13 bytes. Return value is TRUE.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 20, 2011, 02:52:31 AM
very nice Hutch
i knew we'd make a size-monger out of you   :bg

replace the add with pop ecx/pop edx and you have it in 12
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 20, 2011, 02:56:32 AM
 :bg

> i knew we'd make a size-monger out of you

Deja Vu, been there, done that 20 years ago.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: Antariy on March 20, 2011, 02:58:13 AM

extern _imp__InitCommonControlsEx@4:DWORD

push 3FFh
push 8
push esp
call _imp__InitCommonControlsEx@4
pop edx
pop edx


This will take 16 bytes. BUT, usual PROTOs make call to jump thunk, so, all other versions here actually take for 6 bytes longer space than "seeing" :wink
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 20, 2011, 03:02:54 AM
admit it, Hutch - you had fun doing it   :bg
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 20, 2011, 03:34:53 AM
 :bg

Nah, I don't like crap code. here is why the standard Microsoft code is more efficient, a lower instruction count.


0040101D 6A00                   push    0
0040101F 6A08                   push    8
00401021 54                     push    esp
00401022 E899030000             call    jmp_InitCommonControlsEx
00401027 58                     pop     eax
00401028 58                     pop     eax

0040101D C745E008000000         mov     dword ptr [ebp-20h],8
00401024 C745E400000000         mov     dword ptr [ebp-1Ch],0
0040102B 8D45E0                 lea     eax,[ebp-20h]
0040102E 50                     push    eax
0040102F E898030000             call    jmp_InitCommonControlsEx


When it comes to performance, instruction scheduling is the action, not code byte counts.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: jj2007 on March 20, 2011, 09:00:43 AM
Quote from: hutch-- on March 20, 2011, 02:50:35 AM
:bg


0040101D 6A00                   push    0
0040101F 6A08                   push    8
00401021 54                     push    esp
00401022 E89B030000             call    jmp_InitCommonControlsEx
00401027 83C408                 add     esp,8


13 bytes. Return value is TRUE.

Hutch,
You are bloating your code and unnecessarily restricting the user's choice :naughty:

include \masm32\include\masm32rt.inc

.code
start: push ICC_BAR_CLASSES or ICC_HOTKEY_CLASS or ICC_LISTVIEW_CLASSES or ICC_PROGRESS_CLASS or ICC_TAB_CLASSES or ICC_TREEVIEW_CLASSES or ICC_UPDOWN_CLASS
push 8
push esp
call InitCommonControlsEx
pop edx
pop edx
icc_end:
mov ecx, icc_end
sub ecx, start
MsgBox 0, str$(ecx), chr$("That is short:"), MB_OK
exit
end start


12 bytes - test yourself :bg
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 20, 2011, 10:08:15 AM
 :bg

Does that mean you read Dave's posting ?


pop edx
pop edx
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: dedndave on March 20, 2011, 10:28:59 AM
no - i used POP ECX/POP EDX   :bg

it does mean he has carefully selected a group of flags that will yield a small push, though
i suppose we can do without ICC_ANIMATE_CLASS (80h)
but, ICC_COOL_CLASSES (400h) is a likely choice that will force a larger push
#define ICC_LISTVIEW_CLASSES   0x00000001
#define ICC_TREEVIEW_CLASSES   0x00000002
#define ICC_BAR_CLASSES        0x00000004
#define ICC_TAB_CLASSES        0x00000008
#define ICC_UPDOWN_CLASS       0x00000010
#define ICC_PROGRESS_CLASS     0x00000020
#define ICC_HOTKEY_CLASS       0x00000040
#define ICC_ANIMATE_CLASS      0x00000080
#define ICC_WIN95_CLASSES      0x000000FF
#define ICC_DATE_CLASSES       0x00000100
#define ICC_USEREX_CLASSES     0x00000200
#define ICC_COOL_CLASSES       0x00000400

#if (_WIN32_IE >= 0x0400)
#define ICC_INTERNET_CLASSES   0x00000800
#define ICC_PAGESCROLLER_CLASS 0x00001000
#define ICC_NATIVEFNTCTL_CLASS 0x00002000
#endif

#if (_WIN32_WINNT >= 0x501)
#define ICC_STANDARD_CLASSES   0x00004000
#define ICC_LINK_CLASS         0x00008000
#endif

this does not match the windows.inc file, btw
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: hutch-- on March 20, 2011, 12:53:03 PM
 :P

You guys must be really bored.
Title: Re: InitCommonControlsEx() test on memory dialog.
Post by: jj2007 on March 20, 2011, 04:26:40 PM
Quote from: hutch-- on March 20, 2011, 12:53:03 PM
:P

You guys must be really bored.

What can be more amusing than teasing an Aussie on a lazy Sunday afternoon?
:thumbu