Fasm tutorial, assembly in windows.

ok, this tutorial is aimed at those who know the basics behind assembly. i am not going to explain what hexedecimal,binary and decemal are, or how to convert between them or any of thatc stuff. that is well documented, google it if you dont know. this will be in many parts, and im going to deal with the useful stuff really, guis, that stuff...
ok, i am using a compiler called FASM, available at:

http://flatassembler.net/

hey, ho, lets go...

ok, our first program be an introduction to assembly, hello world. basicly a comment is anything following a ;. this means its just excess text, doesnt affect the compiler.

here goes
----------------------------------------------------------->

format PE GUI 4.0 ; tell FASM not to create a console basicly
entry start ; define where to start the program
include 'win32a.inc' ; standard include file

----------------------------------------------------------->

ok, thats the standard headings. iv added comments so you can see what is going on.

the first section is the data, which, in FASM is denoted by the line

section '.data' data readable writeable

this tells the compiler its your data definitions.
so next comes:
----------------------------------------------------------->

section '.data' data readable writeable
_caption db 'hello world!',0; define _caption as hello world!
_message db 'Hello!!',0 ;ditto

------------------------------------------------------------->

ok, you may have seen the comma followed by a zero. this tells the computer where the data ends, try it with them and without them and see the difference.

next comes the code, this is code which is written in pure form, it doesnt use invoke.ok, lets see the next part, the actual code.

---------------------------------------------------------------->

section '.code' code readable executable
start:
push MB_OK ;   style of the messagebox. this is just an ok button
push _caption ;      the title
push _message ;     whats in the messagebox
push NULL ;handle,      dont worry about this for now
call [MessageBox] ;     calling the messagebox.
ret  ;return, exit, basicly.

-------------------------------------------------------------------->

push is a command which will put the item that follows it, on the stack, which is a section of memory. remember, you push onto, and pop off.

ok, thats all very straight forward, isnt it people?
now, in the windows api guide, you may see the messagebox function and think, "hey, wait a minute, here it says to define them in one order, but you define them backwards"

well, yes, in this method of calling a message box, we work for left to right from the api reference. the reason we push them in reverse order is simply because the stack is FILO, or first in last out. this means what we put in first will be last and vice versa, so by putting it in backwards, we compensate for the FILO effect, and so it works.

now, the last section, the imports

-------------------------------------------------------------------->

section '.idata' import data readable writeable
library user,'USER32.dll'

import user,\
MessageBox,'MessageBoxA'

-------------------------------------------------------------------->
this just tells the compiler which api functions we want. its pretty simple.

and thats it, for those who want it, heres the code in full for our basic hello world.

-------------------------------------------------------------------->

format PE GUI 4.0
entry start
include 'win32a.inc'

section '.data' data readable writeable
_caption db 'hello world!',0
_message db 'Hello!!',0

section '.code' code readable executable
start:
push MB_OK
push _caption
push _message
push NULL
call [MessageBox]
ret

section '.idata' import data readable writeable
library user,'USER32.dll'

import user,\
MessageBox,'MessageBoxA'  

-------------------------------------------------------------------->

WOW, it works. paste this into fasm's editor, and click run, compile. and then run it.

you should get your first assembly program!!

ok, now something a bit more advanced, on this same theme. we will code a simple message box which will ask you if you want to run notepad, and then run it for you if you choose yes.

ok, as some of this code is similar, i wont comment it as much, i will only comment the new bits.

---------------------------------------------------------------------->
format PE GUI 4.0
entry start
include 'win32a.inc'

section '.data' data readable writeable

_message db 'Do you want to start notepad??',0
_caption db 'Tutorial 2',0


_notepad db 'notepad',0

-------------------------------------------------------------------->

simple, you know about all that.

now this next bit isn't as simple, it has a few jumps in it, i will explain them as i go along.

------------------------------------------------------------>
section '.code' code readable executable
start:
push MB_ICONQUESTION+MB_YESNO ;style, an icon now, and yes no buttons
push _caption
push _message
push NULL
call [MessageBox]

cmp eax,IDYES ;cmp is compare, see below
jz execute ; a jump, see below
jmp finish ; a different type of jump, see below

execute:

push SW_SHOW
push _notepad
call [WinExec] ; a different type of api, see below.
jmp finish

finish:
ret                                  
                                         
------------------------------------------------------------------>

ok, lets teach you what some of this stuff does.

cmp : this stands for compare, and is simple, it compares the two things you give it, and sees if they are equal or not.

jz : this is a jump, but a conditional jump. this means it depends on the cmp above it. if the two are equal, then the jump is executed. if they are not, nothing happens as far as that line is concerned.

jmp: this is a standard jump. it is not conditional, and will always execute. the 3 lines:

cmp eax,IDYES
jz execute
jmp finish

are used to process all possibilities. if the answer was yes, then it jumps to the routine 'execute', and jumps over the line below, meaning the line below is not processed.  however, if the answer is no, no jump happens, and the next line is execute, which jumps to the routine 'finish'

i hope you understand that, its all logic really.
also is the call i make to WinExec. this is an api command to execute a command. i define this in the data section, and i just execute 'notepad' which will run notepad.  

the last thing you havent really come across is the notations of

execute: and finish:

this is basicly a way of defining sub routines. they are not executed unless jumped to. they are just like subs in perl or any other language for that matter.

ok, last section is the imports again.

------------------------------------------------------------------>
section '.idata' import data readable writeable
 library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL'

import kernel,\
WinExec,'WinExec'

import user,\
MessageBox,'MessageBoxA'

------------------------------------------------------------------->

so heres the whole lot in full again:

-------------------------------------------------------------------->


format PE GUI 4.0
entry start
include 'win32a.inc'

section '.data' data readable writeable

_message db 'Do you want to start notepad??',0
_caption db 'asm practice',0


_notepad db 'notepad',0

section '.code' code readable executable
start:

push MB_ICONQUESTION+MB_YESNO
push _caption
push _message
push NULL
call [MessageBox]

cmp eax,IDYES
jz execute
jmp finish


execute:

push SW_SHOW
push _notepad
call [WinExec]
jmp finish

finish:
ret

section '.idata' import data readable writeable
 library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL'

import kernel,\
WinExec,'WinExec'

import user,\
MessageBox,'MessageBoxA'

---------------------------------------------------------------->

ok, people thats it for part 1 of assembly programming on windows.