Помогите создать простое окно Код (ASM): format PE64 GUI 6.0 entry start include 'win64a.inc' section '.code' code readable executable proc start invoke GetModuleHandleW,0 mov [wc.hInstance],rax invoke RegisterClass,wc invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,144,128,666,666,NULL,NULL,[wc.hInstance],NULL mov [hwnd],rax invoke ShowWindow,hwnd,0 invoke UpdateWindow,hwnd msg_loop: invoke GetMessage,msg,NULL,0,0 cmp eax,1 jb exit jne msg_loop invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop exit: invoke ExitProcess,eax endp proc WindowProc hwnd,wmsg,wparam,lparam invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp exit endp section '.data' data readable writeable hwnd dq ? _title TCHAR 'CLOCK',0 _class TCHAR 'CLOCK',0 wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class msg MSG section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ ExitProcess,'ExitProcess',\ GetModuleHandleW,'GetModuleHandleW',\ Sleep,'Sleep' import user,\ UpdateWindow,'UpdateWindow',\ ShowWindow,'ShowWindow',\ RegisterClass,'RegisterClassA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA'
Код (ASM): format PE GUI 4.0 entry start include "d:\compilers\fasm\include\win32ax.inc" section ".data" data readable writable wndClass db "FASMWND", 0 wndTitle db "FASM Window", 0 _hWnd dd ? _hInstance dd ? wc WNDCLASSEX ? msg MSG ? section ".idata" import data readable writable library kernel32, 'kernel32.dll', user32, 'USER32.DLL' include "d:\compilers\fasm\include\api\kernel32.inc" include "d:\compilers\fasm\include\api\user32.inc" section ".text" code readable writable executable start: invoke GetModuleHandle, NULL mov [_hInstance], eax mov [wc.hInstance], eax mov [wc.cbSize], sizeof.WNDCLASSEX mov [wc.style], CS_HREDRAW or CS_VREDRAW mov [wc.lpfnWndProc], wndProc mov [wc.cbClsExtra], 0 invoke LoadIcon, 0, IDI_APPLICATION mov [wc.hIcon], eax mov [wc.hIconSm], eax invoke LoadCursor, 0, IDC_ARROW mov [wc.hCursor], eax mov [wc.hbrBackground], COLOR_WINDOW+1 mov [wc.lpszMenuName], NULL mov [wc.lpszClassName], wndClass invoke RegisterClassEx, wc invoke CreateWindowEx, 0, wndClass, wndTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, NULL, NULL, [_hInstance], NULL mov [_hWnd], eax invoke ShowWindow, [_hWnd], SW_SHOW msg_loop: invoke GetMessage, msg, NULL, 0, 0 or eax, eax je end_prog invoke TranslateMessage, msg invoke DispatchMessage, msg jmp msg_loop end_prog: invoke ExitProcess, [msg.wParam] proc wndProc hWnd, msg, wParam, lParam push ebx esi edi cmp [msg], WM_DESTROY je destroyWnd invoke DefWindowProc, [hWnd], [msg], [wParam], [lParam] jmp finish destroyWnd: invoke PostQuitMessage, 0 finish: pop ebx esi edi ret endp
Там же в примерах всё есть Код (ASM): ; ------------------------------------------------------------------------------------- ; FASM version of Win32 Hello World: ; http://msdn.microsoft.com/en-us/library/vstudio/bb384843.aspx ; ------------------------------------------------------------------------------------- format PE GUI 4.0 entry win_main include 'win32a.inc' ; ------------------------------------------------------------------------------------- section '.code' code readable executable win_main: ; initialise the members of the wcex structure ; -------------------------------------------- ; WNDCLASSEX ; UINT cbSize ; UINT style ; WNDPROC lpfnWndProc ; int cbClsExtra ; int cbWndExtra ; HINSTANCE hInstance ; HICON hIcon ; HCURSOR hCursor ; HBRUSH hbrBackground ; LPCTSTR lpszMenuName ; LPCTSTR lpszClassName ; HICON hIconSm ; -------------------------------------------- ; the instance handle invoke GetModuleHandle,0 mov [wcex.hInstance],eax ; cbSize mov eax,sizeof.WNDCLASSEX mov [wcex.cbSize],eax ; the windows proc mov [wcex.lpfnWndProc],WndProc ; the windows style mov [wcex.style],CS_HREDRAW+CS_VREDRAW ; load the icons invoke LoadIcon,[wcex.hInstance],IDI_APPLICATION mov [wcex.hIcon],eax mov [wcex.hIconSm],eax ; load the cursor invoke LoadCursor,NULL,IDC_ARROW mov [wcex.hCursor],eax ; the brush for the background mov [wcex.hbrBackground],COLOR_WINDOW+1 ; the windows class name mov dword [wcex.lpszClassName],szClass ; set to NULL mov [wcex.cbClsExtra],0 mov [wcex.cbWndExtra],0 mov dword [wcex.lpszMenuName],NULL ; register wcex ; RegisterClassEx(&wcex) invoke RegisterClassEx,wcex test eax,eax jz reg_error ; create the window invoke CreateWindowEx,0,szClass,szTitle,WS_OVERLAPPEDWINDOW,\ CW_USEDEFAULT,CW_USEDEFAULT,\ 500,100,NULL,NULL,[wcex.hInstance],NULL test eax,eax jz cr_error mov [h_wnd],eax ; show and update the window ; ShowWindow(hWnd,SW_SHOWNORMAL) invoke ShowWindow,[h_wnd],SW_SHOWNORMAL ; UpdateWindow(hWnd) invoke UpdateWindow,[h_wnd] msg_loop: ; the main message loop ; GetMessage(&msg,NULL,0,0) invoke GetMessage,msg,NULL,0,0 cmp eax,1 jb exit jne msg_loop ; TranslateMessage(&msg) invoke TranslateMessage,msg ; DispatchMessage(&msg) invoke DispatchMessage,msg jmp msg_loop reg_error: invoke MessageBox,NULL,szRegError,szTitle,MB_ICONERROR+MB_OK jmp exit cr_error: invoke MessageBox,NULL,szCreateError,szTitle,MB_ICONERROR+MB_OK exit: ; return msg.wParam invoke ExitProcess,[msg.wParam] ; ------------------------------------------------------------------------------------- proc WndProc uses ebx esi edi,hwnd,wmsg,wparam,lparam ; WndProc(hwnd,wmsg,wparam,lparam) ; callback function to process messages for the main window cmp [wmsg],WM_PAINT je .PAINT cmp [wmsg],WM_DESTROY je .DESTROY .DEFAULT: ; DefWindowProc(hWnd,message,wParam,lParam) invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .DONE .PAINT: ; hdc = BeginPaint(hWnd,&ps) invoke BeginPaint,[hwnd],ps mov [hdc],eax ; TextOut(hdc,5,5,greeting,len(greeting)) invoke TextOut,[hdc],5,5,szGreeting,12 ; EndPaint(hWnd,&ps) invoke EndPaint,[hwnd],ps jmp .DONE .DESTROY: ; PostQuitMessage(0) invoke PostQuitMessage,0 xor eax,eax .DONE: ret endp ; ------------------------------------------------------------------------------------- section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ gdi,'GDI32.DLL' import kernel,\ GetModuleHandle,'GetModuleHandleA',\ ExitProcess,'ExitProcess' import user,\ RegisterClassEx,'RegisterClassExA',\ CreateWindowEx,'CreateWindowExA',\ ShowWindow,'ShowWindow',\ UpdateWindow,'UpdateWindow',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA',\ MessageBox,'MessageBoxA',\ DefWindowProc,'DefWindowProcA',\ BeginPaint,'BeginPaint',\ EndPaint,'EndPaint',\ PostQuitMessage,'PostQuitMessage',\ LoadIcon,'LoadIconA',\ LoadCursor,'LoadCursorA' import gdi,\ TextOut,'TextOutA' ; ------------------------------------------------------------------------------------- section '.data' readable writeable szClass TCHAR "Win32app",0 szTitle TCHAR "Win32 Application",0 szGreeting TCHAR "Hello World!",0 szRegError TCHAR "Call to RegisterClassEx failed!",0 szCreateError TCHAR "Call to CreateWindowEx failed!",0 wcex WNDCLASSEX ps PAINTSTRUCT msg MSG h_wnd dd 0 hdc dd 0 ; -------------------------------------------------------------------------------------
njeen, в смысле на Бейсике? Orbit, пишет в топике FASM x64 yashechka дает пример окна для 32-разрядного FASM, а это не совсем то, о чем спрашивал Orbit, поэтому я дал ссылку на цикл статей о х64, правда программы в цикле написаны на masm, но перейти с masm на fasm, IMHO, не так уж сложно...
в смысле "упорото"? давайте разбираться со ссылками, откуда я по вашему это "упорол"? да еще бы и выложил спертое сперва на http://www.masm32.com/board/index.php (http://masm32.com/board/index.php?topic=4190.0) потом несколько глав на wasm.ru до его закрытия, потом сюда
"упорото" - производит впечатление сделанного под веществами. Ваши адаптации цикла x86 Iczelion'а для x86_64 мне приходилось видеть, в т.ч на wasm.ru, я в курсе вашего авторства данной вещи . Однако, разве нет каноничной версии ? Наркомания же.
njeen, а я сперва подумал, что «упорото» это синоним «спёрто», ладно, хоть этот вопрос решили. «Канонический вариант» это, наверное, «голый код» на masm32.com и то, только потому, что английский у меня через google.translate. Русский текст — это мои тексты + фрагменты из переводов Aquila, SheSan (ODBC Tutorial), WD-40 (Урок 23, 25), N/A (Урок 33), переводы из MSDN и фрагменты из книг Чарльза Петцольда «Программирование для Windows® 95» 1996 (оригинал), 1997 (русский перевод издания «BHV — Санкт-Петербург») в двух томах, на которые опирался Iczelion при создании своих уроков.
Orbit, давай по порядку. Прежде чем вызывать функцию RegisterClass нужно иметь полностью заполненные поля структуры WNDCLASS Код (C++): typedef struct tagWNDCLASS { UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; } WNDCLASS Чтобы в каждой программе каждый раз перед регистрацией окна не вызывать GetModuleHandle, LoadIcon, LoadCursor один раз напиши такую программку Код (ASM): .data fmt db "hCursor = %08Xh",0Ah,"hIcon = %08Xh",0Ah,"hInstance =%08Xh",0 .code invoke GetModuleHandle,NULL mov [x1],rax invoke LoadIcon,NULL,IDI_APPLICATION mov [x2],rax invoke LoadCursor,NULL,IDC_ARROW mov [x3],rax invoke wsprintf,buffer,fmt,[x3],[x2],[x1] invoke MessageBox,NULL,buffer,MsgCaption,MB_OK invoke ExitProcess,NULL и после этого используй найденные константы для заполнения полей hInstance, hIcon, hCursor. Для твоей версии Windows они всегда будут одинаковыми для функции CreateWindowEx требуется заполненная структура WNDCLASSEX и функция RegisterClassEx для ее регистрации четвертым параметром передаваемым CreateWindowEx у тебя WS_VISIBLE + WS_OVERLAPPEDWINDOW при наличии WS_VISIBLE последующий вызов ShowWindow и UpdateWindow не нужен. Код (ASM): cmp eax,1 jb exit jne msg_loop invoke TranslateMessage,msg invoke DispatchMessage,msg если GetMessage вернет в RAX (а не в ЕАХ приложение-то 64-разрядное) ноль, тогда на выход из программы и это правильно, а вот дальше стоит для чего-то команда jne msg_loop которая пропускает к функциям TranslateMessage и DispatchMessage только в том случае если rax=1 Хотя согласно MSDN GetMessage return value can be nonzero, zero, or -1... The possibility of a -1 return value in the case that hWnd is an invalid parameter (such as referring to a window that has already been destroyed) means that such code can lead to fatal application errors WindowProc получает значения hwnd, wmsg, wparam, lparam через регистры RCX, RDX, R8, R9, а вот переменные [hwnd], [wmsg], [wparam], [lparam] которые расположены в стеке, нужно предварительно заполнить командами Код (ASM): mov [hwnd],rcx mov [wmsg],rdx mov [wparam],r8 mov [lparam],r9 и этот фрагмент в примере fasm\examples\win64\template\template.asm есть, посмотри внимательно, иначе в строке invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] функции DefWindowProc в качестве параметров передаются нули Функции ExitProcess и DefWindowProc это всего лишь "переходники" к функциям RtlExitUserProcess и NtdllDefWindowProc_A из ntdll.dll привыкай использовать их Твоя процедура WindowProc Код (ASM): proc WindowProc hwnd,wmsg,wparam,lparam invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp exit endp это вообще ЧТО-ТО за гранью добра и зла. WindowProc должна выглядеть вот так Код (ASM): proc WindowProc hwnd,wmsg,wparam,lparam mov [hwnd],rcx mov [wmsg],rdx mov [wparam],r8 mov [lparam],r9 cmp [wmsg],WM_DESTROY jne .defwndproc invoke PostQuitMessage,0 ret .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] ret endp
Код (ASM): format PE64 GUI 6.0 entry start include 'win64a.inc' section '.code' code readable executable ;----------------------------------------------------------------------- start: sub rsp,8 ; Make stack dqword aligned invoke GetModuleHandle,0 mov [wc.hInstance],rax mov [wc.cbSize],sizeof.WNDCLASSEX mov [wc.style],CS_HREDRAW or CS_VREDRAW mov [wc.lpfnWndProc],WindowProc mov [wc.cbClsExtra],0 invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],rax mov [wc.hIconSm],rax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],rax mov [wc.hbrBackground],COLOR_WINDOW+1 mov [wc.lpszMenuName],NULL mov [wc.lpszClassName],szTitle invoke RegisterClassEx,wc invoke CreateWindowEx,0,szTitle,szTitle,WS_VISIBLE + WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,500,100,NULL,NULL,[wc.hInstance],NULL msg_loop: invoke GetMessage,msg,NULL,0,0 or rax,rax je exit invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop exit: invoke ExitProcess,[msg.wParam] ;-------------------------------------------------------------------------------- proc WindowProc hwnd,wmsg,wparam,lparam mov [hwnd],rcx mov [wmsg],rdx mov [wparam],r8 mov [lparam],r9 cmp [wmsg],WM_DESTROY jne .defwndproc invoke PostQuitMessage,0 ret .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] ret endp ;---------------------------------------------------------------------- section '.data' data readable writeable szTitle db 'CLOCK',0 wc WNDCLASSEX msg MSG ;------------------------------------------------------------------------ section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ ExitProcess,'ExitProcess',\ GetModuleHandle,'GetModuleHandleA' import user,\ PostQuitMessage,'PostQuitMessage',\ LoadIcon,'LoadIconA',\ LoadCursor,'LoadCursorA',\ RegisterClassEx,'RegisterClassExA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ GetMessage,'GetMessageA',\ TranslateMessage,'TranslateMessage',\ DispatchMessage,'DispatchMessageA'
так программа выглядит после упрощения Код (ASM): format PE64 GUI 6.0 entry start include 'win64a.inc' section '.code' code readable executable ;----------------------------------------------------------------------- proc start local wc:WNDCLASSEX local msg:MSG mov [wc.hInstance],400000h mov [wc.cbSize],sizeof.WNDCLASSEX mov [wc.style],CS_HREDRAW or CS_VREDRAW mov [wc.lpfnWndProc],WindowProc mov [wc.cbClsExtra],0 invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],rax mov [wc.hIconSm],rax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],rax mov [wc.hbrBackground],COLOR_WINDOW+1 mov [wc.lpszMenuName],NULL mov [wc.lpszClassName],szTitle lea ecx,[wc] invoke RegisterClassEx invoke CreateWindowEx,0,szTitle,szTitle,WS_VISIBLE + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, 400000h, NULL lea edi,[msg] msg_loop: invoke GetMessage,edi,NULL,0,0 invoke DispatchMessage,edi jmp msg_loop endp proc WindowProc hwnd,wmsg,wparam,lparam cmp edx,WM_DESTROY jne .defwndproc invoke ExitProcess,0 .defwndproc: leave jmp [DefWindowProc] endp ;---------------------------------------------------------------------- section '.data' data readable writeable szTitle db 'CLOCK',0 ;------------------------------------------------------------------------ section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' import kernel,\ ExitProcess,'ExitProcess' import user,\ LoadIcon,'LoadIconA',\ LoadCursor,'LoadCursorA',\ RegisterClassEx,'RegisterClassExA',\ CreateWindowEx,'CreateWindowExA',\ DefWindowProc,'DefWindowProcA',\ GetMessage,'GetMessageA',\ DispatchMessage,'DispatchMessageA'
А это финальный этап Код (ASM): format PE64 GUI 6.0 entry start include 'win64a.inc' section '.code' code readable executable writeable ;----------------------------------------------------------------------- proc start local wc:WNDCLASSEX local msg:MSG sub esp,60h mov esi,400000h ;esi=hInstance mov [wc.hInstance],rsi mov [wc.cbSize],sizeof.WNDCLASSEX mov [wc.style],CS_HREDRAW or CS_VREDRAW mov [wc.lpfnWndProc],WindowProc xor ecx,ecx mov [wc.cbClsExtra],ecx mov [wc.lpszMenuName],rcx mov edx,IDI_APPLICATION call [LoadIcon] mov [wc.hIcon],rax mov [wc.hIconSm],rax mov edx,IDC_ARROW xor ecx,ecx call [LoadCursor] mov [wc.hCursor],rax mov [wc.hbrBackground],COLOR_WINDOW+1 mov edi,szTitle mov [wc.lpszClassName],rdi lea ecx,[wc] call [RegisterClassEx] xor ecx,ecx mov edx,edi ;szTitle mov r8d,edi mov r9d,WS_VISIBLE + WS_OVERLAPPEDWINDOW mov [rsp+50h],rsi ;hInstance shl esi,9 ;esi=CW_USEDEFAULT mov [rsp+20h],rsi mov [rsp+28h],rsi mov qword[rsp+30h],500 mov qword[rsp+38h],100 mov [rsp+40h],rcx mov [rsp+48h],rcx mov [rsp+58h],rcx call [CreateWindowEx] lea edi,[msg] msg_loop: mov ecx,edi xor edx,edx xor r8,r8 xor r9,r9 call [GetMessage] mov ecx,edi call [DispatchMessage] jmp msg_loop endp WindowProc: push rbp mov ebp,esp sub esp,20h cmp edx,WM_DESTROY jne .defwndproc xor ecx,ecx call [RtlExitUserProcess] .defwndproc: leave jmp [NtdllDefWindowProc] ;---------------------------------------------------------------------- szTitle db 'CLOCK',0 ;------------------------------------------------------------------------ section '.idata' import data readable writeable library ntdll,'ntdll.DLL',\ user,'USER32.DLL' import ntdll,\ RtlExitUserProcess,'RtlExitUserProcess',\ NtdllDefWindowProc,'NtdllDefWindowProc_A' import user,\ LoadIcon,'LoadIconA',\ LoadCursor,'LoadCursorA',\ RegisterClassEx,'RegisterClassExA',\ CreateWindowEx,'CreateWindowExA',\ GetMessage,'GetMessageA',\ DispatchMessage,'DispatchMessageA'
замени WS_VISIBLE + WS_OVERLAPPEDWINDOW на WS_OVERLAPPED + WS_VISIBLE + WS_CAPTION + WS_SYSMENU + WS_MINIMIZEBOX