

 
 
                       The beginning of Win32
                       ^^^^^^^^^^^^^^^^^^^^^^

                                 by Renegade


The most basic thing you learn in every programming language.
In Win32, displaying a simple MsgBox.

.386                       ; cpu type
model flat, Stdcall        ; model type 

extrn ExitProcess:proc     ;
extrn MessageBoxA:proc     ; API calls
 
.code                      ; beginning of code

start: call MessageBoxA, 0, offset text, offset caption, 0   ; display msg
       call ExitProcess                                      ; exit

.data       ; data section

text db "This is 32bit programming",0        ; our text
caption db "Welcome to a simple MsgBox",0    ; our caption

end start                                    ; the end
___________________________________________________________________________

Quite simple...but what's behind Win32 ?

Ring 3 uses the flat model, in ring 0 we have the normal addressing mode
with paging.
Using ring 3 there are three main segments..the code,data and the extra 
segment(s).Each of it has a total limit of 4 GB, whereas the size of a page
is 4 KB.With the paging in ring 3, because of the flat model,processes can
be used only with mapped addresses within the address space.
The address of most of the PE files is 0x0040000, that's where the loader
maps the file at startup.
You can allocate every type of memory block and execute the code, and you
can work also with pages containing code (write protection must be off).To
check this you can use VirtualQuery, which will give you also some infos
about Rread/Write options:
"The access of all pages is the same with the PAGE_READONLY, PAGE_READWRITE,
PAGE_NOACCESS, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, 
PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, or 
PAGE_NOCACHE flag."
To change the type of protection we have VirtualProtect will following 
options:PAGE_READONLY,PAGE_READWRITE, PAGE_WRITECOPY,PAGE_EXECUTE,
PAGE_EXECUTE_READ,PAGE_EXECUTE_READWRITE,PAGE_EXECUTE_WRITECOPY,PAGE_GUARD,
PAGE_NOACCESS,PAGE_NOCACHE.

Theoretically Win32 could be able to use not only the flat model.In ring 0
we could use also selectors.In win95 every machine has its own LDT (local
description table) used to access memory.But using NT every process has its
own LDT.This is used to distinguish NT from 95.The application selectors of
win95 use the LDT, the one of NT the GDT (Global description table).
In the LDT we find 32/16 bit segments, which are needed only really for
16 bit applications,that's why win95 and NT can execute also 16 bit stuff.
Btw, the LDT and GDT in win95 are not protected, so it can be written on 
them.
In ring 0 it's more complex to create a physical address.We can allocate a
page, some options of the VMM require a number of pages as arguments, this 
corresponds to DIR:TABLE of the linear addressing.
The paging mechanism is quite useful for the virtual memory managment, 
because a linear address will identify the page, but nobody will tell you
if the page is allocated or in memory.Trying to access a page which is not
present you'll get a wonderful GPF.The interrupt handler in the kernel will
check the presence of the page in the swap file and if so it will reallocate
it in memory.Then it will execute the instruction wich caused the GPF again.
If there's no such page in the swap file windows will display the right 
MsgBox,such as "error in page not valid".
Another important aspect of the paging is that it resolves in part the 
problem of defragmentation of the memory.For example if there would  be a 
series of adjacent linear addresses, which point to the same page, then it's
not obvious that they refer automatically to physical adjacent memory areas.
This allows apllications to allocate large memory blocks and treat them as
they would be made of true physical space.Anyway, the paging resolves the
problem of fragmentation of the physical memory, but that's all.
You have to pay attention to the fragmentation of the linear addresses.It
could happen that the usable adjacent linear addresses within a process 
aren't enough.To prevent this Win32 uses a series of flags for the 
allocation of memory.Once a block is allocated you will be returned a handle
and not a linear address.To access this block we first have to use 
GlobalLock:"The GlobalLock function locks a global memory object and returns
a pointer to the first byte of the object's memory block. The memory block 
associated with a locked memory object cannot be moved or discarded". 
So GlobalLock gives us the linear address.At the end we have to use
GlobalUnlock:"The GlobalUnlock function decrements the lock count associated 
with a memory object that was allocated with the GMEM_MOVEABLE flag". 
Using these API's and not linear addresses the address space will be 
automatically defragmentated by Win.

