Listado de tut03es1.asm
|
format PE GUI
include 'macros.inc'
NULL = 00h
WM_DESTROY = 0002h
GWL_WNDPROC = -4
WS_VISIBLE = 010000000h
WS_SYSMENU = 000080000h
WS_THICKFRAME = 000040000h
WS_EX_TOPMOST = 00008h
ES_MULTILINE = 0004h
ES_AUTOVSCROLL = 0040h
struc POINT
{
.x dd ?
.y dd ?
}
struc MSG
{
.hwnd dd ?
.message dd ?
.wParam dd ?
.lParam dd ?
.time dd ?
.pt POINT
}
section '.code' code readable executable
call CreateWindowEx,WS_EX_TOPMOST,_class,_title,\
WS_VISIBLE or WS_SYSMENU or WS_THICKFRAME\
or ES_AUTOVSCROLL or ES_MULTILINE,\
200,220,220,180,\
NULL,NULL,NULL,NULL
mov [hwnd],eax
call SetWindowLong,eax,GWL_WNDPROC,WndProc
mov [oldproc],eax
msg_loop:
call GetMessage,msg,NULL,0,0
or eax,eax
jz terminate
call TranslateMessage,msg
call DispatchMessage,msg
jmp msg_loop
terminate:
call ExitProcess,[msg.wParam]
WndProc:
push ebp
mov ebp,esp
mov eax,[ebp+12]
cmp eax,WM_DESTROY
jne .default
call PostQuitMessage,0
.default:
call CallWindowProc,[oldproc],[ebp+8],\
[ebp+12],[ebp+16],[ebp+20]
leave
retn 16
section '.data' data readable writeable
hwnd dd ?
oldproc dd ?
msg MSG
_class db 'EDIT',0
_title db 'Ensamblando Win32',0
section '.idata' import data readable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL'
import kernel,\
ExitProcess,'ExitProcess'
import user,\
CallWindowProc,'CallWindowProcA',\
CreateWindowEx,'CreateWindowExA',\
DispatchMessage,'DispatchMessageA',\
GetMessage,'GetMessageA',\
PostQuitMessage,'PostQuitMessage',\
SetWindowLong,'SetWindowLongA',\
TranslateMessage,'TranslateMessage'
|
|
Pantallazo
|
|
|
El principio no cambia. Las dos primeras líneas ya son muy familiares y el archivo 'macros.inc' es el mismo del curso anterior.
|
A las igualdades que se encuentran al principio las llamaremos constantes de Windows. Son simplemente números a los que daremos nombres especiales.
Podríamos usar solo los números respectivos y el programa funciona igualmente. Pero es más fácil recordar que quiere decir "WS_VISIBLE" que simplemente "010000000h".
|
struc
La primera novedad del ejemplo es una directiva del fasm que nos permite asociar diferentes etiquetas bajo un mismo nombre de base, comportandose como una unidad llamada estructura.
| POINT es muy usado en las librerías de Windows. Se usa para describir un punto en la pantalla por medio de las coordenadas x e y.
|
MSG es otra estructura básica para el Windows. Se utiliza para comunicaciones entre el sistema operativo y cada aplicación.
Entre la información comunicada encontramos un punto, es decir, podemos definir estructuras usando otras estructuras.
|
Comienza la sección '.code' y con ella, la ejecución de nuestro programa.
El sistema operativo cargará la sección en memoria y pondrá el procesador a ejecutar en la primera línea que encuentra, en éste caso, llamará la función CreateWindowEx por medio de nuestra macro call.
|
CreateWindowEx
Es una función de Windows, específicamente de la librería user32.dll. Nos permite crear una ventana con unas características determinadas. Las características se determinan con los valores que dejamos en la pila.
| En el caso particular, la función espera encontrar doce (12) valores en estricto orden.
|
Otra novedad es el uso de "\" para continuar en la línea siguiente. Fasm interpretará cada línea siguiente como si hiciera parte de la misma línea.
|
Estamos creando una ventana muy conocida y utilizada en windows: EDIT. En windows, cada objeto que vemos en la pantalla es o hace parte de una ventana. Cada tipo de ventana pertenece a una clase determinada. Cada ventana EDIT que sea creada, tiene las mismas características y comportamiento aunque nosotros podemos adaptarlo a nuestras necesidades.
|
mov
Es una de las instrucciones más conocidas del lenguaje ensamblador y es quizá la más utilizada. Es una orden directa al procesador para que asigne un valor en una posición determinada.
| Aquí se trata de asignar en una posición de memoria con etiqueta hwnd, el valor que hay en eax.
|
eax
Es un registro del procesador. Se llama acumulador y tiene una capacidad de 32 bits.
Un registro es un componente electrónico que hace parte del procesador y es en realidad un área de trabajo. El procesador puede trabajar solo con la información que almacena uno de los registros.
Como se deduce de lo anterior, la importancia de los registros es crucial para la programación de computadores y por lo tanto tendremos la oportunidad de profundizar el tema.
|
La situación es análoga con las demás funciones y describiremos dentro de poco su funcionamiento. Por ahora veamos un elemento crucial para el funcionamiento de una aplicación: el bucle de mensajes (message loop).
Las aplicaciones en Windows dependen de la información que el sistema les entrega bajo forma de mensajes. Los movimientos del ratón, una tecla pulsada, un temporizador o un menu, por ejemplo, llegan a nuestra aplicación en forma de mensajes. La aplicación decide cómo y a cuales mensajes responder.
El loop girara eternamente, esperando a que nosotros le indiquemos cuando parar y terminar el programa.
|
WndProc
Es el procedimiento de la ventana de nuestra aplicación. Se encarga de recibir y procesar los mensajes a los cuales queremos responder.
Para responder un mensaje, necesitamos identificarlo y escribir el código necesario para cumplir con la función deseada. Ampliaremos éste procedimiento en breve.
|
El resto del programa es bien conocido en éste momento. La sección '.data' contiene unas etiquetas nuevas, definidas con directivas de datos pero con valor indeterminado denotado por ?. El objetivo de dichas etiquetas es el de manipular variables, es decir, escribiremos en unos espacios reservados en la memoria.
| por ejemplo, con la etiqueta hwnd, denotaremos la información contenida en los 32 bits que componen un dword, definido con la directiva dd.
|
La estructura MSG (en mayúsculas), ocupa un total de 5 dwords (dd) más un punto (POINT) que ocupa 2 dwords más o sea 28 bytes. Es decir, a continuación de la etiqueta msg (en minúsculas), Fasm reserva 28 bytes para la información que escribiremos durante la ejecución del programa.
Usaremos bytes cómo unidad de base para medir la cantidad de memoria porque casi todas las funciones de Windows lo requieren.
|
|