Переписал как: Код (Text): format PE GUI 4.0 DLL entry DllEntryPoint include 'win32a.inc' ; import data in the same section proc DllEntryPoint hinstDLL,fdwReason,lpvReserved mov eax,TRUE ret endp proc Win pop [adr] pop [t] pop [CB] pop [w] pop [h] xchg ebx,eax mov edi,[t] mov esi,400000h ; +------------------------------+ ; | registering the window class | ; +------------------------------+ invoke RegisterClass,esp,ebx,[CB],ebx,\ ebx,esi,ebx,10011h,COLOR_WINDOW,ebx,edi push ebx push esi push ebx push ebx push [h];WinH push [w];WinW invoke GetSystemMetrics,SM_CYSCREEN sub eax,352 shr eax,1 push eax invoke GetSystemMetrics,SM_CXSCREEN sub eax,512 shr eax,1 ; +--------------------------+ ; | creating the main window | ; +--------------------------+ invoke CreateWindowEx,ebx,edi,edi,WS_OVERLAPPEDWINDOW+WS_VISIBLE,eax mov ebp,esp push [adr] ret endp t dd ? w dd ? h dd ? CB dd ? adr dd ? data import library KERNEL32, 'KERNEL32.DLL',\ user32, 'USER32.DLL' import KERNEL32,\ ExitProcess, 'ExitProcess' import user32,\ PostQuitMessage, 'PostQuitMessage',\ RegisterClass, 'RegisterClassA',\ CreateWindowEx, 'CreateWindowExA',\ DefWindowProc, 'DefWindowProcA',\ GetMessage, 'GetMessageA',\ DispatchMessage, 'DispatchMessageA',\ MessageBox, 'MessageBoxA',\ GetSystemMetrics, 'GetSystemMetrics' end data section '.edata' export data readable export 'MM_GUI.DLL',\ Win,'Win' section '.reloc' fixups data discardable и Код (Text): format PE GUI 4.0 entry start include 'win32a.inc' section '.code' code readable executable proc WindowProc hwnd,wmsg,wparam,lparam ;invoke MessageBox,NULL,wTitle,NULL,MB_ICONERROR+MB_OK push ebx esi edi cmp [wmsg],2 je .wmdestroy .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish .wmdestroy: invoke PostQuitMessage,0 xor eax,eax invoke ExitProcess,0 .finish: pop edi esi ebx ret endp wTitle db 'Iczelion Tutorial #3:A Simple Window in centre in FASM',0 start: push 100 push 352 push WindowProc push wTitle invoke Win message_loop: invoke GetMessage,ebp,ebx,ebx,ebx invoke DispatchMessage,ebp jmp message_loop section '.idata' import data readable writeable library KERNEL32, 'KERNEL32.DLL',\ user32, 'USER32.DLL',\ mmgui, 'MM_GUI.DLL' import KERNEL32,\ ExitProcess, 'ExitProcess' import user32,\ PostQuitMessage, 'PostQuitMessage',\ RegisterClass, 'RegisterClassA',\ CreateWindowEx, 'CreateWindowExA',\ DefWindowProc, 'DefWindowProcA',\ GetMessage, 'GetMessageA',\ DispatchMessage, 'DispatchMessageA',\ MessageBox, 'MessageBoxA',\ GetSystemMetrics, 'GetSystemMetrics' import mmgui,\ Win,'Win' Теперь работает, но почему же не работает через Invoke с параметрами? В похожих примерах (скажем пример 'Dll' из стандартной поставки FASM) все нормально работает, а тут я и в отладчике не могу увидеть нарушения очереди стека, но факт - НЕ ПАШЕТ. P.S. Это начинает быть похоже на анекдот: Папа-программист сидит за компом в глубокой отладке. К нему подходит сын-школьник и спрашивает: - Пап, а почему солнце каждый день встает на востоке и садится на западе? - Точно? - Да. - Проверял? - Ну да. - Только ничего не трогай, НИЧЕГО НЕ МЕНЯЙ!
PUSH О ужас! Если воздержаться от комментариев по поводу испохабливания кода... Вы бы хоть обратили внимание в Olly на то, во что преобразуется макрос proc. Своим первым pop [adr] в процедуре Win Вы вытягиваете из стека уже совсем не адрес, а последнее значение ebp. Мало того, Вы ещё и "затеняете" списком параметров внешние имена переменных. Короче, ред бредкий получается. "Исправить" можно двумя способами. Способ номер извращенский: Строку proc Win,t,CB,w,h заменить на Win: . endp соответственно убрать. Способ номер более естесственный: Весь шлейф попов в начале процедуры убрать. mov ebp,esp в конце процедуры перенести за её пределы (а именно в экзешник сразу после вызова). push [adr] в конце процедуры убрать. Объявления переменных под процедурой убрать. А вообще мне интересено, какова цель столь изысканных извращений. Mikl___ после таких издевательств над его кодом, явно для этого не предназначенном, спокойно спать не сможет. P.S. Это всё было к посту 19.
По Олли Proc преобразуется в Код (Text): push EBP mov EBP,ESP ... leave retn 10 Понял теперь насчет mov ebp,esp. Я как понимаю, в ESP CreateWindowEx сохраняет хендл окна? Попробовал сохранить ESP в стек и достать в EBP в основном EXE-шнике, понял - ЗРЯ А в макросе proc нет ли возможности вернуть значение (было бы красиво), просто, чтобы не извращаться. А то, действительно, можно и все процедуры поменять на метки, и писать шлейфы PUSH-ев/POP-ов А, насчет извращений над кодом, эт я поучиться ассемблеру захотел. На сложном сложнее учиться, но зато, если поймешь, усвоишь значительно больше полезной информации. Вот я и извращаюсь... l_inc P.S. Спасибо за советы РЕЗКО ОБЛЕГЧАЮЩИЕ ПОНИМАНИЕ.
PUSH Ой не... Если это и может быть правдой, то это явно не тот случай. Особенно с учётом фраз вида: "Я как понимаю, в ESP CreateWindowEx сохраняет хендл окна?" Это абсолютный бред. Вы начинаете себе создавать некоторые представления, которые вроде как объясняют поведение программы, но на самом деле теория флогистона по сравнению с этими представлениями - детский лепет на лужайке. Начинайте спокойно с этого и с этого. Иначе Вы своё изучение ассемблера тормознёте годика этак на два. Возврат значения обычно происходит через регистр eax (в том числе и в случае CreateWindowEx). Значение инструкции mov ebp,esp я объяснил в посте 9: к CreateWindowEx она не имеет ни малейшего отношения. Я потому и написал, что это извращенский способ (в посте 21 Вы именно им и воспользовались. invoke с аргументами можно было в шлейф PUSH'ей не раскрывать). В частности редким извращением считается (во-первых) вытягивание переданных функции аргументов (во-вторых) в ГЛОБАЛЬНЫЕ (!) переменные: это Ваш шлейф попов в начале процедуры. P.S. Идея Mikl___ заключается в минимизации объёма кода. И ради этой минимизации он делает некоторые относительно нетривиальные вещи. Категорически не рекомендую продолжать изучать его примеры. P.P.S. Если в процедурно-модульном подходе к программированию (в частности dll) и была какая-то хорошая мысль, то Вы её уничтожили на корню.