pamiętnik programisty

02 wrz, 2009

Tworzenie okienka w asm

Zamieszczony przez: pejotr w: Programowanie

Wiadomo że stworzenie okienka przy wykorzystaniu języka C i WinAPI nie jest zadaniem trudnym. Nawet w dokumentacji od MS można znaleźć gotowy przykład. Jest to natomiast zadanie bardzo żmudne i z reguły z pełnym zrozumieniem pól i dopuszczalnych wartości dla wymaganych struktur robi się to tylko raz. Potem albo się kopiuje gotowy standardowy kod wprowadzając tylko pewne czasami zmiany odbiegającego od typowego zastosowania, albo przyjmuje że “się umie” i “zna fundament” i przesiada na WindowsForms. Ale można pójść w drugą stronę, stworzyć okienko w assmeblerze i tym samym uzyskać miano rycerza hardcoru.

Może dziwić ale zbudowanie okna korzystając z języka maszynowego nie jest trudno. Objętość programu jest zbliżona do tego utworzonego standardowo z wykorzystaniem C. Ponadto korzystając z kompilatora dostarczonego przez Microsoft (MASM) istnieje możliwość bardzo łatwego dostępu do funkcji API systemu Windows. Ponad to kompilator dostarcza wiele ułatwiających życie makr.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
.386
.model flat,stdcall
option casemap:none
include     c:\masm32\include\windows.inc
include  c:\masm32\include\user32.inc
includelib  c:\masm32\lib\user32.lib
include     c:\masm32\include\kernel32.inc
includelib  c:\masm32\lib\kernel32.lib

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

.data ; zainicjalizowanie zmienne
   ClassName db "SimpleWinClass",0
   AppName db "Our first Window",0
.data?   ; niezainicjalizowane zmienne
   hInstance HINSTANCE ?
   CommandLine LPSTR ?
.code
   start:
      invoke GetModuleHandle,NULL
      mov hInstance,eax
      invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
      invoke ExitProcess,0
     
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,\
                hInst,\
                NULL
    mov hwnd,eax
    invoke ShowWindow,hwnd,CmdShow
    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

Nie ma co wiele tłumaczyć. Kod jaki jest interpretowany przez MASM wygląda już niemalże jak język wysokiego poziomu(niektórzy mówią że C to język niskiego poziomu, ale to dlatego że nie umieli znaleźć określenia dla Javy, C# itp.) Bardzo fajnym makrem jest invoke uruchamiające zadaną procedurę i umożliwiające podanie listy argumentów poprzez rozdzielenie przecinkiem. Bardzo przyjemna alternatywa dla push’owania w odwrotnej kolejności.
Jedyny wniosek jaki można wysnuć to to że jeżeli ktoś umie programować z wykorzystaniem WinAPI w C, to i bez problemu zastosuje go w assemblerze. Oczywiście nie ma obowiązku korzystania z MASM, do API można się także dostać korzystać z innych assemblerów np. NASM ( polacam zapoznanie się z nasmx).

Tagi: ,

Brak odpowiedzi na "Tworzenie okienka w asm"

Formularz komentarza

O mnie:

pejotrWitam, nazywam się Piotr Doniec, w internecie występuję pod nickami 'pejotr' oraz 'doniczek'. Obecnie jestem studentem 3 roku informatyki na Politechnice Warszawskiej na wydziale Elektroniki i Technik Informacyjnych.

Kategorie