I so totally don't get this line from tutorial#3 of iczelions tutorials

.BREAK .IF (!eax)

as far as i can tell ! is the logical NOT operator. I can't understand why you would want to break if eax was its own complimentry number. Can someone help please. I'm a Newbie.. :cool:

I know the .break means to break from the sequence and .if is under the condition that it is true. so wouldn't you have to find out if eax was zero or not.
Posted on 2003-11-26 23:45:36 by Phase Verocity
okay well maybe it just means is NOT 0, but he didn't say that in his tutorial so i am still wondering if that is right
Posted on 2003-11-26 23:48:27 by Phase Verocity
It will exit the loop if eax = 0 (!eax)

.IF eax -> eax <> 0

.IF !eax -> eax = 0

(!eax) is the same as !eax
Posted on 2003-11-26 23:49:03 by donkey
cheers.. looks like I had it the wrong way round.. glad I asked
Posted on 2003-11-27 02:28:09 by Phase Verocity
Why is it .BREAK .IF (!eax)
and not .IF (!eax) .BREAK ????
Posted on 2003-11-27 05:23:47 by AceEmbler
Both are acceptable, but the first one doesnt need a matching .endif, and only requires one line of code to check a single condition, whereas the second version requires a .endif but therefore can enclose any number of checks inside it.
See the MASM helpfile for more information.
Posted on 2003-11-27 07:19:35 by Homer


.loop:
lea eax, [.msg]
invoke GetMessage, eax, NULL, 0, 0
cmp eax, 0
jb .erro
je .fin
lea eax, [.msg]
invoke TranslateMessage, eax
lea eax, [.msg]
invoke DispatchMessage, eax
jmp .loop
.erro:
invoke MessageBoxA, 0, Error, Saliendo, MB_OK
.fin:
mov eax, dword[.msg+MSG.wParam]


I do in that way.....

In a strict way.. .BREAK .IF (!eax) is wrong, because Get message return -1 in case that there exist a error, but normally GetMessage not return that -1 ;).

the correct will be if eax is major to zero.


If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle.



Nice day or night.
Posted on 2003-11-27 12:41:48 by rea
Hi. :)

Actually,
.BREAK .IF EAX > 0

would be incorrect, since it considers EAX to be unsigned.
.BREAK .IF (EAX == 0) || (EAX == -1)

would be a little better, but IMHO this is the best way:


.repeat
invoke GetMessage,addr msg,0,0,0
inc eax
.break .if zero?
dec eax
.break .if zero?

;(...)

.until FALSE

Assembles the same as this:


@1:
push 0
push 0
push 0
lea eax,msg
push eax
call GetMessage
inc eax
jz @2
dec eax
jz @2

;(...)

jmp @1
@2:

My 0.02 on the topic. ;)



PS:
This is a bad idea:
.IF !EAX

.BREAK
.ENDIF

Since it assembles:


or eax,eax
jz @3
jmp @2
@3:
;etc...

That is, using an .IF block here would assemble an extra jump.
Posted on 2003-11-27 16:06:40 by QvasiModo
ok. well if you wrote you're code correctly I shoudn't think that you would need to worry about an invalid handle. Wouldn't worrying about it just produce more code. Also in tutorial 3 he uses a NULL for the window handle. I am wondering if you guys might know why I can't use hWnd. Cheers

:alright:
Posted on 2003-11-30 16:42:50 by Phase Verocity
Hi if you're talking about the CreateWindowEx function in WinMain then check this out:



HWND CreateWindowEx(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent, // handle to parent window.
HMENU hMenu, // handle to menu
HINSTANCE hInstance, // handle to current instance.
LPVOID lpParam
);


That should explain it, Since the window you create in tut 3 has no parent window but it itself is the main window. Remember that this function can also be used to create controls like textboxes, buttons, etc., so there you need to specify the handle to the parent.

Regards,
Art
Posted on 2003-11-30 16:55:40 by art_sands
maybe you could use jle.. ie jump if less than or equal.. I thought of this but then I realised that you would still need two jumps because you would have to jump over the code that jle jumped to. I am wondering if there is any way of taking the code that jle jumps to outside of the instruction set so that you don't have to jump over it in order to keep the code in line, And without performing yet another jump.

i.e.
.WHILE TRUE

invoke GetMessage,addr msg,NULL,0,0
jle nogo
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp over

nogo:
je breaker
invoke MessageBox, 0, addr Error, addr msgboxtitle, MB_OK

breaker:

.BREAK

over:
mov eax,msg.wParam
.ENDW


also I'm not sure why you needed this ---------> mov eax, dword[.msg+MSG.wParam] instead of
mov eax,msg.wParam


I'm still a newbie too
:confused:
Posted on 2003-11-30 18:28:03 by Phase Verocity
thankyou art.. I thought it just refered to the handle not the parent window handle:alright:
Posted on 2003-11-30 18:43:44 by Phase Verocity
I think your code need be some like this:

a infinite loop can be done some like this:
1)
.while TRUE
;code
.endw


Or:
2)
.startOfInfiniteLoop:
;code
jmp .startOfInfiniteLoop


The '.' is only for modify a label in nasm and be a "local label", dunno if is the same for masm, but i think is diferent...

A little mod, only for not take that jumps


.WHILE TRUE
.infiniteLoop:
invoke GetMessage,addr msg,NULL,0,0
cmp eax, 0; or eax, eax ; for set the flags but or will only work for set zero flag.. I think.
jle .nogo
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp .infiniteLoop

.nogo:
je breaker
invoke MessageBoxA, 0, Error, Saliendo, MB_OK
.breaker:
.BREAK ;only break for zero ok
.ENDW
mov eax,msg.wParam


Then taking the thing abou the infinite loops...



.infiniteLoop:
invoke GetMessage,addr msg,NULL,0,0
cmp eax, 0
jle .nogo
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp .infiniteLoop

.nogo:
je breaker
invoke MessageBoxA, 0, Error, Saliendo, MB_OK
.breaker:
mov eax,msg.wParam


I think you dont get here two jumps, that case is only when exist or eax equal to 0, it jump to the label (or target) .nogo and then jump to .breaker


The thing about:
1) mov eax,msg.wParam and
2) mov eax,

The second is nasm sintaxis, at the end, for access a structure is converted in access displacement of memory, this is, the label (or base address) msg plus the displacement of the member that you whan to access, because nasm dont have direct suport for manipulate structs, have a build macro that help on structs, then this macro work in the way (some like this): a) Give me a name for the struct, b) give me the members (for calculate the displacements) and c) I create some equates that Include the name of the struct in this case MSG a point and the member that you give me. Then MSG.wParam is equal to some like 8 and msg+MSG.wParam is msg+8.



I dont understand the words stream lined code.

I'm still a newbie too

Yep I continue working :D.


Nice day.

Posted on 2003-11-30 19:23:17 by rea
thanks hgb, I rewrote the code so that it works with masm. it is nearly the same as yours but i didn't use cmp. I haven't run the program with a window yet.. its still just a shell. so i don't know if its right but i didn't get any error messages.. is there any reason i need the cmp instruction and if so do you know why?

P.S. I edited the code in the message above. I can repost it if you like.

ok i looked up jle in my assembly book and it says you need to use a cmp to set the flags. that means it needs another instruction but. do you think its worth worrying about the -1.
Posted on 2003-11-30 19:41:02 by Phase Verocity
With cmp you modify the flags O(verflow) S(ign) Z(ero) A(uxiliary) P(arity) C(arry)


The importan here is compare to 0, and know if is equal or if is low, any greater is ok.

When you invoke (or call)
invoke GetMessage,addr msg,NULL,0,0

Here you dont know the last instruction that was executed and you dont know the state of the flags register(ok, maybe a ret 16 instruction), maybe a mov to eax (mov dont modify the flags).

That is for what you need test against 0 the value stored in eax that was returned by the funtion and modify the state of the flags that come from the execution of the function.



You need test because the anterior state of the flags come from the function, if interiorly was some comparision or additions, then the flags will be modificated in some way that you dont know.

That is for what you need modificate the flags with cmp.


About the code, yes you can ;), if you think is the same then dont put it ;), if you think that something is extrange put it.



--------------------------------------

About if necesary test against -1, becoming strict, yes because the function return that -1 and if you miss omething that is returned by some, you are skipping some part(but nobody say that you can not skip).. some time a go... that comparision let me know where was my error, and was that I dont test the value of hwnd agains 0 or NULL, and I enter directly to the loop, ok, then maybe you can move the comparision for example check if the hWnd is 0 outside of the loop, and in this way you dont need test each time, the suposition is that GetMessage and the others dont make errors.

Maybe another one solution (dont put a error message), only watch is is major than 0 is only one comparision, this is join .nogo and .breaker and delete the code betwen this instructions, in this way you are watching a 'posible' return of -1.

------
By the way you can look at this two references
status flags condition codes

Nice day or night.
Posted on 2003-11-30 20:13:05 by rea
well my final code looked like this.. you need to run the WinProc with it though and a DefWindowProc otherwise it freezes.

.386
.model flat,stdcall
option casemap:none


include windows.inc
include kernel32.inc
include user32.inc
;include a practise examp.inc
includelib kernel32.lib
includelib user32.lib

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

.CONST
.DATA

AppName db "An Application",0
ClassName db "A Class Name",0
Error db "Incorrect Parent Handle",0
msgboxtitle db "No Window Handle",0

.DATA?

hInstance HINSTANCE ?
CommandLine LPSTR ?

.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+CS_VREDRAW
mov wc.lpfnWndProc,OFFSET WinProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
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
cmp eax,0
jle nogo
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp over

nogo:
je breaker
invoke MessageBox, NULL, addr Error, addr msgboxtitle, MB_OK

breaker:
.BREAK

over:
mov eax,msg.wParam
.ENDW

ret

WinMain endp

WinProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax

ret

WinProc endp

end start


It seems to work.. I moved -1 into eax before the cmp and it produced the errorbox, however when I put the hWnd into the windows handle of the getmessage function I got a beep on exit.. I assume this was because it was tyring to display a box when the window was closing.

I still don't know if its worth worrying about the -1 output as I'm using radasm and it tells me about most of the mistakes, I am kind of wondering how you could get a wrong module handle. Still I did learn a bit from tying it out.

So Thankyou
Posted on 2003-11-30 21:58:50 by Phase Verocity
http://www.asmcommunity.net/board/index.php?topic=10788

I remember some extrange, try to (if you know how) take a look with a debugger at the files that i put in this thread... (time a go) http://www.asmcommunity.net/board/index.php?topic=10788

rename or delete the last .asm and only let the .exe, the first work ok, and the second with a very little diference dont work ok ...


For get a extrange window handle is something related to unaligned stack, or some ting like that....


That was one reason because I check the values, for dont get this extrange programms (sure that was at first days) but hey i can continue having problems today ;).


Nice day or night.
Posted on 2003-11-30 22:55:08 by rea
Phase Verocity,

Try the code below. It is much more concise and readable. Ratch



;*****WINDOWEX CREATION*********************************************************

MOV ECX,080000000H ;ECX=CW_USEDEFAULT
LEA EAX,[ESP.WINMAIN.szAppName]
LEA EDX,[ESP.WINMAIN.szCaption]
S2 EQU WS_OVERLAPPEDWINDOW OR WS_CLIPCHILDREN
INVOKE CreateWindowExA,EBP,EAX,EDX,S2,ECX,ECX,ECX,ECX,EBP,EBP,ESI,EBP ;ESI=hInst,EBP=0

;*****END OF WINDOWEX CREATION**************************************************

IF DBUG
.IF !EAX
INVOKE MessageBox,ESI,BYTER('Main CreateWindow call error',0),EBP,MB_OK ;message and exit if failure
JMP EXIT
.ENDIF
ENDIF

; MOV [hWnd],EAX ;window handle
MOV ESI,EAX ;now ESI=window handle

INVOKE ShowWindow,ESI,iCmdShow

INVOKE UpdateWindow,ESI

IF DBUG
.IF !EAX
INVOKE MessageBox,ESI,BYTER('UpdateWindow call error',0),EBP,MB_OK
JMP EXIT
.ENDIF
ENDIF

MOV EBX,ESP ;EBX=&msg

.WHILE TRUE ;beginning of message loop
INVOKE GetMessageA,EBX,EBP,EBP,EBP ;
TEST EAX,EAX

IF DBUG
JS GMERR ;jump out on GetMessage error
ELSE
JS EXIT ;jump out on GetMessage error
ENDIF

.BREAK .IF ZERO? ;jump out on WM_QUIT message

INVOKE TranslateMessage,EBX ;EBX=&msg
INVOKE DispatchMessageA,EBX ;EBX=&msg
.ENDW ;repeat message loop

MOV EAX,[ESP.WINMAIN.msg.wParam]

EXIT:
ADD ESP,WINMAIN ;recover local space

INVOKE ExitProcess,EAX

GMERR: ;display error message via message box & jmp to EXIT
INVOKE MessageBox,ESI,BYTER('GetMessage call error',0),EBP,MB_OK
JMP EXITCODE]
Posted on 2003-12-01 08:27:38 by Ratch
I've tried to put that code in but I've come up with an error that it doesn't know what dbug is.. I don't know what dbug is either.. could you tell me please. Nice bit of code on the createwindowsex though, I didn't realise you didn't need to register the class.
Posted on 2003-12-01 09:52:40 by Phase Verocity
DBUG looks like a flag that is defined for conditional assembly, he should use IFDEF instead so it will still compile if DBUG has not been defined.

Alternatively you can just put DBUG equ 1 or DBUG equ 0 at the top of your source.

{EDIT}BTW if you use IFDEF do not define DBUG if you do not want those blocks assembled{/EDIT}
Posted on 2003-12-01 10:09:44 by donkey