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
:bg
When you can improve on the 4 byte orred result, let me know. :P
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
No data section structure, just the call:
push 03FFh ; all classes
push 8 ; size
invoke InitCommonControlsEx,esp
add esp,8
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
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.
it is one dword - ICC_FLAGS
and - no MOV instruction
And an initialised DATA section entry.
.DATA
icc INITCOMMONCONTROLSEX <sizeof INITCOMMONCONTROLSEX,ICC_FLAGS>
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
Edgar's code is correct and does it in 16 bytes, data included.
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
: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.
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
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.
you don't wanna suck all the fun out of it :P
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
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]
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
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
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
mine doesn't :bg
and - if you do - do so manually so that you can pop them in the right order
Can you imagine how much pushin' & poppin' can be avoided that way... and it's faster, too :green2
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
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=
80000Congrats 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
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
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
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.
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)
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
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?
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.
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)
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.
: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.
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
:bg
> i knew we'd make a size-monger out of you
Deja Vu, been there, done that 20 years ago.
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
admit it, Hutch - you had fun doing it :bg
: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.
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
:bg
Does that mean you read Dave's posting ?
pop edx
pop edx
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
:P
You guys must be really bored.
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