TinmanQC

Asm

Apr 15th, 2021
1,172
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;-------------------------------------------------------------------------------------------------------------------
  2. ; Hello, Windows!  in x86 ASM - (c) 2021 Dave's Garage - Use at your own risk, no warranty!
  3. ;-------------------------------------------------------------------------------------------------------------------
  4.  
  5. ; Compiler directives and includes
  6.  
  7. .386                        ; Full 80386 instruction set and mode
  8. .model flat, stdcall                ; All 32-bit and later apps are flat. Used to include "tiny, etc"
  9. option casemap:none             ; Preserve the case of system identifiers but not our own, more or less
  10.  
  11.  
  12. ; Include files - headers and libs that we need for calling the system dlls like user32, gdi32, kernel32, etc
  13. include \masm32\include\windows.inc     ; Main windows header file (akin to Windows.h in C)
  14. include \masm32\include\user32.inc      ; Windows, controls, etc
  15. include \masm32\include\kernel32.inc        ; Handles, modules, paths, etc
  16. include \masm32\include\gdi32.inc       ; Drawing into a device context (ie: painting)
  17.  
  18. ; Libs - information needed to link ou binary to the system DLL callss
  19.  
  20. includelib \masm32\lib\kernel32.lib     ; Kernel32.dll
  21. includelib \masm32\lib\user32.lib       ; User32.dll
  22. includelib \masm32\lib\gdi32.lib        ; GDI32.dll
  23.  
  24. ; Forward declarations - Our main entry point will call forward to WinMain, so we need to define it here
  25.  
  26. WinMain proto :DWORD, :DWORD, :DWORD, :DWORD    ; Forward decl for MainEntry
  27.  
  28. ; Constants and Datra
  29.  
  30. WindowWidth equ 640             ; How big we'd like our main window
  31. WindowHeight    equ 480
  32.  
  33. .DATA
  34.  
  35. ClassName       db "MyWinClass", 0      ; The name of our Window class
  36. AppName     db "Dave's Tiny App", 0     ; The name of our main window
  37.  
  38. .DATA?                      ; Uninitialized data - Basically just reserves address space
  39.  
  40. hInstance   HINSTANCE ?         ; Instance handle (like the process id) of our application
  41. CommandLine LPSTR     ?                     ; Pointer to the command line text we were launched with
  42.  
  43. ;-------------------------------------------------------------------------------------------------------------------
  44. .CODE                       ; Here is where the program itself lives
  45. ;-------------------------------------------------------------------------------------------------------------------
  46.  
  47. MainEntry proc
  48.  
  49.     LOCAL   sui:STARTUPINFOA        ; Reserve stack space so we can load and inspect the STARTUPINFO
  50.  
  51.     push    NULL                ; Get the instance handle of our app (NULL means ourselves)
  52.     call    GetModuleHandle         ; GetModuleHandle will return instance handle in EAX
  53.     mov hInstance, eax          ; Cache it in our global variable
  54.  
  55.     call    GetCommandLineA         ; Get the command line text ptr in EAX to pass on to main
  56.     mov CommandLine, eax
  57.  
  58.     ; Call our WinMain and then exit the process with whatever comes back from it
  59.  
  60.     ; Please check this, I have only typed it, not tested it :-)
  61.  
  62.     lea eax, sui            ; Get the STARTUPINFO for this process
  63.     push    eax
  64.     call    GetStartupInfoA         ; Find out if wShowWindow should be used
  65.     test    sui.dwFlags, STARTF_USESHOWWINDOW  
  66.     jz  @1
  67.     push    sui.wShowWindow         ; If the show window flag bit was nonzero, we use wShowWindow
  68.     jmp @2
  69. @1:
  70.     push    SW_SHOWDEFAULT          ; Use the default
  71. @2:
  72.     push    CommandLine
  73.     push    NULL
  74.     push    hInstance
  75.     call    WinMain
  76.  
  77.     push    eax
  78.     call    ExitProcess
  79.  
  80. MainEntry endp
  81.  
  82. ;
  83. ; WinMain - The traditional signature for the main entry point of a Windows programa
  84. ;
  85.  
  86. WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
  87.  
  88.     LOCAL   wc:WNDCLASSEX           ; Create these vars on the stack, hence LOCAL
  89.     LOCAL   msg:MSG
  90.     LOCAL   hwnd:HWND
  91.  
  92.     mov wc.cbSize, SIZEOF WNDCLASSEX        ; Fill in the values in the members of our windowclass
  93.     mov wc.style, CS_HREDRAW or CS_VREDRAW  ; Redraw if resized in either dimension
  94.     mov wc.lpfnWndProc, OFFSET WndProc      ; Our callback function to handle window messages
  95.     mov wc.cbClsExtra, 0            ; No extra class data
  96.     mov wc.cbWndExtra, 0            ; No exttra window data
  97.     mov eax, hInstance
  98.     mov wc.hInstance, eax           ; Our instance handle
  99.     mov wc.hbrBackground, COLOR_3DSHADOW+1  ; Default brush colors are color plus one
  100.     mov wc.lpszMenuName, NULL           ; No app menu
  101.     mov wc.lpszClassName, OFFSET ClassName  ; The window's class name
  102.  
  103.     push    IDI_APPLICATION             ; Use the default application icon
  104.     push    NULL   
  105.     call    LoadIcon
  106.     mov wc.hIcon, eax
  107.     mov wc.hIconSm, eax
  108.  
  109.     push    IDC_ARROW               ; Get the default "arrow" mouse cursor
  110.     push    NULL
  111.     call    LoadCursor
  112.     mov wc.hCursor, eax
  113.  
  114.     lea eax, wc
  115.     push    eax
  116.     call    RegisterClassEx             ; Register the window class
  117.  
  118.     push    NULL                    ; Bonus data, but we have none, so null
  119.     push    hInstance               ; Our app instance handle
  120.     push    NULL                    ; Menu handle
  121.     push    NULL                    ; Parent window (if we were a child window)
  122.     push    WindowHeight                ; Our requested height
  123.     push    WindowWidth             ; Our requested width
  124.     push    CW_USEDEFAULT               ; Y
  125.     push    CW_USEDEFAULT               ; X
  126.     push    WS_OVERLAPPEDWINDOW + WS_VISIBLE    ; Window stytle (normal and visible)
  127.     push    OFFSET AppName              ; The window title (our application name)
  128.     push    OFFSET ClassName            ; The window class name of what we're creating
  129.     push    0                   ; Extended style bits, if any
  130.     call    CreateWindowExA
  131.     cmp eax, NULL
  132.     je  WinMainRet              ; Fail and bail on NULL handle returned
  133.     mov hwnd, eax               ; Window handle is the result, returned in eax
  134.  
  135.     push    eax                 ; Force a paint of our window
  136.     call    UpdateWindow
  137.  
  138. MessageLoop:
  139.  
  140.     push    0
  141.     push    0
  142.     push    NULL
  143.     lea eax, msg
  144.     push    eax
  145.     call    GetMessage              ; Get a message from the application's message queue
  146.  
  147.     cmp eax, 0                  ; When GetMessage returns 0, it's time to exit
  148.     je  DoneMessages
  149.  
  150.     lea eax, msg                ; Translate 'msg'
  151.     push    eax
  152.     call    TranslateMessage
  153.  
  154.     lea eax, msg                ; Dispatch 'msg'
  155.     push    eax
  156.     call    DispatchMessage
  157.  
  158.     jmp MessageLoop
  159.  
  160. DoneMessages:
  161.    
  162.     mov eax, msg.wParam             ; Return wParam of last message processed
  163.  
  164. WinMainRet:
  165.    
  166.     ret
  167.  
  168. WinMain endp
  169.  
  170. ;
  171. ; WndProc - Our Main Window Procedure, handles painting and exiting
  172. ;
  173.  
  174. WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
  175.  
  176.     LOCAL   ps:PAINTSTRUCT              ; Local stack variables
  177.     LOCAL   rect:RECT
  178.     LOCAL   hdc:HDC
  179.  
  180.     cmp uMsg, WM_DESTROY
  181.     jne NotWMDestroy
  182.  
  183.     push    0                   ; WM_DESTROY received, post our quit msg
  184.     call    PostQuitMessage             ; Quit our application
  185.     xor eax, eax                ; Return 0 to indicate we handled it
  186.     ret
  187.  
  188. NotWMDestroy:
  189.  
  190.     cmp uMsg, WM_PAINT
  191.     jne NotWMPaint
  192.  
  193.     lea eax, ps                 ; WM_PAINT received
  194.     push    eax
  195.     push    hWnd
  196.     call    BeginPaint              ; Go get a device context to paint into
  197.     mov hdc, eax
  198.  
  199.     push    TRANSPARENT
  200.     push    hdc
  201.     call    SetBkMode               ; Make text have a transparent background
  202.  
  203.     lea eax, rect               ; Figure out how big the client area is so that we
  204.     push    eax                 ;   can center our content over it
  205.     push    hWnd
  206.     call    GetClientRect
  207.  
  208.     push    DT_SINGLELINE + DT_CENTER + DT_VCENTER
  209.     lea eax, rect
  210.     push    eax
  211.     push    -1
  212.     push    OFFSET AppName
  213.     push    hdc
  214.     call    DrawText                ; Draw text centered vertically and horizontally
  215.  
  216.     lea eax, ps
  217.     push    eax
  218.     push    hWnd
  219.     call    EndPaint                ; Wrap up painting
  220.  
  221.     xor eax, eax                ; Return 0 as no further processing needed
  222.     ret
  223.  
  224. NotWMPaint:
  225.    
  226.     push    lParam
  227.     push    wParam
  228.     push    uMsg
  229.     push    hWnd
  230.     call    DefWindowProc               ; Forward message on to default processing and
  231.     ret                     ;   return whatever it does
  232.  
  233. WndProc endp
  234.  
  235. END MainEntry                       ; Specify entry point, else _WinMainCRTStartup is assumed
  236.  
  237.  
RAW Paste Data