В чем тут проблема? *NOOB*

Тема в разделе "WASM.BEGINNERS", создана пользователем PUSH, 28 фев 2009.

  1. PUSH

    PUSH New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2008
    Сообщения:
    25
    Переписал как:
    Код (Text):
    1. format PE GUI 4.0 DLL
    2. entry DllEntryPoint
    3. include 'win32a.inc'
    4. ; import data in the same section
    5.  
    6. proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
    7.     mov eax,TRUE
    8.     ret
    9. endp
    10.  
    11. proc Win
    12.       pop [adr]
    13.       pop [t]
    14.       pop [CB]
    15.       pop [w]
    16.       pop [h]
    17.       xchg ebx,eax
    18.       mov edi,[t]
    19.       mov esi,400000h
    20.       ; +------------------------------+
    21.       ; | registering the window class |
    22.       ; +------------------------------+
    23.       invoke RegisterClass,esp,ebx,[CB],ebx,\
    24.       ebx,esi,ebx,10011h,COLOR_WINDOW,ebx,edi
    25.       push ebx
    26.       push esi
    27.       push ebx
    28.       push ebx
    29.       push [h];WinH
    30.       push [w];WinW
    31.       invoke GetSystemMetrics,SM_CYSCREEN
    32.       sub eax,352
    33.       shr eax,1
    34.       push eax
    35.       invoke GetSystemMetrics,SM_CXSCREEN
    36.       sub eax,512
    37.       shr eax,1
    38.       ; +--------------------------+
    39.       ; | creating the main window |
    40.       ; +--------------------------+
    41.       invoke CreateWindowEx,ebx,edi,edi,WS_OVERLAPPEDWINDOW+WS_VISIBLE,eax
    42.       mov ebp,esp
    43.       push [adr]
    44.     ret
    45. endp
    46.  
    47.       t dd ?
    48.       w dd ?
    49.       h dd ?
    50.       CB dd ?
    51.       adr dd ?
    52.  
    53. data import
    54.  library KERNEL32, 'KERNEL32.DLL',\
    55.      user32,   'USER32.DLL'
    56.  import KERNEL32,\
    57.            ExitProcess,    'ExitProcess'
    58.  import user32,\
    59.         PostQuitMessage,        'PostQuitMessage',\
    60.         RegisterClass,      'RegisterClassA',\
    61.         CreateWindowEx,     'CreateWindowExA',\
    62.         DefWindowProc,      'DefWindowProcA',\
    63.         GetMessage,     'GetMessageA',\
    64.         DispatchMessage,    'DispatchMessageA',\
    65.         MessageBox,    'MessageBoxA',\
    66.         GetSystemMetrics,   'GetSystemMetrics'
    67. end data
    68.  
    69. section '.edata' export data readable
    70.  
    71.   export 'MM_GUI.DLL',\
    72.      Win,'Win'
    73.      
    74. section '.reloc' fixups data discardable
    и
    Код (Text):
    1. format PE GUI 4.0
    2. entry start
    3.  
    4. include 'win32a.inc'
    5.  
    6. section '.code' code readable executable
    7. proc WindowProc hwnd,wmsg,wparam,lparam
    8.     ;invoke MessageBox,NULL,wTitle,NULL,MB_ICONERROR+MB_OK
    9.     push    ebx esi edi
    10.     cmp [wmsg],2
    11.     je  .wmdestroy
    12.   .defwndproc:
    13.     invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
    14.     jmp .finish
    15.   .wmdestroy:
    16.     invoke  PostQuitMessage,0
    17.     xor eax,eax
    18.     invoke  ExitProcess,0
    19.   .finish:
    20.     pop edi esi ebx
    21.     ret
    22. endp
    23.  
    24.   wTitle db   'Iczelion Tutorial #3:A Simple Window in centre in FASM',0
    25.  
    26.   start:
    27.     push 100
    28.     push 352
    29.     push WindowProc
    30.     push wTitle
    31.     invoke  Win
    32.  
    33.   message_loop: invoke GetMessage,ebp,ebx,ebx,ebx
    34.       invoke DispatchMessage,ebp
    35.       jmp message_loop
    36.  
    37. section '.idata' import data readable writeable
    38.  
    39.   library KERNEL32, 'KERNEL32.DLL',\
    40.      user32, 'USER32.DLL',\
    41.      mmgui, 'MM_GUI.DLL'
    42.  import KERNEL32,\
    43.            ExitProcess,    'ExitProcess'
    44.  import user32,\
    45.         PostQuitMessage,        'PostQuitMessage',\
    46.         RegisterClass,      'RegisterClassA',\
    47.         CreateWindowEx,     'CreateWindowExA',\
    48.         DefWindowProc,      'DefWindowProcA',\
    49.         GetMessage,     'GetMessageA',\
    50.         DispatchMessage,    'DispatchMessageA',\
    51.         MessageBox,    'MessageBoxA',\
    52.         GetSystemMetrics,   'GetSystemMetrics'
    53.  
    54.   import mmgui,\
    55.      Win,'Win'
    Теперь работает, но почему же не работает через Invoke с параметрами? В похожих примерах (скажем пример 'Dll' из стандартной поставки FASM) все нормально работает, а тут я и в отладчике не могу увидеть нарушения очереди стека, но факт - НЕ ПАШЕТ.

    P.S. Это начинает быть похоже на анекдот:
    Папа-программист сидит за компом в глубокой отладке. К нему подходит сын-школьник и спрашивает:
    - Пап, а почему солнце каждый день встает на востоке и садится на западе?
    - Точно?
    - Да.
    - Проверял?
    - Ну да.
    - Только ничего не трогай, НИЧЕГО НЕ МЕНЯЙ!
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    PUSH
    О ужас! Если воздержаться от комментариев по поводу испохабливания кода... Вы бы хоть обратили внимание в Olly на то, во что преобразуется макрос proc. Своим первым pop [adr] в процедуре Win Вы вытягиваете из стека уже совсем не адрес, а последнее значение ebp. Мало того, Вы ещё и "затеняете" списком параметров внешние имена переменных. Короче, ред бредкий получается. "Исправить" можно двумя способами.
    Способ номер извращенский:
    Строку proc Win,t,CB,w,h заменить на Win: . endp соответственно убрать.
    Способ номер более естесственный:
    Весь шлейф попов в начале процедуры убрать. mov ebp,esp в конце процедуры перенести за её пределы (а именно в экзешник сразу после вызова). push [adr] в конце процедуры убрать. Объявления переменных под процедурой убрать.

    А вообще мне интересено, какова цель столь изысканных извращений. Mikl___ после таких издевательств над его кодом, явно для этого не предназначенном, спокойно спать не сможет.
    P.S. Это всё было к посту 19.
     
  3. PUSH

    PUSH New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2008
    Сообщения:
    25
    По Олли Proc преобразуется в
    Код (Text):
    1. push EBP
    2. mov EBP,ESP
    3. ...
    4. leave
    5. retn 10
    Понял теперь насчет mov ebp,esp. Я как понимаю, в ESP CreateWindowEx сохраняет хендл окна? Попробовал сохранить ESP в стек и достать в EBP в основном EXE-шнике, понял - ЗРЯ :) А в макросе proc нет ли возможности вернуть значение (было бы красиво), просто, чтобы не извращаться. А то, действительно, можно и все процедуры поменять на метки, и писать шлейфы PUSH-ев/POP-ов :)

    А, насчет извращений над кодом, эт я поучиться ассемблеру захотел. На сложном сложнее учиться, но зато, если поймешь, усвоишь значительно больше полезной информации. Вот я и извращаюсь... :)

    l_inc
    P.S. Спасибо за советы РЕЗКО ОБЛЕГЧАЮЩИЕ ПОНИМАНИЕ.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    PUSH
    Ой не... Если это и может быть правдой, то это явно не тот случай. Особенно с учётом фраз вида: "Я как понимаю, в ESP CreateWindowEx сохраняет хендл окна?" Это абсолютный бред. Вы начинаете себе создавать некоторые представления, которые вроде как объясняют поведение программы, но на самом деле теория флогистона по сравнению с этими представлениями - детский лепет на лужайке. Начинайте спокойно с этого и с этого. Иначе Вы своё изучение ассемблера тормознёте годика этак на два.
    Возврат значения обычно происходит через регистр eax (в том числе и в случае CreateWindowEx). Значение инструкции mov ebp,esp я объяснил в посте 9: к CreateWindowEx она не имеет ни малейшего отношения.
    Я потому и написал, что это извращенский способ (в посте 21 Вы именно им и воспользовались. invoke с аргументами можно было в шлейф PUSH'ей не раскрывать). В частности редким извращением считается (во-первых) вытягивание переданных функции аргументов (во-вторых) в ГЛОБАЛЬНЫЕ (!) переменные: это Ваш шлейф попов в начале процедуры.
    P.S. Идея Mikl___ заключается в минимизации объёма кода. И ради этой минимизации он делает некоторые относительно нетривиальные вещи. Категорически не рекомендую продолжать изучать его примеры.
    P.P.S. Если в процедурно-модульном подходе к программированию (в частности dll) и была какая-то хорошая мысль, то Вы её уничтожили на корню.