I have a problem in the following code. In the WndProc I call a procedure written by myself, but my program crashes every time, I change my windows size. If I put the PUSHA and POPA instructions to save the registers in my procedure (MoveDlgControls), the program works fine.

Interesting is that the program works well under XP without PUSHA/POPA, I have problem only with Win9x, NT and 2k.

I would like to ask, which registers should I save in my procedures? Why is this problem. If I debug my program, the exception occurs, after exiting the WndProc, so the error does not appear directly in the MoveDlg Control procedure or in WndProc.
  ; ## Resize Message

.elseif eax==WM_WINDOWPOSCHANGED
mov ebx,lParam
.if !([ebx+WINDOWPOS.flags]&SWP_NOSIZE)
invoke GetDlgItem,hDlg,IDC_MYIMCLIENT_SBR1
invoke MoveWindow,eax,0,0,0,0,FALSE
invoke GetDlgItem,hDlg,IDC_MYIMCLIENT_TBR1
invoke MoveWindow,eax,0,0,0,0,FALSE
[B]invoke MoveDlgControls ; Problematic procedure[/B]
invoke InvalidateRect,hDlg,NULL,TRUE
invoke UpdateWindow,hDlg
.endif

...

MoveDlgControls proc
LOCAL Rect:RECT
LOCAL DeltaW,DeltaH:DWORD

[B]pusha ; If I don't put this I obtain exception[/B]
invoke GetWindowRect,hDlg,addr Rect
mov eax,Rect.right
sub eax,Rect.left
sub eax,550
mov DeltaW,eax
mov eax,Rect.bottom
sub eax,Rect.top
sub eax,450
mov DeltaH,eax
; Moving the Message List View
invoke GetDlgItem,hDlg,IDC_MYIMCLIENT_LSV1
mov edx,DeltaW
add edx,417
push edx
mov ebx,DeltaH
add ebx,233
invoke MoveWindow,eax,9,33,edx,ebx,FALSE
; Moving the Group Control
invoke GetDlgItem,hDlg,IDC_MYIMCLIENT_GRP1
pop edx
mov ebx,DeltaH
add ebx,274
invoke MoveWindow,eax,9,ebx,edx,89,FALSE
[B]popa ; If I don't put this I obtain exception[/B]
ret

MoveDlgControls endp

Dr. Watson on NT generates the following log:
Application exception occurred:

App: (pid=64)
When: 6/22/2004 @ 12:12:14.184
Exception number: c0000005 (access violation)

*----> System Information <----*
Computer Name: KICSI
User Name: Administrator
Number of Processors: 1
Processor Type: x86 Family 5 Model 8 Stepping 0
Windows Version: 4.0
Current Build: 1381
Service Pack: 6
Current Type: Uniprocessor Free

*----> Task List <----*
0 Idle.exe
2 System.exe
20 SMSS.exe
26 CSRSS.exe
34 WINLOGON.exe
40 SERVICES.exe
43 LSASS.exe
69 SPOOLSS.exe
42 rpcss.exe
46 DKService.exe
95 Navapsvc.exe
102 PSTORES.exe
79 nddeagnt.exe
120 mstask.exe
124 EXPLORER.exe
107 systray.exe
135 LOADWC.exe
143 Navapw32.exe
145 internat.exe
64 MyIMClient.exe
72 DRWTSN32.exe
0 _Total.exe

(00400000 - 00400000)
(77f60000 - 77fbf000) dll\ntdll.dbg
(77e70000 - 77ec2000) dll\user32.dbg
(77f00000 - 77f5f000) dll\kernel32.dbg
(78140000 - 78175000) dll\gdi32.dbg
(77dc0000 - 77dff000) dll\advapi32.dbg
(77e10000 - 77e67000) dll\rpcrt4.dbg
(71710000 - 71794000) dll\comctl32.dbg
(77d80000 - 77db2000) dll\comdlg32.dbg
(77c40000 - 77d7b000) dll\shell32.dbg
(776b0000 - 776c4000) dll\ws2_32.dbg
(78000000 - 78044000)
(776a0000 - 776a7000) dll\ws2help.dbg
(76aa0000 - 76aa6000) dll\indicdll.dbg
(71300000 - 71306000) dll\msidle.dbg

State Dump for Thread Id 0x37

eax=0048bbe0 ebx=00000144 ecx=000f00d8 edx=fdd17720 esi=00000047 edi=0048bc94
eip=77e87010 esp=0012fc78 ebp=0012fca8 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000202


function: CharPrevW
77e86ff1 ff7514 push dword ptr [ebp+0x14] ss:0102e6ae=????????
77e86ff4 ff7510 push dword ptr [ebp+0x10] ss:0102e6ae=????????
77e86ff7 56 push esi
77e86ff8 ff75f8 push dword ptr [ebp-0x8] ss:0102e6ae=????????
77e86ffb ffd1 call ecx
77e86ffd 8b4df8 mov ecx,[ebp-0x8] ss:0102e6ae=????????
77e87000 8945fc mov [ebp-0x4],eax ss:0102e6ae=????????
77e87003 e8feb3feff call IsWindow+0x84 (77e72406)
77e87008 85c0 test eax,eax
77e8700a 0f843b070000 je CharPrevW+0xbf2 (77e8774b)
[COLOR=red][B][I]; This address is not in my code[/I][/B][/COLOR]
FAULT ->77e87010 f6437bc0 test byte ptr [ebx+0x7b],0xc0 ds:00efeb4a=??
77e87014 0f8531070000 jne CharPrevW+0xbf2 (77e8774b)
77e8701a 83fe2f cmp esi,0x2f
77e8701d 774a ja CharPrevW+0x510 (77e87069)
77e8701f 83fe2e cmp esi,0x2e
77e87022 0f8323070000 jnb CharPrevW+0xbf2 (77e8774b)
77e87028 83fe19 cmp esi,0x19
77e8702b 746a jz CharPrevW+0x53e (77e87097)
77e8702d 837dfc00 cmp dword ptr [ebp-0x4],0x0 ss:0102e6ae=????????
77e87031 0f85df050000 jne CharPrevW+0xabd (77e87616)
77e87037 83fe10 cmp esi,0x10
77e8703a 7766 ja CharPrevW+0x549 (77e870a2)

*----> Stack Back Trace <----*

FramePtr ReturnAd Param#1 Param#2 Param#3 Param#4 Function Name
0012fca8 77e734af 0048bbe0 00000047 00000000 0012fcf0 user32!CharPrevW
0012fcd4 77f76563 0012fce4 00000030 0048bbe0 00000047 user32!MBToWCSEx
0012fd54 77e87064 0048bbe0 00000112 0000f002 01b60310 ntdll!KiUserCallbackDispatcher
0012fda0 77e71dbb 0048bbe0 00000112 0000f002 01b60310 user32!CharPrevW
0012fdcc 77f76563 0012fddc 00000018 0048bbe0 00000112 user32!DefWindowProcA
0012fe34 77e87064 0048bbe0 000000a1 0000000b 01b60310 ntdll!KiUserCallbackDispatcher
0012fe80 77e8b7cc 0048bbe0 000000a1 0000000b 01b60310 user32!CharPrevW
0012fe9c 77e71416 000f00d8 000000a1 0000000b 01b60310 user32!DefDlgProcA
0012ff08 01b60310 000babb1 00000310 000001b6 00000001 user32!TranslateMessageEx

*----> Raw Stack Dump <----*
0012fc78 04 00 00 00 00 00 00 00 - e0 bb 48 00 d8 00 0f 00 ..........H.....
0012fc88 47 00 01 01 04 00 00 00 - 04 00 00 00 00 00 00 00 G...............
0012fc98 e0 bb 48 00 c4 fc 12 00 - d8 00 0f 00 01 00 00 00 ..H.............
0012fca8 d4 fc 12 00 af 34 e7 77 - e0 bb 48 00 47 00 00 00 .....4.w..H.G...
0012fcb8 00 00 00 00 f0 fc 12 00 - 01 00 00 00 12 01 00 00 ................
0012fcc8 e0 bb 48 00 00 00 00 00 - 00 00 00 00 54 fd 12 00 ..H.........T...
0012fcd8 63 65 f7 77 e4 fc 12 00 - 30 00 00 00 e0 bb 48 00 ce.w....0.....H.
0012fce8 47 00 00 00 00 00 00 00 - d8 00 0f 00 00 00 00 00 G...............
0012fcf8 ed 00 00 00 94 00 00 00 - 27 02 00 00 bb 01 00 00 ........'.......
0012fd08 16 12 00 00 01 00 00 00 - 3c 6f e8 77 0e 16 e7 77 ........<o.w...w
0012fd18 d8 00 0f 00 12 01 00 00 - 02 f0 00 00 10 03 b6 01 ................
0012fd28 00 00 00 00 9e 02 00 00 - 01 00 00 00 94 bc 48 00 ..............H.
0012fd38 12 01 00 00 e0 bb 48 00 - 44 f2 ea 77 28 0c eb 77 ......H.D..w(..w
0012fd48 70 fd 12 00 60 25 e7 77 - a8 c8 48 00 a0 fd 12 00 p...`%.w..H.....
0012fd58 64 70 e8 77 e0 bb 48 00 - 12 01 00 00 02 f0 00 00 dp.w..H.........
0012fd68 10 03 b6 01 01 00 00 00 - 02 00 00 00 00 00 00 00 ................
0012fd78 e0 bb 48 00 be 00 00 00 - 0f 03 00 00 4b 02 00 00 ..H.........K...
0012fd88 f1 00 00 00 be 00 00 00 - 71 64 e7 77 60 9a 47 00 ........qd.w`.G.
0012fd98 d8 00 0f 00 00 00 00 00 - cc fd 12 00 bb 1d e7 77 ...............w
0012fda8 e0 bb 48 00 12 01 00 00 - 02 f0 00 00 10 03 b6 01 ..H.............

Sorry for this long post. Thanks in advance for your help
Posted on 2004-06-22 04:18:20 by bszente
You should always preserve EBX, ESI and EDI. The fault you have is because EBX was modified.

FAULT ->77e87010 f6437bc0         test    byte ptr [[b][color=red]ebx[/color][/b]+0x7b],0xc0 
Posted on 2004-06-22 04:26:25 by donkey
Thanks donkey wery much.
I corrected the problem with your help. But it seems that WinXP is not so sensitive for such register modifications.
Posted on 2004-06-22 04:38:08 by bszente
I have one more question: I change the value of the EBX register in the WndProc:

.elseif eax==WM_GETMINMAXINFO

mov [COLOR=red][B]ebx[/B][/COLOR],lParam
mov [ebx+MINMAXINFO.ptMinTrackSize.x],IDD_MYIMSERVER_WMIN
mov [ebx+MINMAXINFO.ptMinTrackSize.y],IDD_MYIMSERVER_HMIN
; ## Resize Message
.elseif eax==WM_WINDOWPOSCHANGED
mov [COLOR=red][B]ebx[/B][/COLOR],lParam
.if !([ebx+WINDOWPOS.flags]&SWP_NOSIZE)
invoke GetDlgItem,hDlg,IDC_MYIMSERVER_SB


The code works perfectly. Is it allowed to change the content of the EBX and EDI regsiters in the WndProc ?
Posted on 2004-06-22 04:56:28 by bszente
Then the code will not work on win2k.
Posted on 2004-06-22 07:18:58 by roticv

Thanks donkey wery much.
I corrected the problem with your help. But it seems that WinXP is not so sensitive for such register modifications.


Yes, it is. You just were not using instructions that were effected but believe me it will eventually jump up and bite you. You are *required* to preserve EBX,EDI and ESI in all callback functions, ie WndProc, DlgProc etc... Also every API function will preserve them for you so within a callback you can use them and when you make a call to Windows they will be unchanged. You can do this by simply using the USES directive...

DlgProc proc uses ebx, edi esi, hwnd, uMsg, wParam, lParam

DlgProc endp
Posted on 2004-06-22 07:46:55 by donkey
Ok, I understand now, and I will take care of these registers from now one.

Thank for your replies.
Posted on 2004-06-22 08:01:31 by bszente
Also, remember than ANY external function you call is allowed to trash eax, ecx, edx. You must also preserve EBP and if you set the direction flag (STD) you must clear it (CLD). Of course "preserve" means "push/pop the register if you use it", not "blindly save it" (disclaimer to avoid... people.)

This whole preservation thing is mostly visible in callbacks (wndproc, dlgproc, the EnumWindowsProc used with EnumWindows, et cetera) - but it also applies to your own routines. Of course you're free to use whatever calling convention you want in your own routines - but if you forget that a piece of your code uses a non-standard calling convention, you risk crashes later on.
Posted on 2004-06-22 11:24:46 by f0dder
Hehe. For my own routines, every registers need to be preserve except eax. Sometimes eax needs to be preserved too and return using cf. The reason being that some parts of my code make use of all 8 registers. If one register is not preserved, the code will crash.

Back to my point which is f0dder is right about the fact that you are free to use whatever calling convention you see fit, just that you need to remember that so long the function is a callback for windows, you need to preserve esp, ebp, edi, esi, ebx. The esp and ebp is like duh and some assemblers fix that for you.
Posted on 2004-06-22 11:56:40 by roticv
Interesting is that the program works well under XP without PUSHA/POPA, I have problem only with Win9x, NT and 2k



Funny i think i know what it is... it happened to me for months. XP does us a favor by letting code run with its attach-ments or not letting code run without the attachment. I don't really know.

I think XP emulates our code by default. I would like to know if i can turn things like this off so it just be me and the CPU (direct please). Do we get any options between a OS and a CPU now and into the future.
Posted on 2004-06-22 13:38:36 by cmax
This is an off-topic question, but all of you keep mentioning these "callbacks." I've seen it before in C++ code for Win32 (obviously) and tried getting help on a C++ forum, but all they said was that it was Windows specific...not much help. Anyway I was just wondering if you guys could explain or point me to a link about these "callbacks" and what they're all about. Any help appreciated and sorry for such an off-topic question :alright:
Posted on 2004-06-22 13:56:31 by DaRetard
A "callback" is basically just a function that is 'called back' by another part of the system.
It is not Windows-specific ofcourse, other systems also use them at times.
A window proc is a good example of what a callback is. You create a function, but you never call it. You just pass the address of the function to the OS. Then everytime your window receives a message, the OS calls your function back.
Ofcourse the thing here is that your function must behave the way the OS expects, or else things are going to break ;)
Posted on 2004-06-22 14:55:49 by Scali
I see that I'm not the only one in this situation and most of you had strange experiences.
Originally posted by cmax
XP does us a favor by letting code run with its attach-ments or not letting code run without the attachment. I think XP emulates our code by default.

I'm not sure if I understand your opinion about the emulation. I hardly believe WinXP is emulating, because the programs run quite fast.
Posted on 2004-06-22 15:33:11 by bszente

A "callback" is basically just a function that is 'called back' by another part of the system.
It is not Windows-specific ofcourse, other systems also use them at times.
A window proc is a good example of what a callback is. You create a function, but you never call it. You just pass the address of the function to the OS. Then everytime your window receives a message, the OS calls your function back.
Ofcourse the thing here is that your function must behave the way the OS expects, or else things are going to break ;)

Now why couldn't those "C++ ers" give that good of an good explanation :grin: Thanks a lot for such a clear answer ;)
Posted on 2004-06-22 16:58:02 by DaRetard
Because most "C++ ers" don't have the faintest idea about what's really going on! :tongue: (Kidding of course!)
Posted on 2004-06-23 01:41:14 by SubEvil
Posted on 2004-06-23 05:33:21 by cmax
Quite possible. According to Raymond Chen, even C-calling convention window proc's are supported in some cases. He explained (and still does in his blog entries) what and why gross hacks are in windows kernel. Basically, some brain-damaged vendors (including MS themselves) got away with idiotic code in the past, and MS does not want to be blamed for breaking existing apps.

Maybe what you've been experimenting happened to replicate one of those cases, and triggered kernel hacks.
Posted on 2004-06-23 06:11:27 by Starless
I understand now your opinion, cmax. It might be monitoring the apps, rather than emulating.
Who knows which undocumented features are runnig in background... :)
It is true that the Windows explorer is slower, but I think due to the fact that it detects the content of a directory (music, photos, etc), and it displayes according background images in lower right corner, and it does probable many other "useless" :) stuffs. But in general I found that the applications run faster than under Win9x or Win2K. I'm quite satisfied with WinXP.
Posted on 2004-06-23 11:24:34 by bszente
Well, 9x seems a LOT more forgiving than XP... although the NT kernel does have a few gross hacks to support ring3 apps, like some particular nast stack hacks for eudora. So much for anybody blaiming microsoft for being hostile against third-party apps, they're actually hostile against their OWN code to support third-party apps :rolleyes: . Of course this is wrong, they should have simply broken compatibility with the BROKEN third-party apps, making *gross* assumptions about the internal workings of windows. Sigh, play by the fscking rules, people.

Yep, explorer is slower in winxp because of the metadata shit, and this pi$$es me off. A lot of other features makes it faster (well, the "end-user" experience is faster"), because of things like threading the icon-load stuff. But the end-result is ho-humm. Anyway, turn off the "last-access" time and you'll see a lot of explorer-related things (like filesearch, wow!) go a lot faster on NT.

But in general, I'm so much happier with NT than 9x... I'm still mixed-minds about XP, but after you turn off all the crudd, it's about as good as 2k. Some things are worse, some things are better. If you're not on a HTT machine and you don't have problems, there's not much use to go 2k->xp though (but on HTT, you do NOT want anything lower than xp!)
Posted on 2004-06-23 16:57:03 by f0dder
I almost love XP. Can't wait until i learn how to speed things up a bit. Until than its a guesting game for me.

HTT ... aha

Its about hardware ... Thanks
Posted on 2004-06-23 17:26:27 by cmax