Title: Win32 Programming with Masm Author: Evil Homer Dated: March 7, 2004 This is the second chapter of my tutorial, did you read the first one? We will be building on what we learned previously. start: call Main invoke ExitProcess,0 end start Hello, what's this? Obviously theres a function called Main, but why did we use "call" and not "invoke" ? What is the difference? Well in simple terms, we can use "call" where a function has NO params. To be more specific, theres no such thing as "invoke" really. If we looked at that code in a disassembler, it would look like this: start: call Main push 0 call ExitProcess end start To be even more specific, "invoke" causes a number of parameters (params) to be PUSHED onto the "stack", and then a CALL is made. We should know that since we are using the "Standard Calling Convention", that the params are in fact pushed in "reverse order", so our call to MessageBox looks something like this: push MB_OK push offset szMyTitle push offset szMyFirstString push 0 call MessageBox Gee, its much nicer to use the Invoke method, isn't it? Makes our source look much neater :) So could we use "invoke Main" instead of "call Main" ?? Yes, it makes NO difference. The only reason I used it was so I could ramble about how Invoke really works. Ok, so now we can begin to think of this little snippet of code at the "start:" label as being our "Entry Code". Obviously, the real fun will begin in "Main". Note that labels are identified by the trailing colon. So, are we forced to use the names "start" and "Main" ?? Not at all. You can call them whatever you want, thats just fine. So what goes on in Main? How do we define a procedure (aka "function")? Let's take a look: Main PROC invoke MessageBox,0,addr szMyFirstString, addr szMyTitle, MB_OK ret Main ENDP That's pretty easy, huh? Note the RET opcode there, all procs should have a RET at the end. Ok now something interesting: if in our source we have this Main procedure somewhere BEFORE the start label, and after the .CODE statement, everything is Peachy. If however, we have Main AFTER the call the ExitProcess and before the "end start" statement (which must ALWYS be the last line) then we have a problem: you see, we have a call to Main in our entry code, and we have not yet defined Main. We can get around this issue by placing one "prototype" for the procedure anywhere in the source before the call appears. A Prototype is a statement that tells the compiler how many parameters to expect in a procedure. Even if there are none, which is true in our case. Main PROTO That's all we would need to have for Main. Now the compiler knows that Main is a procedure, and how many params it has, even if the procedure itself is yet to be defined. Our Main procedure is still looking very thin and needs some meat on its bones. In fact, we can begin to think of our source so far as a "Skeleton", since we can save time by reusing the current source for various future projects. The act of adding code to a skeleton is often known as "Fleshing Out" the application, and so the term "skeleton" now makes sense to us. In the next installment of this tutorial, we will be covering the creation of our Application Window, and discussing what the "MessagePump" is, and how it relates to our Application Window.