The instruction at "0x00401189" referenced memory at "0x00404000". The memory could not be "written".

I'm not good enough at debugging, just observed this is the offending line:

mov , eax


...and here is the whole code, help?

...or http://wolfshade.home.ro/project.asm

project.asm
.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc
include \masm32\include\gdi32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib


WinMain proto :DWORD, :DWORD, :DWORD, :DWORD
ChildWndProc proto :DWORD, :DWORD, :DWORD, :DWORD

.data
ClassName db "Parent", 0
ChildClassName db "Child", 0
AppName db "Project", 0

.data?
hInstance dd ?
CommandLine dd ?
cxClient dd ?
cyClient dd ?
ChildIDsArray dd 13 dup(?)
i dd ?
temp1 dd ?
temp2 dd ?
temp3 dd ?

.code
start:
invoke GetModuleHandle, NULL
mov?  ?  hInstance, eax

invoke GetCommandLine
mov?  ?  CommandLine, eax

invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax

WinMain PROC hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND

mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET ClassName
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax

invoke RegisterClassEx, ADDR wc

mov wc.lpfnWndProc, OFFSET ChildWndProc
mov wc.cbWndExtra, 4
mov wc.lpszClassName, OFFSET ChildClassName
mov wc.hIcon, NULL

invoke RegisterClassEx, ADDR wc

invoke CreateWindowEx, NULL, ADDR ClassName, ADDR AppName,\
WS_OVERLAPPEDWINDOW,\
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,\
NULL, NULL, hInst, NULL
mov hwnd, eax

invoke ShowWindow, hwnd, SW_SHOWNORMAL
invoke UpdateWindow, hwnd

.WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW

mov?  ?  ? eax, msg.wParam
ret
WinMain endp

WndProc PROC hwnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_CREATE
xor ecx, ecx
mov ecx, 12; i = 12
push esi
xor esi, esi
label1::
xor edx, edx
mov edx, 13000
add edx, ecx
invoke CreateWindowEx, NULL, ADDR ChildClassName, NULL,\
WS_CHILDWINDOW + WS_VISIBLE,\
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,\
hwnd, edx, hInstance, NULL
mov , eax
add esi, 4
loop label1
pop esi

.elseif uMsg==WM_SIZE
mov edx, lParam
and lParam, 0FFFFh
push lParam
pop cxClient; Client width
mov lParam, edx
shr lParam, 16
push lParam
pop cyClient; Client height

mov temp2, 4
fld temp2 ; 4
fld1 ; 1, 4
fdivp ST(1), ST(0) ; 1/4
fld cxClient ; cxClient, 1/4
fmulp ST(1), ST(0) ; cxClient*(1/4)
fstp temp2 ; temp2 = ST(0), FPU stack balanced

mov temp3, 7
fld temp3 ; 7
fld1 ; 1, 7
fdivp ST(1), ST(0) ; 1/7
fld cxClient ; cxClient, 1/7
fmulp ST(1), ST(0) ; cxClient*(1/7)
fstp temp3 ; temp3 = ST(0), FPU stack balanced

xor ecx, ecx
mov ecx, 4
push esi
xor esi, esi
label2::
mov i, esi

mov temp1, 3
fld temp1 ; 4
fld i ; i, 4
fdivp ST(1), ST(0) ; i/4
fld cxClient ; cxClient, i/4
fmulp ST(1), ST(0) ; cxClient*(i/4)
fstp temp1 ; temp1 = ST(0), FPU stack balanced

invoke MoveWindow, , temp1, 0, temp2, temp3, TRUE
inc esi
loop label2
pop esi

?  ?  .elseif uMsg==WM_DESTROY
invoke PostQuitMessage, NULL

.else
invoke DefWindowProc, hwnd, uMsg, wParam, lParam
ret
.endif
xor eax,eax
ret
WndProc endp

ChildWndProc PROC hwnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL temp:DWORD
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL rect:RECT

.if uMsg==WM_CREATE
invoke SetWindowLong,hwnd, 0, 0

.elseif uMsg==WM_LBUTTONDOWN
invoke GetWindowLong, hwnd, 0
xor eax, 1
invoke SetWindowLong, hwnd, 0, eax
invoke InvalidateRect, hwnd, NULL, FALSE

.elseif uMsg==WM_PAINT
invoke BeginPaint, hwnd, ADDR ps
mov hdc, eax
invoke GetClientRect, hwnd, addr rect
invoke Rectangle, hdc, 0, 0, rect.right, rect.bottom

invoke GetWindowLong, hwnd, 0
.if eax
invoke MoveToEx, hdc, 0, 0, NULL
invoke LineTo, hdc, rect.right, rect.bottom
invoke MoveToEx, hdc, 0, rect.bottom, NULL
invoke LineTo, hdc, rect.right, 0
.endif
invoke EndPaint, hdc , ADDR ps

.else
invoke DefWindowProc, hwnd, uMsg, wParam, lParam

.endif
xor eax, eax
ret
ChildWndProc endp
end start
Posted on 2006-08-20 06:45:44 by w0lfshad3
Classic example of register preservation problem :)

Whenever you call a piece of external code, you should assume that EAX,ECX,EDX are destroyed - this means that ECX, your loop counter, is not reliable after the call to CreateWindowEx. Either push/pop it, or use a non-volatile register (EBX,ESI,EDI) for loop control.

And remember that EBX,ESI,EDI need to be preserved in callbacks, so if you use any of them you need either manual push/pop, or add the register(s) to the "USES" clause of the proc.
Posted on 2006-08-20 06:57:20 by f0dder
changed this: now all registers i use are push/pop but i get same error only it sais it can't "read" at that memory location; temp is a local double word variable, ChildIDsArray changed type to HWND wich is still a double word as before i think.

label1::
mov edx, 13000
add edx, ecx
mov temp, edx
push ecx
push esi
invoke CreateWindowEx, NULL, ADDR ChildClassName, NULL,\
WS_CHILDWINDOW + WS_VISIBLE,\
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,\
hwnd, , hInstance, NULL
pop esi
mov , eax
add esi, 4
pop ecx
loop label1
pop esi


In Petzold example the ChildIDsArray(wich are handles but still DWORD integers) are defined as static at file scope wich still means global i think in asm terms except for c it means they can only be accesed directly at that file scope.
I can't see the problem now, array memory is "reserved" for use at run-time, and everything else should work.
Posted on 2006-08-20 07:37:32 by w0lfshad3
I'm in the process of fixing up your code, will post a bit later, if the thunder doesn't nuke my computer ;)
Posted on 2006-08-20 08:10:45 by f0dder
lol k thank you very much, (thunder go away please :) well actually i will check again tomorrow.
I don't think i know to use a debugger properly(thank godness for VC7 catching it).
so i always see a tooltip when i look at that particular array+esp where esp is 4503 or such always, is that the real value that it holds when it gets there?, and that means my push/pops were useless?
Posted on 2006-08-20 08:57:56 by w0lfshad3
Visual Studio has a pretty decent debugger, but you'll probably be better off with OllyDebug for debugging your own assembly apps.

There's more problems with your code than just a few push/pop issues, I'm going to upload "fixed" source file + highlighted diffs of the changes once I'm done. Be patient :)
Posted on 2006-08-20 09:07:23 by f0dder
Yes :) like having DWORD variables to store floating point values instead of QWORD, and after all that needing to pass the values truncated to an integer actually to the function; and the same problem with MoveWindow like i have in this one.
I really need to learn to track my variables values in code.

EDIT: still stuck learned to debug a bit i can't tell yet whats the prob except ESI doesn't contain what i want at that time alltough in the debugger the code appears as i intended it to work.
Posted on 2006-08-20 18:24:26 by w0lfshad3
This did the trick however my code doesn't do what its suppose to do; make each child window appear as a rectangle and when it gets a mouse click draw an "X" on it, it uses a flag made out of window extra bytes; the code is made after i learned the "checker3" program of Charles Petzold's Programming Windows.

Think you can point me to what going wrong?

mov ecx, 4
push esi
xor esi, esi
push edi
xor edi, edi
label2::
mov i, edi

mov temp1, 3
fld temp1 ; 4
fld i ; i, 4
fdivp ST(1), ST(0) ; i/4
fld cxClient ; cxClient, i/4
fmulp ST(1), ST(0) ; cxClient*(i/4)
fstp temp1 ; temp1 = ST(0), FPU stack balanced

push ecx
push esi
push edi
invoke MoveWindow, , temp1, 0, temp2, temp3, TRUE
pop edi
inc edi
pop esi
add esi, 4
pop ecx
loop label2
pop esi
Posted on 2006-08-21 20:36:37 by w0lfshad3