Está en la página 1de 68

2012

EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER

Javier Gara Cambronel SEGUNDO DE ASIR 08/01/2012

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

EJERCICIO1 EJERCICIO2 EJERCICIO3 EJERCICIO4 EJERCICIO5 EJERCICIO6 EJERCICIO7 EJERCICIO8

EJERCICIO9
EJERCICIO10 EJERCICIO11 EJERCICIO12

EJERCICIO13
EJERCICIO14 EJERCICIO15

SEGUNDO DE ASIR

Pgina 1

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

MICROSOFT MACRO ASSEMBLER


El Microsoft Macro Assembler (MASM) es un ensamblador para la familia x86 de microprocesadores. Fue producido originalmente por Microsoft para el trabajo de desarrollo en su sistema operativo MS-DOS, y fue durante cierto tiempo el ensamblador ms popular disponible para ese sistema operativo. El MASM soport una amplia variedad de facilidades para macros y programacin estructurada, incluyendo construcciones de alto nivel para bucles, llamadas a procedimientos y alternacin (por lo tanto, MASM es un ejemplo de un ensamblador de alto nivel). Versiones posteriores agregaron la capacidad de producir programas para los sistemas operativos Windows. MASM es una de las pocas herramientas de desarrollo de Microsoft para las cuales no haba versiones separadas de 16 bits y 32 bits. INSTALACIN Y COMPILACIN Y EJECUCIN DE NUESTRO PRIMER PROGRAMA
Nos metemos en la pgina Web para descargarnos el programa

SEGUNDO DE ASIR

Pgina 2

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


Seleccionamos la opcin de Download

Una vez descargado procedemos a la instalacin seleccionando la ruta (letra de la unidad donde se instalar)

Aceptamos el mensaje que se nos muestra y se extraer e instalara juestamente despus

Se crear un icono en el escritorio el cual tendremos que ejecutar para iniciar el programa

SEGUNDO DE ASIR

Pgina 3

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


Una vez este ejecutado, podemos ver todas las opciones que nos presenta el programa y podremos despleguar los disitintos menus que se nos presentan, podremos abrir un archivo, guardarlo.

Funciona como un sencillo editor de texto y en la imagen que vemos ms abajo, vemos nuestro cdigo y remarcado en rojo donde pulsaremos para guardar el archivo

El archivo, lo tenemos que guardar con el nombre que queramos, pero hay que tener en cuenta que la extensin tiene que ser ASM como vemos en la imagen

SEGUNDO DE ASIR

Pgina 4

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


Una vez guardado pulsamos la opcin de Console Build All para compilarlo

Y nos saldr la siguiente ventana donde se ve que dicho proceso se esta llevando a cabo

Una vez llevado a cabo pulsando la opcin Run program, ejecutaremos el programa que acabamos de compilar

Y veremos el resultado

SEGUNDO DE ASIR

Pgina 5

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO1


Ensmblalo y crrelo. Vers un cuadro de mensaje desplegando el texto " Este es el ejemplo1 de esta serie de ejercicios realizados por Javier Garca Veamos de nuevo el cdigo fuente. Definimos dos cadenas terminadas en cero en la seccin .data. Recuerda que toda cadena ANSI en Windows debe terminar en NULL (0 hexadecimal). Usamos dos constantes, NULL y MB_OK. Esas constantes estn documentadas en windows.inc. As que nos referiremos a ellas por nombres y no por valores. Esto facilita la lectura de nuestro cdigo fuente. El operador addr es usado para pasar la direccin de una etiqueta a la funcin. Es vlido slo en el contexto de la directiva invoke. No puedes usarla para asignar la direccin de un registro/variable, por ejemplo. En vez de esto, puedes usar offset en el ejemplo anterior. Sin embargo hay algunas diferencias entre los dos: 1. addr no puede manejar referencias delante de ella mientras que offset si puede. Por ejemplo, si la etiqueta est definida en una parte ms adelante del cdigo fuente que la directiva invoke, entonces addr no trabajar. invoke MessageBox,NULL, addr MsgBoxText,addr MsgBoxCaption,MB_OK ...... MsgBoxCaption db " EJERCICIOS ENSAMBLADOR ",0 MsgBoxText db " Este es el ejemplo1 de esta serie de ejercicios realizados por Javier Garca ",0 MASM reportar error.Si usas offset en vez de addr .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib include \masm32\include\user32.inc includelib \masm32\lib\user32.lib .data MsgBoxCaption db "EJERCICIOS ENSAMBLADOR",0 MsgBoxText db "Este es el ejemplo1 de esta serie de ejercicios realizados por Javier Garca Cambronel",0 .code start: invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK invoke ExitProcess, NULL end start EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 6

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO2


Construiremos un programa para Windows que despliegue una ventana completamente funcional sobre el escritorio .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib WinMain proto :DWORD,:DWORD,:DWORD,:DWORD .data ClassName db "SimpleWinClass",0 AppName db "Esta es mi primera ventana",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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInstance pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\

SEGUNDO DE ASIR

Pgina 7

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


hInst,NULL mov hwnd,eax invoke ShowWindow, hwnd,SW_SHOWNORMAL invoke UpdateWindow, hwnd .WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp

WndProc 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 WndProc endp end start

EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 8

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO3


Construiremos un programa para "pintar" texto en el rea cliente de una ventana. El texto en Windows es un tipo de objeto GUI. Cada carcter est compuesto por numerosos pixeles o puntos (dots) que estn amontonados dentro de un patrones distintos. Por eso hablamos de "pintar" en vez de "escribir". Normalmente, pintas texto en tu propia area cliente (relamente, puedes tambin pintar fuera del area cliente, pero eso es otra historia). En Windows, poner texto en la pantalla es algo radicalmente distinto a DOS. En DOS, puedes pensar en la pantalla como una dimensin de 80x25. Pero en Windows, la pantalla es compartida por varios programas. Algunas reglas deben ser reforzadas para evitar que los programas escriban sobre la pantalla de otros. Windows asegura esto limitando el rea para pintar de cada ventana a su rea cliente solamente. El tamao del area cliente de una ventana tampoco es constante. El usuario puede cambiarla en cualquier momento. As que hay que determinar dinmicamente las dimensiones del rea cliente de las ventanas. Antes de que puedas pintar algo sobre el rea cliente, debes pedir permiso a Windows. Eso es correcto, ya no tienes el control total sobre el monitor como lo tenas con DOS. Debes pedir permiso a Windows para pintar tu propia area cliente. Windows determinar el tamao de tu rea cliente, de la fuente, los colores y otros atributos GDI y regresar un manejador del contexto de dispositivo a tu programa. Luego puedes emplear tu contexto de dispositivo como un pasaporte para pintar tu rea cliente. .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data ClassName db "SimpleWinClass",0 AppName db "Esta es mi primera ventana",0 OurText db "Y este mi mensaje que se muestra",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine 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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst

SEGUNDO DE ASIR

Pgina 9

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,0 invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax 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 .BREAK .IF (!eax) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT LOCAL rect:RECT .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_PAINT invoke BeginPaint,hWnd, ADDR ps mov hdc,eax invoke GetClientRect,hWnd, ADDR rect invoke DrawText, hdc,ADDR OurText,-1, ADDR rect, DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint,hWnd, ADDR ps .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end start

SEGUNDO DE ASIR

Pgina 10

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 11

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO4


Construiremos como en el ejercico anterior una ventana con texto pero esta vez con formato, es decir de una forma mas, digamoscompleja y a la vez presentable con colores, tipos de letras y dems. El sistema de colores de Windows est basado en valores RGB, R=red (rojo), G=Green (verde), B=Blue (azul). Si quieres especificar un color en Windows, debes establecer el color que desees en trminos de estos tres colores mayores. Cada valor de color tiene un rango desde 0 a 255 (un valor de un byte). Por ejemplo, si quieres un color rojo puro, deberas usar 255,0,0. O si quieres un color blanco puro, debes usar 255,255,255. Puedes ver en los ejemplos que obtener el color que necesitas es muy difcil con este sistema ya que tienes que tener una buena comprensin de como mezclar y hacer corresponder los colores .386 .model flat,stdcall option casemap:none

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


include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib RGB macro red,green,blue xor eax,eax mov ah,blue shl eax,8 mov ah,green mov al,red endm .data ClassName db "SimpleWinClass",0 AppName db "Esta es mi primera ventana",0 TestString db "Este es mi primer texto con formato",0 FontName db "script",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine 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

SEGUNDO DE ASIR

Pgina 12

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax 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 .BREAK .IF (!eax) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT LOCAL hfont:HFONT .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_PAINT invoke BeginPaint,hWnd, ADDR ps mov hdc,eax invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\ OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\ DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\ ADDR FontName invoke SelectObject, hdc, eax mov hfont,eax RGB 200,200,50 invoke SetTextColor,hdc,eax RGB 0,0,255 invoke SetBkColor,hdc,eax invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString invoke SelectObject,hdc, hfont invoke EndPaint,hWnd, ADDR ps

SEGUNDO DE ASIR

Pgina 13

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


.ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end start EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 14

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO5


Crearemos un programa de Windows recibe entrada de teclado Como normalmente slo hay un teclado para cada PC, todos los programas de Windows deben compartirlo entre s. Windows es responsable de enviar los golpes de tecla a la ventana que tiene el foco de entrada. Aunque pueden haber varias ventanas en el monitor, slo una de ellas tiene el foco de entrada. La ventana que tiene el foco de entrada es la nica que puede recibir los golpes de tecla. Puedes diferenciar la ventana que tiene el foco de entrada de las otras ventanas observando la barra de ttulo. La barra de ttulo del programa que tiene el foco est iluminada. Realmente, hay dos tipos principales de mensajes de teclado, dependiendo de tu punto de vista sobre el teclado. Puedes ver el teclado como una coleccin de teclas. En este caso, si presionas una tecla, Windows enva un mensaje WM_KEYDOWN a la ventana que tiene el foco de entrada, que notifica que una tecla ha sido presionada. Cuando sueltas la tecla, Windows enva un mensaje WM_KEYUP. T tratas a las teclas como si fueran botones. Otra manera de ver el teclado es como un dispositivo de entrada de caracteres. Cuando presionas "una" tecla, Windows enva un mensaje WM_CHAR a la ventana que tiene el foco de entrada, dicindole que el usuario enva "un" caracter a ella. En realidad, Windows enva mensajes WM_KEYDOWN y WM_KEYUP a la ventana que tiene el foco de entrada y esos mensajes sern traducidos a mensajes WM_CHAR por una llamada a TranslateMessage. El procedimiento de ventana puede decidir si procesa los tres mensajes o slo los mensajes que interesan. Muchas veces, podrs ignorar WM_KEYDOWN y WM_KEYUP ya que la funcin TranslateMessage en el bucle de mensajes traduce los mensajes WM_KEYDOWN y WM_KEYUP a mensajes WM_CHAR. En este tutorial nos concentraremos en WM_CHA .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib .data ClassName db "SimpleWinClass",0 AppName db "Our First Window",0 char WPARAM 20h .data? hInstance HINSTANCE ? CommandLine LPSTR ? .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT invoke ExitProcess,eax WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX

SEGUNDO DE ASIR

Pgina 15

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax 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 .BREAK .IF (!eax) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_CHAR push wParam pop char invoke InvalidateRect, hWnd,NULL,TRUE .ELSEIF uMsg==WM_PAINT invoke BeginPaint,hWnd, ADDR ps mov hdc,eax invoke TextOut,hdc,0,0,ADDR char,1 invoke EndPaint,hWnd, ADDR ps .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax

SEGUNDO DE ASIR

Pgina 16

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


ret WndProc endp end start EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 17

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO6


Crearemos un programa para recibir y responder a la entrada del ratn en nuestro procedimiento de ventana. El programa esperar por los clicks del botn izquierdo del ratn y desplegar una cadena de texto en exactamente el punto indicado por el ratn sobre el rea cliente. Como con la entrada del teclado, Windows detecta y enva notificaciones sobre las actividades del ratn que son relevantes para las ventanas. Esas actividades incluyen los clicks de los botones izquierdo y derecho del ratn, el movimiento del cursor del ratn sobre la ventana, doble clicks. A diferencia de la entrada del teclado, que es dirigida a la ventana que tiene el foco de entrada, los mensajes del ratn son enviados a cualquier ventana sobre la cual est el cursor del ratn, activo o no. Adems, tambin hay mensajes del ratn sobre el rea no cliente. Pero la mayora de las veces, afortunademente podemos ignorarlas. Podemos concentrarnos en los mensajes relacionados con el rea cliente. Hay dos mensajes para cada botn el ratn: los mensajes WM_LBUTTONDOWN, WM_RBUTTONDOWN y WM_LBUTTONUP, WM_RBUTTONUP. Para un ratn con tres botones, estn tambin WM_MBUTTONDOWN and WM_MBUTTONUP. Cuando el cursor del ratn se mueve sobre el rea cliente, Windows enva mensajes WM_MOUSEMOVE a la ventana debajo del cursor. Una ventana puede recibir mensajes de doble clicks, WM_LBUTTONDBCLK o WM_RBUTTONDBCLK, si y slo si la clase de su ventana tiene activada la bandera correspondiente al estilo CS_DBLCLKS, sino la ventana recibir slo una serie de mensajes del topo botn del ratn arriba o abajo. Para todos estos mensajes, el valor de lParam contiene la posicin del ratn. La palabra [word] baja es la coordenada 'x', y la palabra alta es la coordenada 'y' relativa a la esquina izquierda superior del rea cliente de la ventana. wParam indica el estado de los botones del ratn y de las teclas Shift y Ct

.386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib .data ClassName db "SimpleWinClass",0 AppName db "Este es mi mensaje, se muestra donde has clickeado",0 MouseClick db 0 ; 0=no click yet .data? hInstance HINSTANCE ? CommandLine LPSTR ? hitpoint POINT <> .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT

SEGUNDO DE ASIR

Pgina 18

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax 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 .BREAK .IF (!eax) INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_LBUTTONDOWN mov eax,lParam and eax,0ffffh mov hitpoint.x,eax mov eax,lParam shr eax,16 mov hitpoint.y,eax mov MouseClick,TRUE invoke InvalidateRect,hWnd,NULL,TRUE .ELSEIF uMsg==WM_PAINT invoke BeginPaint,hWnd, ADDR ps mov hdc,eax

SEGUNDO DE ASIR

Pgina 19

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


.IF MouseClick invoke lstrlen,ADDR AppName invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR AppName,eax .ENDIF invoke EndPaint,hWnd, ADDR ps .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end start

EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 20

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO7


En este programa crearemos un men, con varias opciones, realizando cada una de ellas una accin de mensaje en otra ventana diferente. El men es uno de los componentes ms importantes en nuestra ventana. El men presenta una lista de los servicios que un programa ofrece a un usuario. El usuario ya no tiene que leer el manual incluido con el programa para utilizarlo, ya que puede leerse cuidadosamente el men para obtener una visin general de las capacidades de un programa particular y comenzar a trabajar con l inmediatamante. Como el men es una herramienta para obtener el acercamiento del usuario y correr el programa rpidamente, se debera seguir siempre el estandard. Puesto sucintamente, los primeros dos elementos [items] del men deberan ser Archivo [File] y Editar [Edit] y el ltimo debera ser Ayuda [Help]. Puedes insertar tus propios elementos de men entre Editar y Ayuda. Si un elemento de men invoca una caja de dilogo, deberas anexar una ellipsis (...) a la cadena del men. El men es un tipo de recurso. Hay varios tipos de recursos, tales como dialog box, string table, icon, bitmap, men etc. Los recursos son descritos en un archivo separado llamado archivo de recursos, el cual generalmente tiene extensin .rc. Luego combinas los recursos cion el archivo fuente durante el estado de enlace. El resultado final es un archivo ejecutable que contiene tanto instrucciones como recursos. Puedes escribir guiones [scripts] de recursos usando un editor de texto. Estos guiones estn compuestos por frases que describen la apariencia y otros atributos de los recursos usados en un programa particular. Aunque puedes escribir guiones de recursos con un editor de texto, esto resulta ms bien embarazoso. Una mejor altrenativa es usar un editor de recursos que te permita visualizar con facilidad el diseo de los recursos. Usualmente los paquetes de compiladores como Visual C++, Borland C++, etc, incluyen editores de recursos .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data ClassName db "SimpleWinClass",0 AppName db "Our First Window",0 MenuName db "FirstMenu",0 Test_string db "You selected Test menu item",0 Hello_string db "Hello, my friend",0 Goodbye_string db "See you again, bye",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? .const IDM_TEST equ 1 IDM_HELLO equ 2 IDM_GOODBYE equ 3 IDM_EXIT equ 4 .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine

SEGUNDO DE ASIR

Pgina 21

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax 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 .BREAK .IF (!eax) INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam .IF ax==IDM_TEST invoke MessageBox,NULL,ADDR Test_string,OFFSET AppName,MB_OK .ELSEIF ax==IDM_HELLO invoke MessageBox, NULL,ADDR Hello_string, OFFSET AppName,MB_OK .ELSEIF ax==IDM_GOODBYE invoke MessageBox,NULL,ADDR Goodbye_string, OFFSET AppName, MB_OK .ELSE invoke DestroyWindow,hWnd .ENDIF .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret

SEGUNDO DE ASIR

Pgina 22

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


.ENDIF xor eax,eax ret WndProc endp end start MENU RC #define IDM_TEST 1 #define IDM_HELLO 2 #define IDM_GOODBYE 3 #define IDM_EXIT 4 FirstMenu MENU { POPUP "&PopUp" { MENUITEM "&Say Hello",IDM_HELLO MENUITEM "Say &GoodBye", IDM_GOODBYE MENUITEM SEPARATOR MENUITEM "E&xit",IDM_EXIT } MENUITEM "&Test", IDM_TEST } MAKEFILE NAME=menu $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 23

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

SEGUNDO DE ASIR

Pgina 24

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO8


Exploraremos los controles de ventana que son unos dispositivos de entrada y salida muy importantes dentro de nuestros programas Windows provee algunas clases de ventana predefinidas que podemos usar satisfactoriamente dentro de nuestros programas. Muchas veces las usamos como componentes de una caja de dilogo por lo que ellas usualmente son llamadas controles de ventanas hijas. Los controles de ventanas hijas procesan sus propios mensajes de teclado y de ratn y notifican a las ventanas padres cuando sus estados han cambiado. Ellos liberan al programador de enormes cargas, as que deberas usarlas cada vez que sea posible. En este tutorial las pongo sobre una ventana normal para demostrar cmo puedes crearlas y usarlas, pero en realidad deberas ponerlas en una caja de dilogo. Ejemplos de clases de ventanas predefinidas son el botn, la caja de lista [listbox], la caja de chequeo [checkbox], botn de radio [radio button], edicin [edit] etc. Con el fin de usar el control de vemtana hija, debes crearla con CreateWindow o CreateWindowEx. Nota que no tienes que registrar la clase de ventana puesto que Windows lo hace por t. El parmetro nombre de la clase DEBE ser el nombre de la clase predefinida. Es decir, si quieres crear un botn, debes especificar "button" como nombre de la clase en CreateWindowEx. Los otros parmetros que debes llenar son la agarradera o manejador [handle] de la ventana padre y el ID del control. El ID del control debe ser nico entre los controles. El ID del control es el ID de ese control. Lo usas para diferenciar entre controles. Despus de que el control fue creado, enviar mensajes de notificacin a la ventana padre cuando su estado cambie. Normalmente, creas las ventanas hijas durante el mensaje WM_CREATE de la ventana padre. La ventana hija enva mensajes WM_COMMAND a la ventana padre con su ID de control en la palabra baja de wParam, el cdigo de notificacin en la palabra alta de wParam, y su manejador de ventana en lParam. Cada conrtol de ventana hija tiene su propio cdigo de notificacin, as que debes revisar la referencia de la API de Win32 para ms informacin. Tambin la ventana padre puede enviar rdenes o comandos a la ventana hija, llamando a la funcin SendMessage. Esta funcin enva el mensaje especificado acompaado de otrops valores en wParam y lParam a la ventana especificada por el manejador de ventana. Es una funcin extremadamente til, ya que puede enviar mensajes a cualquier ventana que conozcas su manejador. As que despus de crear ventanas hijas, la ventana padre debe procesar los mensajes WM_COMMAND para poder recibir cdigos de notificacin desde las ventanas hijas. .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data ClassName db "SimpleWinClass",0 AppName db "Our First Window",0 MenuName db "FirstMenu",0 ButtonClassName db "button",0 ButtonText db "My First Button",0 EditClassName db "edit",0 TestString db "Wow! I'm in an edit box now",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? hwndButton HWND ?

SEGUNDO DE ASIR

Pgina 25

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


hwndEdit HWND ? buffer db 512 dup(?) .const ButtonID equ 1 EditID equ 2 IDM_HELLO equ 1 IDM_CLEAR equ 2 IDM_GETTEXT equ 3 IDM_EXIT equ 4 .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine 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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_BTNFACE+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,300,200,NULL,NULL,\ hInst,NULL mov hwnd,eax INVOKE ShowWindow, hwnd,SW_SHOWNORMAL INVOKE UpdateWindow, hwnd .WHILE TRUE INVOKE GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp

SEGUNDO DE ASIR

Pgina 26

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_CREATE invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\ WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\ ES_AUTOHSCROLL,\ 50,35,200,25,hWnd,EditID,hInstance,NULL mov hwndEdit,eax invoke SetFocus, hwndEdit invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\ WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\ 75,70,140,25,hWnd,ButtonID,hInstance,NULL mov hwndButton,eax .ELSEIF uMsg==WM_COMMAND mov eax,wParam .IF lParam==0 .IF ax==IDM_HELLO invoke SetWindowText,hwndEdit,ADDR TestString invoke SendMessage,hwndEdit,WM_KEYDOWN,VK_END,NULL .ELSEIF ax==IDM_CLEAR invoke SetWindowText,hwndEdit,NULL .ELSEIF ax==IDM_GETTEXT invoke GetWindowText,hwndEdit,ADDR buffer,512 invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK .ELSE invoke DestroyWindow,hWnd .ENDIF .ELSE .IF ax==ButtonID shr eax,16 .IF ax==BN_CLICKED invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0 .ENDIF .ENDIF .ENDIF .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end start CONTROL RC #define IDM_HELLO 1 #define IDM_CLEAR 2 #define IDM_GETTEXT 3 #define IDM_EXIT 4 FirstMenu MENU { POPUP "&Test Controls"

SEGUNDO DE ASIR

Pgina 27

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


{ MENUITEM "Say Hello",IDM_HELLO MENUITEM "Clear Edit Box",IDM_CLEAR MENUITEM "Get Text", IDM_GETTEXT MENUITEM SEPARATOR MENUITEM "E&xit",IDM_EXIT } } MAKEFILE NAME=controls $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 28

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

SEGUNDO DE ASIR

Pgina 29

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO9


Veremos como podemos usar una caja de dilogo como programa principal. Si juegas bastante con los ejemplos del tutorial anterior, encontrars que no puedes cambiar el foco de entrada de un control de ventana hija a otra con la tecla Tab. La nica manera de realizar eso es haciendo click sobre el control que deseas que gane el foco de entrada. Esta situacin es ms bien incmoda. Otra cosa que deberas notar es que cambi el color del fondo de la ventana padre a gris en vez de a blanco, como lo haba hecho en los ejemplos previos. Esto se hace as para que el color de la ventana hija pueda armonizar con el color del rea cliente del ventana padre. Hay otra manera de salvar este problema pero no es fcil. Tienes que subclasificar todos los controles de ventana hija en tu ventana padre. La razn de la existencia de tal inconveniente es que los controles de ventana hija estn originalmente diseados para trabajar dentro de cajas de dilogo, no en una ventana normal. Los colores por defecto de los controles de ventanas hijas, como los botones, es gris porque el rea cliente de la caja de dilogo normalmente es gris para que armonicen entre s sin ninguna intervensin por parte del programador. Antes de entrar en detalles, deberamos saber qu es una caja de dilogo. Una caja de dilogo no es ms que una ventana normal diseada para trabajar con controles de ventanas hijas. Windows tambin proporciona un administrador interno de cajas de dilogo ["dialog box manager"] responsable por gran parte de la lgica del teclado tal como desplazamiento del foco de entrada cuando el ususario presiona Tab, presionar el botn por defecto si la tecla Enter es presionada, etc; as los programadores pueden ocuparse de tareas de ms alto nivel. Las cajas de dilogo son usadas primero como dispositivos de entrada/salida. Como tal, una caja de dilogo puede ser considerada como una "caja negra" de entrada/salida lo que siginifica que no tienes que saber cmo funciona internamente una caja de dilogo para usarla, slo tienes que saber cmo interactuar con ella. Es un principio de la programacin orientada a objetos [object oriented programming (OOP)] llamado encapsulacin u ocultamiento de la informacin. Si la caja negra es *perfectamente* diseada , el usuario puede emplarla sin tener conocimiento de cmo funciona. Lo nico es que la caja negra debe ser perfecta, algo difcil de alcanzar en el mundo real. La API de Win32 API tambin ha sido diseada como una caja negra. Bien, parece que nos hemos alejado de nuestro camino. Regresemos a nuestro tema. Las cajas de dilogo han sido diseadas para reducir la carga de trabajo del programador. Normalmente si tienes que poner controles de ventanas hijas sobre una ventana normal, tienes que subclasificarlas y escribir t mismo la lgica del teclado. Pero si quieres ponerlas en una caja de dilogo, Windows manejar la lgica por t. Slo tienes que saber cmo obtener la entrada del usuario de la caja de dilogo o como enviar rdenes a ella. Como el men, una caja de dilogo se define como un recurso. Escribes un plantilla describiendo las caractersticas de la caja de dilogo y sus controles y luego compilas el guin de recursos con un compilador de recursos. Nota que todos los recursos se encuentran en el mismo archivo de guin de recursos. Puedes emplear cualquier editor de texto para escribir un guin de recursos, pero no lo recomiendo. Deberas usar un editor de recursos para hacer la tarea visualmente ya que arreglar la disposicin de los controles en la caja de dilgo es una tarea dura de hacer manualmente. Hay disponibles algunos excelentes editores de recursos. Muchos de las grandes suites de compiladores incluyen sus propios editores de recursos. Puedes usar cualquiera para crear un guin de recursos para tu programa y luego cortar las lneas irrelevantes tales como las relacionadas con MFC. Hay dos tipos principales de cajas de dilogo: modal y no-modal. Una caja de dilogo no-modal te deja cambiar de foco hacia otra ventana. Un ejempo es el dilogo Find de MS Word. Hay dos subtipos de caja de dilogo modal: modal de aplicacin y modal de sistema. Una caja de dilogo modal de aplicacin no permite cambiar el foco a otra ventana en la misma aplicacin sino cambiar el foco de entrada a la ventana de OTRA aplicacin. Una caja de dilogo modal de sistema no te permite cambiar de foco hacia otra ventana hasta que respondas a la primera. Una caja de dilogo no-modal se crea llamando a la funcin de la API CreateDialogParam. Una caja de dilogo modal se crea llamando a DialogBoxParam. La nica diferencia entre una caja de dilogo de no-modal y una modal de sistema es el estilo DS_SYSMODAL. Si quieres incluir el estilo DS_SYSMODAL en una plantilla de caja de dilogo, esa caja de dilogo ser modal de sistema. .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

SEGUNDO DE ASIR

Pgina 30

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data ClassName db "DLGCLASS",0 MenuName db "MyMenu",0 DlgName db "MyDialog",0 AppName db "Our First Dialog Box",0 TestString db "Wow! I'm in an edit box now",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? buffer db 512 dup(?) .const IDC_EDIT equ 3000 IDC_BUTTON equ 3001 IDC_EXIT equ 3002 IDM_GETTEXT equ 32000 IDM_CLEAR equ 32001 IDM_EXIT equ 32002 .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine 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 hDlg:HWND mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,DLGWINDOWEXTRA push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_BTNFACE+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc invoke CreateDialogParam,hInstance,ADDR DlgName,NULL,NULL,NULL

SEGUNDO DE ASIR

Pgina 31

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


mov hDlg,eax invoke GetDlgItem,hDlg,IDC_EDIT invoke SetFocus,eax INVOKE ShowWindow, hDlg,SW_SHOWNORMAL INVOKE UpdateWindow, hDlg .WHILE TRUE INVOKE GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke IsDialogMessage, hDlg, ADDR msg .if eax==FALSE INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .endif .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .if uMsg==WM_CREATE invoke SetDlgItemText,hWnd,IDC_EDIT,ADDR AppName .ELSEIF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam .IF lParam==0 .IF ax==IDM_GETTEXT invoke GetDlgItemText,hWnd,IDC_EDIT,ADDR buffer,512 invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK .ELSEIF ax==IDM_CLEAR invoke SetDlgItemText,hWnd,IDC_EDIT,NULL .ELSE invoke DestroyWindow,hWnd .ENDIF .ELSE mov edx,wParam shr edx,16 .IF dx==BN_CLICKED .IF ax==IDC_BUTTON invoke SetDlgItemText,hWnd,IDC_EDIT,ADDR TestString .ELSEIF ax==IDC_EXIT invoke SendMessage,hWnd,WM_COMMAND,IDM_EXIT,0 .ENDIF .ENDIF .ENDIF .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end start #include "resource.h"

SEGUNDO DE ASIR

Pgina 32

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

#define IDC_EDIT #define IDC_BUTTON #define IDC_EXIT #define IDM_GETTEXT #define IDM_CLEAR #define IDM_EXIT

3000 3001 3002 32000 32001 32003

DIALOG MyDialog DIALOG 10, 10, 205, 60 STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK CAPTION "Our First Dialog Box" CLASS "DLGCLASS" BEGIN EDITTEXT IDC_EDIT, 15,17,111,13, ES_AUTOHSCROLL | ES_LEFT |WS_TABSTOP DEFPUSHBUTTON "Say Hello", IDC_BUTTON, 141,10,52,13 PUSHBUTTON "E&xit", IDC_EXIT, 141,26,52,13 END

MyMenu MENU BEGIN POPUP "Test Controls" BEGIN MENUITEM "Get Text", IDM_GETTEXT MENUITEM "Clear Text", IDM_CLEAR MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/ MENUITEM "E&xit", IDM_EXIT END END MAKEFILE NAME=dialog $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /VERSION:4.0 /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 33

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

SEGUNDO DE ASIR

Pgina 34

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO10


Especificamente, vamos a explorar la manera de como usar cajas de dilogo como nuestra entrada-salida de datos. Si leste el tutorial anterior, este te va a resultar ligero. Encontrars algunos cambios menores, es todo lo que necesitamos para poder usar cajas de dilogo adjuntas a nuestra ventana principal. En este tutorial tambin aprenderemos como usar cajas de dilogo comunes Hay muy poco que decir sobre como usar las cajas de dilogo como entrada-salida de nuestro programa. Tu programa crea la pgina principal normalmente y cuando quieres mostrar la cajas de dilogo, llamas a CreateDialogParam o DialogBoxParam. Con la llamada a DialogBoxParam, no tendrs que hacer nada mas, slo procesar los mensajes en el procedimiento de la cajas de dilogo. Con CreateDialogParam, tendrs que insertar la llamada a IsDialogMessage en el bucle de mensajes para dejar a la cajas de dilogo el control sobre la navegacin del teclado en tu cajas de dilogo. Como los dos casos son diferentes, no pondr el codigo fuente aqu. Puedes bajarte los ejemplos y examinarlos tu mismo, aqu y aqu. Comencemos con las cajas de dilogo comunes. Windows tiene preperadas unas cajas de dilogo predefinidas que pueden ser usadas por tus aplicaciones. Estas cajas de dilogo existen para proveer un interfaz estandard de usuario. Consisten en cajas de dilogo de archivo, impresin, color, fuente, y busqueda. Deberas usarlas lo mximo posible. Las cajas de dilogo residen en comdlg32.dll. Para usarlas, tendrs que enlazar [link] el archivo comdlg32.lib. Creas estas cajas de dilogo llamando a la funcin apropiada en la librera de las cajas de dilogo. Para el archivo de dilogo "Abrir" [Open], se emplea la funcin GetOpenFileName, para la caja de dilgo "Guardar" [Save] GetSaveFileName, para dibujar un dilogo es PrintDlg y ya est. Cada una de estas funciones toma como parmetro un puntero a la estructura. Debers mirarlo en la referencia de la API de Win32. En este tutorial, demostrar como crear y usar un dilogo "Abrir archivo" [Open file]. .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib WinMain proto :DWORD,:DWORD,:DWORD,:DWORD DlgProc PROTO :HWND, :DWORD, :DWORD, :DWORD .data ClassName db "SimpleWinClass",0 AppName db "Our Main Window",0 MenuName db "FirstMenu",0 DlgName db "MyDialog",0 TestString db "Hello, everybody",0 hwndDlg dd 0 ; Handle to the dialog box .data? hInstance HINSTANCE ? CommandLine LPSTR ? .const IDM_EXIT equ 1 IDM_ABOUT equ 2 IDC_EDIT equ 3000 IDC_BUTTON equ 3001 IDC_EXIT equ 3002

SEGUNDO DE ASIR

Pgina 35

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


.code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine 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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,300,200,NULL,NULL,\ hInst,NULL mov hwnd,eax INVOKE ShowWindow, hwnd,SW_SHOWNORMAL INVOKE UpdateWindow, hwnd .WHILE TRUE INVOKE GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) .if hwndDlg!=0 invoke IsDialogMessage,hwndDlg,ADDR msg .if eax==TRUE .continue .endif .endif INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam

SEGUNDO DE ASIR

Pgina 36

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


.if ax==IDM_ABOUT invoke CreateDialogParam,hInstance, addr DlgName,hWnd,OFFSET DlgProc,NULL mov hwndDlg,eax .else invoke DestroyWindow, hWnd .endif .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp

DlgProc PROC hWnd:HWND,iMsg:DWORD,wParam:WPARAM, lParam:LPARAM .if iMsg==WM_INITDIALOG invoke GetDlgItem,hWnd,IDC_EDIT invoke SetFocus,eax .elseif iMsg==WM_CLOSE invoke EndDialog,hWnd,NULL mov hwndDlg,0 .elseif iMsg==WM_COMMAND mov eax,wParam mov edx,eax shr edx,16 .if dx==BN_CLICKED .if eax==IDC_EXIT invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL .elseif eax==IDC_BUTTON invoke SetDlgItemText,hWnd,IDC_EDIT,ADDR TestString .endif .endif .else mov eax,FALSE ret .endif mov eax,TRUE ret DlgProc endp end start
DIALOG.RC // constants for dialog box #define IDC_EDIT 3000 #define IDC_BUTTON 3001 #define IDC_EXIT 3002 #define DS_CENTER 0x0800L #define DS_CENTER 0x0800L #define WS_MINIMIZEBOX 0x00020000L #define WS_SYSMENU 0x00080000L #define WS_VISIBLE 0x10000000L #define WS_OVERLAPPED 0x00000000L #define DS_MODALFRAME 0x80L #define DS_3DLOOK 0x0004L

SEGUNDO DE ASIR

Pgina 37

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


#define WS_CAPTION 0xC00000L #define ES_AUTOHSCROLL 0x80L #define ES_LEFT 0 // Constants for menu #define IDM_EXIT 1 #define IDM_ABOUT 2 FirstMenu MENU { POPUP "&File" { MENUITEM "E&xit",IDM_EXIT } MENUITEM "About",IDM_ABOUT }

MyDialog DIALOG 10, 10, 205, 60 STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK CAPTION "Our Second Dialog Box" BEGIN EDITTEXT IDC_EDIT, 15,17,111,13, ES_AUTOHSCROLL | ES_LEFT DEFPUSHBUTTON "Say Hello", IDC_BUTTON, 141,10,52,13 PUSHBUTTON "E&xit", IDC_EXIT, 141,26,52,13 END MAKEFILE NAME=dialog $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 38

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

SEGUNDO DE ASIR

Pgina 39

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO10B


.386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\comdlg32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\comdlg32.lib .const IDM_OPEN equ 1 IDM_EXIT equ 2 MAXSIZE equ 260 OUTPUTSIZE equ 512 .data ClassName db "SimpleWinClass",0 AppName db "Our Main Window",0 MenuName db "FirstMenu",0 ofn OPENFILENAME <> FilterString db "All Files",0,"*.*",0 db "Text Files",0,"*.txt",0,0 buffer db MAXSIZE dup(0) OurTitle db "-=Our First Open File Dialog Box=-: Choose the file to open",0 FullPathName db "The Full Filename with Path is: ",0 FullName db "The Filename is: ",0 ExtensionName db "The Extension is: ",0 OutputString db OUTPUTSIZE dup(0) CrLf db 0Dh,0Ah,0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine 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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc

SEGUNDO DE ASIR

Pgina 40

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,300,200,NULL,NULL,\ hInst,NULL mov hwnd,eax INVOKE ShowWindow, hwnd,SW_SHOWNORMAL INVOKE UpdateWindow, hwnd .WHILE TRUE INVOKE GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam .if ax==IDM_OPEN mov ofn.lStructSize,SIZEOF ofn push hWnd pop ofn.hWndOwner push hInstance pop ofn.hInstance mov ofn.lpstrFilter, OFFSET FilterString mov ofn.lpstrFile, OFFSET buffer mov ofn.nMaxFile,MAXSIZE mov ofn.Flags, OFN_FILEMUSTEXIST or \ OFN_PATHMUSTEXIST or OFN_LONGNAMES or\ OFN_EXPLORER or OFN_HIDEREADONLY mov ofn.lpstrTitle, OFFSET OurTitle invoke GetOpenFileName, ADDR ofn .if eax==TRUE invoke lstrcat,offset OutputString,OFFSET FullPathName invoke lstrcat,offset OutputString,ofn.lpstrFile invoke lstrcat,offset OutputString,offset CrLf invoke lstrcat,offset OutputString,offset FullName mov eax,ofn.lpstrFile

SEGUNDO DE ASIR

Pgina 41

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


push ebx xor ebx,ebx mov bx,ofn.nFileOffset add eax,ebx pop ebx invoke lstrcat,offset OutputString,eax invoke lstrcat,offset OutputString,offset CrLf invoke lstrcat,offset OutputString,offset ExtensionName mov eax,ofn.lpstrFile push ebx xor ebx,ebx mov bx,ofn.nFileExtension add eax,ebx pop ebx invoke lstrcat,offset OutputString,eax invoke MessageBox,hWnd,OFFSET OutputString,ADDR AppName,MB_OK invoke RtlZeroMemory,offset OutputString,OUTPUTSIZE .endif .else invoke DestroyWindow, hWnd .endif .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end start OPEN.RC // Constants for menu #define IDM_OPEN 1 #define IDM_EXIT 2 FirstMenu MENU { POPUP "&File" { MENUITEM "&Open",IDM_OPEN MENUITEM SEPARATOR MENUITEM "E&xit",IDM_EXIT } } MAKEFILE NAME=open $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm

SEGUNDO DE ASIR

Pgina 42

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 43

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO11


Crearemos un programa para manejar la memoria rudimentariamente y las operaciones de entrada/salida de archivos. Adicionalmente usaremos cajas de dilogo comunes como instrumento de entrada-salida El manejo de la memoria bajo Win32 desde el punto de vista de las aplicaciones es un poco simple y directo. Cada proceso usa un espacio de 4 GB de dirrecciones de memoria. El modelo de memoria usado se llama modelo de memoria plana [flat]. En este modelo, todos los segmentos de registro (o selectores) direccionan a la misma localidad de memoria y el desplazamiento [offset] es de 32-bit. Tambien las aplicaciones pueden acceder a la memoria en cualquier punto en su espacio de direcciones sin necesidad de cambiar el valor de los selectores. Esto simplifica mucho el manejo de la memoria. No hay mas puntos "near" (cerca) o "far" (lejos). Bajo Win16, hay dos categoras principales de funciones de la API de memoria: Global y Local. Las de tipo Global tienen que ver con la memoria situada en diferentes segmentos, por eso hay funciones para memoria "far" (lejana). Lasfunciones de la API de tipo Local tienen que ver con un motculo [heap] de memoria local del proceso as que son las funciones de memoria "near" (cercana). Bajo Win32, estos dos tipos son uno y le mismo tipo. tendrs el mismo resultado si llamas a GlobalAlloc o LocalAlloc. Los pasos para ubicar y usar la memoria son los siguientes: 1. Ubicar el bloque de memoria llamando a GlobalAlloc. Esta funcin devuelve un manejador (handle) al bloque de memoria pedido. 2. "Bloquear" [lock] el bloque de memoria llamando a GlobalLock. Esta funcin acepta un manejador (handle) al bloque de memoria y devuelve un puntero al bloque de memoria. 3. Puedes usar el puntero para leer o escribir en la memoria. 4. Desbloquear [unlock] el bloque de memoria llamando a GlobalUnlock . Esta funcin invalida el puntero al bloque de memoria. 5. Liberar el bloque de memoria llamando a GlobalFree. Esta funcin acepta un manejador (handle) al bloque de memoria. Puedes sustituir "Global" por "Local" en LocalAlloc, LocalLock,etc. El mtodo de arriba puede simplificarse radicalmente usando el flag GMEM_FIXED en la llamada a GlobalAlloc. Si usas esta bandera [flag], El valor de retorno de Global/LocalAlloc ser el puntero al bloque de memoria reservado, no el manejador (handle). No tienes que llamar a Global/LocalLock y puedes pasar el puntero a Global/LocalFree sin llamar primero a Global/LocalUnlock. Pero en este tutorial, usar el modo "tradicional" ya que te lo puedes encontrar cuando leas el cdigo de otros programas. La E/S de archivos bajo Win32 tiene una semblanza ms notable que la de bajo DOS. Los pasos a seguir son los mismos. Slo tienes que cambiar las interrupciones por llamadas a la API y ya est. Los pasos requeridos son los siguientes: 1. Abrir o Crear el archivo llamando a la funcin CreateFile. Esta funcin es muy verstil: aadiendo a los archivos, puede abrir puertos de comunicacin, tuberas [pipes], dipositivos de discos. Cuando es correcto, devuelve un manejador (handle) al archivo o dispositivo. Entonces puedes usar este manejador (handle) para llevar a cabo operaciones en el archivo o dispositivo. Mueve el puntero a la posicin deseada llamando a SetFilePointer. Realiza la operacin de lectura o escritura llamando a ReadFile o WriteFile. Estas funciones transfieren datos desde un bloque de memoria hacia o desde un archivo. As que tendrs que reservar un bloque de memoria suficientemente grande para alojar los datos. Cierra el archivo llamando a CloseHandle. Esta funcin acepta el manejador (handle) de archivo.

2.

3.

.386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc

SEGUNDO DE ASIR

Pgina 44

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


include \masm32\include\kernel32.inc include \masm32\include\comdlg32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\comdlg32.lib .const IDM_OPEN equ 1 IDM_SAVE equ 2 IDM_EXIT equ 3 MAXSIZE equ 260 MEMSIZE equ 65535 EditID equ 1 .data ClassName db "Win32ASMEditClass",0 AppName db "Win32 ASM Edit",0 EditClass db "edit",0 MenuName db "FirstMenu",0 ofn OPENFILENAME <> FilterString db "All Files",0,"*.*",0 db "Text Files",0,"*.txt",0,0 buffer db MAXSIZE dup(0) .data? hInstance HINSTANCE ? CommandLine LPSTR ? hwndEdit HWND ? hFile HANDLE ? hMemory HANDLE ? pMemory DWORD ? SizeReadWrite DWORD ? .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine 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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName

SEGUNDO DE ASIR

Pgina 45

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,300,200,NULL,NULL,\ hInst,NULL mov hwnd,eax INVOKE ShowWindow, hwnd,SW_SHOWNORMAL INVOKE UpdateWindow, hwnd .WHILE TRUE INVOKE GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc uses ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_CREATE INVOKE CreateWindowEx,NULL,ADDR EditClass,NULL,\ WS_VISIBLE or WS_CHILD or ES_LEFT or ES_MULTILINE or\ ES_AUTOHSCROLL or ES_AUTOVSCROLL,0,\ 0,0,0,hWnd,EditID,\ hInstance,NULL mov hwndEdit,eax invoke SetFocus,hwndEdit mov ofn.lStructSize,SIZEOF ofn push hWnd pop ofn.hWndOwner push hInstance pop ofn.hInstance mov ofn.lpstrFilter, OFFSET FilterString mov ofn.lpstrFile, OFFSET buffer mov ofn.nMaxFile,MAXSIZE .ELSEIF uMsg==WM_SIZE mov eax,lParam mov edx,eax shr edx,16 and eax,0ffffh invoke MoveWindow,hwndEdit,0,0,eax,edx,TRUE .ELSEIF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam .if lParam==0 .if ax==IDM_OPEN mov ofn.Flags, OFN_FILEMUSTEXIST or \ OFN_PATHMUSTEXIST or OFN_LONGNAMES or\

SEGUNDO DE ASIR

Pgina 46

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


OFN_EXPLORER or OFN_HIDEREADONLY invoke GetOpenFileName, ADDR ofn .if eax==TRUE invoke CreateFile,ADDR buffer,\ GENERIC_READ or GENERIC_WRITE ,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,\ NULL mov hFile,eax invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE mov hMemory,eax invoke GlobalLock,hMemory mov pMemory,eax invoke ReadFile,hFile,pMemory,MEMSIZE-1,ADDR SizeReadWrite,NULL invoke SendMessage,hwndEdit,WM_SETTEXT,NULL,pMemory invoke CloseHandle,hFile invoke GlobalUnlock,pMemory invoke GlobalFree,hMemory .endif invoke SetFocus,hwndEdit .elseif ax==IDM_SAVE mov ofn.Flags,OFN_LONGNAMES or\ OFN_EXPLORER or OFN_HIDEREADONLY invoke GetSaveFileName, ADDR ofn .if eax==TRUE invoke CreateFile,ADDR buffer,\ GENERIC_READ or GENERIC_WRITE ,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ NULL,CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,\ NULL mov hFile,eax invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE mov hMemory,eax invoke GlobalLock,hMemory mov pMemory,eax invoke SendMessage,hwndEdit,WM_GETTEXT,MEMSIZE1,pMemory invoke WriteFile,hFile,pMemory,eax,ADDR SizeReadWrite,NULL invoke CloseHandle,hFile invoke GlobalUnlock,pMemory invoke GlobalFree,hMemory .endif invoke SetFocus,hwndEdit .else invoke DestroyWindow, hWnd .endif .endif .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF

SEGUNDO DE ASIR

Pgina 47

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


xor eax,eax ret WndProc endp end start FILE.RC // Constants for menu #define IDM_OPEN 1 #define IDM_SAVE 2 #define IDM_EXIT 3 FirstMenu MENU { POPUP "&File" { MENUITEM "&Open",IDM_OPEN MENUITEM "&Save As",IDM_SAVE MENUITEM SEPARATOR MENUITEM "E&xit",IDM_EXIT } } MAKEFILE NAME=file $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm

EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 48

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

SEGUNDO DE ASIR

Pgina 49

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO12


Si examinas detenidamente el ejemplo del tutorial previo, encontrars que tiene un serio inconveniente: qu pasa si el archivo que quieres leer es ms grande que el bloque de memoria localizado? o qu si la cadena que quieres buscar es cortada por la mitad al final del bloque de memoria? La respuesta tradicional para la primera cuestin es que deberas leer repetidas veces en los datos desde el inicio del archivo hasta que encuentres el final del archivo. La respuesta para la segunda cuestin es que deberas prepararte para el caso especial al final del bloque de memoria. Esto es lo que se llama el problema del valor del lmite. Presenta terribles dolores de cabeza a los programadores y causa innumerables errores [bugs]. Sera agradable localizar un bloque de memoria, lo suficientemente grande para almacenar todo el archivo pero nuestro programa debera ser abundante en recursos. Proyeccin de archivo al ataque. Al usar proyeccin de archivo, puedes pensar en todo el archivo como si estuviera ya cargado en la memoria y puedes usar un puntero a la memoria para leer o escribir datos desde el archivo. Tan fcil como eso. No necesitas usar las funciones de memoria de la API y separar ms las funciones de la API para E/S de archivo, todas ellas son una y la misma bajo proyeccin de archivo. La proyeccin de archivos tambin es usada como un medio de compartir memoria entre los archivos. Al usar proyeccin de archivos de esta manera, no hay involucrados archivos reales. Es ms como un bloque de memoria reservado que todo proceso puede *ver*. Pero compartir datos entre procesos es un asunto delicado, no para ser tratado ligeramente. Tienes que implementar sincronizacin de procesos y de hilos, sino tus aplicaciones se quebrarn [crash] en un orden muy corto. No tocaremos el tema de los archivos proyectados como un medio de crear una memoria compartida en este tutorial. Nos concentraremos en cmo usar el archivo proyectado como medio para "proyectar" un archivo en memoria. En realidad, el cargador de archivos PE usa proyeccin de archivo para cargar archivos ejecutables en memoria. Es muy conveniente ya que slo las partes pueden ser ledas selectivamente desde el archivo en disco. Bajo Win32, deberas usar proyeccin de archivos cada vez que fuera posible. Sin embargo, hay algunas limitaciones al emplear archivos proyectados en memoria. Una vez que creas un archivo proyectado en memoria, su tamao no puede ser cambiado durante esa seccin. As que proyectar archivos es muy bueno para archivos de slo lectura u operaciones de archivos que no afecten el tamao del archivo. Eso no significa que no puedes usar proyeccin de archivo si quieres incrementar el tamao del archivo. Puedes estimar el nuevo tamao y crear archivos proyectados en memoria basados en el nuevo tamao y el archivo se incrementar a ese tamao. Esto es muy conveniente, eso es todo. Suficiente para la explicacin. Vamos a zambullirnos dentro de la implemantacin de la proyeccin de archivos. Con el fin de usar proyeccin de archivos, deben seguirse los siguientes pasos: 1. llamar CreateFile para abrir el archivo que quieres proyectar. 2. llamar CreateFileMapping con el manejador de archivo regresado por CreateFile como uno de sus parmetros. Esta funcin crea un objeto de archivo proyectado a partir del archivo abierto por CreateFile. 3. llamar a MapViewOfFile para proyectar una regin del archivo seleccionado o el archivo completo a memoria. Esta funcin regresa un puntero al primer byte de la regin proyectada del archivo. 4. Usar el puntero para leer o escribir el archivo 5. llamar UnmapViewOfFile para des-proyectar el archivo. 6. llamar a CloseHandle con el manejador del archivo proyectado como parmetro para cerrar el archivo proyectado. 7. llamar CloseHandle de nuevo, esta vez con el manejador regresado por CreateFile para cerrar el archivo actual.

.386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc

SEGUNDO DE ASIR

Pgina 50

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\comdlg32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\comdlg32.lib .const IDM_OPEN equ 1 IDM_SAVE equ 2 IDM_EXIT equ 3 MAXSIZE equ 260 .data ClassName db "Win32ASMFileMappingClass",0 AppName db "Win32 ASM File Mapping Example",0 MenuName db "FirstMenu",0 ofn OPENFILENAME <> FilterString db "All Files",0,"*.*",0 db "Text Files",0,"*.txt",0,0 buffer db MAXSIZE dup(0) hMapFile HANDLE 0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? hFileRead HANDLE ? hFileWrite HANDLE ? hMenu HANDLE ? pMemory DWORD ? SizeWritten DWORD ? .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine 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 or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName

SEGUNDO DE ASIR

Pgina 51

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,300,200,NULL,NULL,\ hInst,NULL mov hwnd,eax invoke ShowWindow, hwnd,SW_SHOWNORMAL invoke UpdateWindow, hwnd .WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_CREATE invoke GetMenu,hWnd mov hMenu,eax mov ofn.lStructSize,SIZEOF ofn push hWnd pop ofn.hWndOwner push hInstance pop ofn.hInstance mov ofn.lpstrFilter, OFFSET FilterString mov ofn.lpstrFile, OFFSET buffer mov ofn.nMaxFile,MAXSIZE .ELSEIF uMsg==WM_DESTROY .if hMapFile!=0 call CloseMapFile .endif invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam .if lParam==0 .if ax==IDM_OPEN mov ofn.Flags, OFN_FILEMUSTEXIST or \ OFN_PATHMUSTEXIST or OFN_LONGNAMES or\ OFN_EXPLORER or OFN_HIDEREADONLY invoke GetOpenFileName, ADDR ofn .if eax==TRUE invoke CreateFile,ADDR buffer,\ GENERIC_READ ,\ 0,\ NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,\ NULL mov hFileRead,eax

SEGUNDO DE ASIR

Pgina 52

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


invoke CreateFileMapping,hFileRead,NULL,PAGE_READONLY,0,0,NULL mov hMapFile,eax mov eax,OFFSET buffer movzx edx,ofn.nFileOffset add eax,edx invoke SetWindowText,hWnd,eax invoke EnableMenuItem,hMenu,IDM_OPEN,MF_GRAYED invoke EnableMenuItem,hMenu,IDM_SAVE,MF_ENABLED .endif .elseif ax==IDM_SAVE mov ofn.Flags,OFN_LONGNAMES or\ OFN_EXPLORER or OFN_HIDEREADONLY invoke GetSaveFileName, ADDR ofn .if eax==TRUE invoke CreateFile,ADDR buffer,\ GENERIC_READ or GENERIC_WRITE ,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ NULL,CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,\ NULL mov hFileWrite,eax invoke MapViewOfFile,hMapFile,FILE_MAP_READ,0,0,0 mov pMemory,eax invoke GetFileSize,hFileRead,NULL invoke WriteFile,hFileWrite,pMemory,eax,ADDR SizeWritten,NULL invoke UnmapViewOfFile,pMemory call CloseMapFile invoke CloseHandle,hFileWrite invoke SetWindowText,hWnd,ADDR AppName invoke EnableMenuItem,hMenu,IDM_OPEN,MF_ENABLED invoke EnableMenuItem,hMenu,IDM_SAVE,MF_GRAYED .endif .else invoke DestroyWindow, hWnd .endif .endif .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp CloseMapFile PROC invoke CloseHandle,hMapFile mov hMapFile,0 invoke CloseHandle,hFileRead ret CloseMapFile endp end start FILEMAP.RC

SEGUNDO DE ASIR

Pgina 53

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

// Constants for menu #define IDM_OPEN 1 #define IDM_SAVE 2 #define IDM_EXIT 3 FirstMenu MENU { POPUP "&File" { MENUITEM "&Open",IDM_OPEN MENUITEM "&Save As",IDM_SAVE, GRAYED MENUITEM SEPARATOR MENUITEM "E&xit",IDM_EXIT } } MAKEFILE NAME=filemap $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm

EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 54

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012

SEGUNDO DE ASIR

Pgina 55

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO13


qu es un proceso, cmo crearlo y cmo terminarlo "Un proceso es una aplicacin en ejecucin que consiste en un espacio de direcciones privado, cdigo, datos, y otros recursos del sistema operativo, tales como archivos, tuberas, y objetos de sincronizacin que son visibles al proceso." Cmo puedes ver, un proceso "se apropia" de algunos objetos: el espacio de direcciones, el mdulo ejecutante o los mdulos, y cualquier cosa que el mdulo ejecutante pueda crear o abrir. Al menos, un proceso debe consistir en un mdulo ejecutable, un espacio de direcciones privado y un hilo. Todo proceso debe tener por lo menos un hilo. Qu es un hilo? Un hilo es realmente una cola o flujo de ejecucin. Cuando Windows crea un proceso, crea slo un hilo para el proceso. Este hilo generalmente inicia la ejecucin desde la primera instruccin en el mdulo. Si el proceso luego necesita ms hilos, puede crearlos explcitamente. Cuando Windows recibe la orden de crear un proceso, crea un espacio de direcciones privado para el proceso y luego proyecta el archivo ejecutable en la memoria de ese proceso. Despus de eso crea el hilo primario del proceso. .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .const IDM_CREATE_PROCESS equ 1 IDM_TERMINATE equ 2 IDM_EXIT equ 3 .data ClassName db "Win32ASMProcessClass",0 AppName db "Win32 ASM Process Example",0 MenuName db "FirstMenu",0 processInfo PROCESS_INFORMATION <> programname db "msgbox.exe",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? hMenu HANDLE ? ExitCode DWORD ? .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

SEGUNDO DE ASIR

Pgina 56

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,300,200,NULL,NULL,\ hInst,NULL mov hwnd,eax invoke ShowWindow, hwnd,SW_SHOWNORMAL invoke UpdateWindow, hwnd invoke GetMenu,hwnd mov hMenu,eax .WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL startInfo:STARTUPINFO .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_INITMENUPOPUP invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode .if eax==TRUE .if ExitCode==STILL_ACTIVE invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_GRAYED invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_ENABLED .else invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_ENABLED invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_GRAYED .endif .else invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_ENABLED invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_GRAYED

SEGUNDO DE ASIR

Pgina 57

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


.endif .ELSEIF uMsg==WM_COMMAND mov eax,wParam .if lParam==0 .if ax==IDM_CREATE_PROCESS .if processInfo.hProcess!=0 invoke CloseHandle,processInfo.hProcess mov processInfo.hProcess,0 .endif invoke GetStartupInfo,ADDR startInfo invoke CreateProcess,ADDR programname,NULL,NULL,NULL,FALSE,\ NORMAL_PRIORITY_CLASS,\ NULL,NULL,ADDR startInfo,ADDR processInfo invoke CloseHandle,processInfo.hThread .elseif ax==IDM_TERMINATE invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode .if ExitCode==STILL_ACTIVE invoke TerminateProcess,processInfo.hProcess,0 .endif invoke CloseHandle,processInfo.hProcess mov processInfo.hProcess,0 .else invoke DestroyWindow,hWnd .endif .endif .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end start PROCESS.RC // Constants for menu #define IDM_CREATE_PROCESS 1 #define IDM_TERMINATE 2 #define IDM_EXIT 3 FirstMenu MENU { POPUP "&Process" { MENUITEM "&Create Process",IDM_CREATE_PROCESS MENUITEM "&Terminate Process",IDM_TERMINATE MENUITEM SEPARATOR MENUITEM "E&xit",IDM_EXIT } } MAKEFILE NAME=process

SEGUNDO DE ASIR

Pgina 58

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


$(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 59

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO14


Crearemos un programa multihilos [multithreading program]. En el tutorial previo, aprendiste que un proceso consta de al menos un hilo [thread]: el hilo primario. Un hilo es una cadena de ejecucin. tambin puedes crear hilos adicionales en tu programa. Puedes concebir la programacin multihilos [multithreading programming] como una programacin multitareas [multitasking programming] dentro de un mismo programa. En trminos de implementacin, un hilo es una funcin que corre concurrentemente con el hilo principal. Puedes correr varias instancias de la misma funcin o puedes correr varias funciones simultneamente dependiendo de tus requerimientos. La programacin multihilos es especfica de Win32, no existe una contraparte en Win16. Los hilos corren en el mismo proceso, as que ellos pueden acceder a cualquiera de sus recursos tal como variables globales, manejadores etc. Sin embargo, cada hilo tiene su pila [stack] propia, as que las variables locales en cada hilo son privadas. Cada hilo tambin es propietario de su grupo de registros privados, as que cuando Windows conmuta a otros hilos, el hilo puede "recordar" su ltimo estado y puede "resumir" la tarea cuando gana el control de nuevo. Esto es manejado internamente por Windows. Podemos dividir los hilos en dos categoras: 1. Hilo de interface de usuario: Este tipo de hilo crea su propia ventana, y as recibe mensajes de ventana. Puede responder al usuario a travs de su propia ventana. Este tipo de hilo est sujeto a la regla del Mutex de Win16 que permite slo un hilo de interface de usuario en el ncleo de usuario y gdi de 16bit. Mientras el hilo de interface de usuario est ejecutando cdigo de ncleo de usuario y gdi de 16-bit, otros hilos UI no podrn usar los servicios del ncleo de usuario y gdi. Nota que este Mutex de Win16 es especfico a Windows 95 desde su interior, pues las funciones de la API de Windows 95 se remontan [thunk down] hasta el cdigo de 16-bit. Windows NT no tiene Mutex de Win16 as que los hilos de interface de usuario bajo NT trabajan con ms fluidez que bajo Windows 95. 2. Hilo obrero [Worker thread]: Este tipo de hilo no crea ninguna ventana as que no puede recibir ningn mensaje de ventana. Existe bsicamente para hacer la tarea asignada en el trasfondo hence el nombre del hilo obrero. Recomiendo la siguiente estrategia cuando se use la capacidad multihilo de Win32: Dejar que el hilo primario haga de interface de usuario y los otros hilos hagan el trabajo duro en el trasfondo. De esta manera, el hilo primario es como un Gobernador, los otros hilos son como el equipo del gobernador [Governor's staff]. El Gobernador delega tareas a su equipo mientras mantiene contacto con el pblico. El equipo del Gobernador ejecuta con obediencia el trabajo y lo reporta al Gobernador. Si el Gobernador fuera a realizar todas las tareas por s mismo, el no podra atender bien al pblico ni a la prensa. Esto sera parecido a una ventana que est realizando una tarea extensa en su hilo primario: no responde al usuario hasta que la tarea ha sido completada. Este programa podra beneficiarse con la creacin de un hilo adicional que sera el respondable de la extensa tarea, permitiendo al hilo primario responder a las rdenes del usuario.

.386 .model flat,stdcall option casemap:none WinMain proto :DWORd,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .const IDM_CREATE_THREAD equ 1 IDM_EXIT equ 2 WM_FINISH equ WM_USER+100h .data ClassName db "Win32ASMThreadClass",0

SEGUNDO DE ASIR

Pgina 60

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


AppName db "Win32 ASM MultiThreading Example",0 MenuName db "FirstMenu",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? hMenu HANDLE ? ExitCode DWORD ? hwnd HANDLE ? ThreadID DWORD ? .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 mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,300,200,NULL,NULL,\ hInst,NULL mov hwnd,eax invoke ShowWindow, hwnd,SW_SHOWNORMAL invoke UpdateWindow, hwnd invoke GetMenu,hwnd mov hMenu,eax .WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW

SEGUNDO DE ASIR

Pgina 61

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam .if lParam==0 .if ax==IDM_CREATE_THREAD mov eax,OFFSET ThreadProc invoke CreateThread,NULL,NULL,eax,\ NULL,NORMAL_PRIORITY_CLASS,\ ADDR ThreadID invoke CloseHandle,eax .else invoke DestroyWindow,hWnd .endif .endif .ELSEIF uMsg==WM_FINISH invoke MessageBox,NULL,ADDR AppName,ADDR AppName,MB_OK .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp

ThreadProc PROC USES ecx Param:DWORD mov ecx,300000000 Loop1: add eax,eax dec ecx jz Get_out jmp Loop1 Get_out: invoke SendMessage,hwnd,WM_FINISH,NULL,NULL ret ThreadProc ENDP end start
THREAD.RC

// Constants for menu #define IDM_CREATE_THREAD 1 #define IDM_EXIT 2


FirstMenu MENU { POPUP "&Process" { MENUITEM "&Create Thread",IDM_CREATE_THREAD MENUITEM SEPARATOR

SEGUNDO DE ASIR

Pgina 62

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


MENUITEM "E&xit",IDM_EXIT } } MAKEFILE NAME=thread $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm THREAD1.EXE EJECUCION DEL PROGRAMA Y CARACTERSTICAS

THREAD.EXE

SEGUNDO DE ASIR

Pgina 63

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012 EJERCICIO15


Crearemos un objeto evento y lo usaremos en un programa multithilo. En el tutorial anterior, demostr como se comunican los hilos usando un mensaje de ventana custom. I left out otros dos mtodos: variable global y objeto evento. Usaremos los dos en este tutorial. Un objeto evento es como un conmutador [switch]: tiene dos estados: activado [on] o inactivado [off]. Cuando un objeto es activado [turned on], est en estado "sealado". Cuando es desactivado [turned off], est en estado "no-sealado". Creas un evento y pones en un recorte de cdigo en los hilos releventes para ver el estado del objeto evento. Si el objeto evento est en el estado no sealado, los hilos que esperan sern puestos a dormir [asleep]. Cuando los hilos estn en estado de espera, consumen algo de tiempo del CPU. .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .const IDM_START_THREAD equ 1 IDM_STOP_THREAD equ 2 IDM_EXIT equ 3 WM_FINISH equ WM_USER+100h .data ClassName db "Win32ASMEventClass",0 AppName db "Win32 ASM Event Example",0 MenuName db "FirstMenu",0 SuccessString db "The calculation is completed!",0 StopString db "The thread is stopped",0 EventStop BOOL FALSE .data? hInstance HINSTANCE ? CommandLine LPSTR ? hwnd HANDLE ? hMenu HANDLE ? ThreadID DWORD ? ExitCode DWORD ? hThread DWORD ? hEventStart HANDLE ? .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT invoke ExitProcess,eax

SEGUNDO DE ASIR

Pgina 64

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_WINDOW+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,300,200,NULL,NULL,\ hInst,NULL mov hwnd,eax invoke ShowWindow, hwnd,SW_SHOWNORMAL invoke UpdateWindow, hwnd invoke GetMenu,hwnd mov hMenu,eax .WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_CREATE invoke CreateEvent,NULL,FALSE,FALSE,NULL mov hEventStart,eax mov eax,OFFSET ThreadProc invoke CreateThread,NULL,NULL,eax,\ NULL,NORMAL_PRIORITY_CLASS,\ ADDR ThreadID mov hThread,eax .ELSEIF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam .if lParam==0 .if ax==IDM_START_THREAD invoke SetEvent,hEventStart invoke EnableMenuItem,hMenu,IDM_START_THREAD,MF_GRAYED

SEGUNDO DE ASIR

Pgina 65

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


invoke EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_ENABLED .elseif ax==IDM_STOP_THREAD mov EventStop,TRUE invoke EnableMenuItem,hMenu,IDM_START_THREAD,MF_ENABLED invoke EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_GRAYED .else invoke DestroyWindow,hWnd .endif .endif .ELSEIF uMsg==WM_FINISH invoke MessageBox,NULL,ADDR SuccessString,ADDR AppName,MB_OK .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp ThreadProc PROC USES ecx Param:DWORD invoke WaitForSingleObject,hEventStart,INFINITE mov ecx,600000000 .WHILE ecx!=0 .if EventStop==FALSE add eax,eax dec ecx .else invoke MessageBox,hwnd,ADDR StopString,ADDR AppName,MB_OK mov EventStop,FALSE jmp ThreadProc .endif .ENDW invoke PostMessage,hwnd,WM_FINISH,NULL,NULL invoke EnableMenuItem,hMenu,IDM_START_THREAD,MF_ENABLED invoke EnableMenuItem,hMenu,IDM_STOP_THREAD,MF_GRAYED jmp ThreadProc ret ThreadProc ENDP end start THREAD2.RC // Constants for menu #define IDM_START_THREAD 1 #define IDM_STOP_THREAD 2 #define IDM_EXIT 3 FirstMenu MENU { POPUP "&Thread" { MENUITEM "&Run Thread",IDM_START_THREAD MENUITEM "&Stop Thread",IDM_STOP_THREAD,GRAYED MENUITEM SEPARATOR

SEGUNDO DE ASIR

Pgina 66

[EJERCICIOS ENSAMBLADOR CON MICROSOFT MACRO ASSEMBLER] 8 de enero de 2012


MENUITEM "E&xit",IDM_EXIT } } MAKEFILE NAME=thread2 $(NAME).exe: $(NAME).obj $(NAME).res Link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res $(NAME).res: $(NAME).rc rc $(NAME).rc $(NAME).obj: $(NAME).asm ml /c /coff /Cp $(NAME).asm

EJECUCION DEL PROGRAMA Y CARACTERSTICAS

SEGUNDO DE ASIR

Pgina 67

También podría gustarte