Сейчас на форуме: tyns777, cppasm, dutyfree (+8 невидимых)

 eXeL@B —› Вопросы новичков —› Вопрос по WinMain
Посл.ответ Сообщение

Ранг: 12.0 (новичок)
Активность: 0.020
Статус: Участник

Создано: 05 июля 2017 14:33 · Поправил: shiroko
· Личное сообщение · #1

Рассматривая разные примеры кода в туторах по масму, наткнулся на неясность с функцией WinMain. С одной стороны, это главная функция, с которой начинается исполнение win32-программы и , если верить минимальное приложение должно выглядеть так:
Code:
  1. .386
  2. .model flat,stdcall
  3. ExitProcess PROTO :DWORD
  4. .code
  5. WinMain PROC PUBLIC hinst,prev_hinst,command_line,cmd_show
  6.  ;...
  7.  invoke ExitProcess,0
  8. WinMain ENDP
  9. end

И тут же наткнулся на код из первого урока cracklab-a Assembler_Windows_Coding_01.rar, где при создании оконного приложения WinMain и вовсе не нужен. Можеn где-то затупил, но когда есть необходимость в стартовой функции? Или она обязательна только в высокоуровневых ЯП типа С++, где параметры WinMain автоматически заполняются
run-time функцией функция _WinMainCRTStartup?



Ранг: 80.6 (постоянный), 194thx
Активность: 0.10.04
Статус: Участник

Создано: 05 июля 2017 15:28 · Поправил: v00doo
· Личное сообщение · #2

shiroko пишет:
Может где-то затупил, но когда есть необходимость в стартовой функции?

Точка входа есть всегда, WinMainCRTStartup инициализирует CRT и передает параметры дальше в winmain, а саму же winmain можно назвать как угодно, на уровне линковщика это просто функция.
При отладке в той же студии, например, все будет начинаться с майна, crt не будет видно, это вспомогательная вещь, без нее в си не заведутся вещи из немспейса std:: и т.п., но ее так же можно "отключить" и писать все самому с нуля, некоторые так и делают, в общем зависит от настроек компиляции.



Ранг: 12.0 (новичок)
Активность: 0.020
Статус: Участник

Создано: 05 июля 2017 15:55 · Поправил: shiroko
· Личное сообщение · #3

v00doo пишет:
WinMainCRTStartup инициализирует CRT и передает параметры дальше в winmain

Так в чистом masm вроде как нет автоматической run-time инициализации.
In C/C++ programs, the label “WinMain” must be used but in assembler any label can be used
Тут как бы все ясно, и далее:
Code:
  1. .CODE  
  2. START:
  3.                 invoke  GetModuleHandle  ,  Null 
  4.                  mov    HINST   ,  EAX          
  5.                       CALL   MY_REGISTER_CLASS 
  6.                            cmp   EAX  ,  null
  7.                        je   EXIT
  8.                 invoke    CreateWindowEx   ,  Null  ,   addr    String_CLASS   ,  addr  String_CAPTION  , \
  9.                    WS_VISIBLE +  WS_CAPTION  + WS_SYSMENU   ,   100 , 100 ,  500 ,  500  , \
  10.                    NULL ,  NULL  ,  HINST ,  NULL      
  11.                   MOV   HWND_WIN  , EAX           
  12.                 invoke  ShowWindow   ,  HWND_WIN   , TRUE  
  13.                 invoke  UpdateWindow ,  HWND_WIN                                        
  14. MSG_LOOP:
  15.                            invoke   GetMessage  ,    addr  MSG_WIN  , null , null , null
  16.                            CMP   Eax  ,  FALSE
  17.                          JE    EXIT          
  18.                            invoke   TranslateMessage  ,   addr   MSG_WIN 
  19.                            invoke   DispatchMessage       , addr  MSG_WIN
  20.                         JMP   MSG_LOOP      
  21. EXIT:     
  22.              invoke               ExitProcess        ,       Null
  23.                                                         
  24. ;----------------------------------------------------------------------------------------------------------
  25. MY_REGISTER_CLASS  PROC   
  26. ...  
  27. MY_REGISTER_CLASS   ENDP
  28. ;-----------------------------------------------------------------------------------------------------------
  29. MAIN_WINDOW_PROC     PROC   USES  EBX   ESI  EDI  \
  30. ...
  31. FINISH:
  32. RET  16                                                 
  33. MAIN_WINDOW_PROC     ENDP
  34. ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  35. END  START

Где здесь WinMainCRTStartup инициализирует CRT и передает параметры дальше в winmain ?

И вот еще:
Приложения для win32, написанные на ассемблере и собранные без runtime-библиотеки, работают в среде, несколько отличающейся от той, которая привычна программистам C/C++ и выше. Все дело в том, что runtime-библиотека в значительной мере занимается подготовкой этой среды. Вернее, не сама библиотека (это, конечно, не ее задача), а входящая в нее функция _WinMainCRTStartup. В частности, эта функция устанавливает значения четырех параметров функции WinMain, которую программист воспринимает как стартовую функцию приложения:

WinMain PROC PUBLIC hInstance,hPrevInstance,lpCmdLine,nCmdShow


и далее:
И вот все эти ценные и не очень параметры программисту на ассемблере недоступны. Сборка приложения без подключения runtime-библиотеки (например libc.lib) экономит от одного до нескольких десятков килобайт. Но тогда функция _WinMainCRTStartup не существует, а функция WinMain объявляется при сборке как точка входа. И следовательно, значения ее параметров неопределенны
И снова никакой WinMain в коде выше нет.



Ранг: 173.8 (ветеран), 208thx
Активность: 0.120.36
Статус: Участник

Создано: 05 июля 2017 16:22
· Личное сообщение · #4

Вот тут почитайте, достаточно понятно написано



Ранг: 1.8 (гость)
Активность: 0.010
Статус: Участник

Создано: 05 июля 2017 16:44
· Личное сообщение · #5

Точка входа может находиться по любому адресу, который вы укажите линкеру. Зачем обязательно вам какие то эфемерные WinMain etc. ?



Ранг: 12.0 (новичок)
Активность: 0.020
Статус: Участник

Создано: 05 июля 2017 16:56
· Личное сообщение · #6

>>0xC3
За точку входа то понятно, не совсем точно выразился.
0xC3 пишет:
Зачем обязательно вам какие то эфемерные WinMain etc. ?

Вот в этом то и заключается сам вопрос. Неоднозначность необходимости в коде асма стартовой WinMain (которая в С++ по любому должна быть), порядком озадачила.




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 05 июля 2017 17:09
· Личное сообщение · #7

shiroko

> И снова никакой WinMain в коде выше нет. Тогда что, метка start выступает в роли точки входа?

Так реально и нет никакой "WinMain".

Точка входа" это адрес, с которого начинается выполнение обработки, в вашем случае это адрес с которого начинается выполнение приложения. Обозвать его можно как угодно.

-----
vx




Ранг: 12.0 (новичок)
Активность: 0.020
Статус: Участник

Создано: 05 июля 2017 17:18
· Личное сообщение · #8

Отредактировал пост про точку входа, потому как понял что затупил, но все продолжают мне об этом напоминать)



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 05 июля 2017 20:03 · Поправил: dosprog
· Личное сообщение · #9

WinMain() получает управление от стандартной библиотеки С/C++.
Тогда как код библиотеки получает управление от самой системы после загрузки модуля.

Если код изначально ассемблерный, безо всяких RTL,
то там и нет никаких WinMain функций.





Ранг: -0.7 (гость), 170thx
Активность: 0.540
Статус: Участник

Создано: 05 июля 2017 21:19
· Личное сообщение · #10

v00doo пишет: без нее в си не заведутся вещи из немспейса std:

в си этого нет и вообще в стандарте нет, точку входа вполне можно писать самому, crt вариант для ленивых.

shiroko пишет: которая в С++ по любому должна быть

может лучше посмотреть драфт и не гадать? никто, никому, ничего не должен, пишите какую угодно точку входа, только не факт, что чья то реализация stl у вас заведется, поскольку подобные нюансы возложены на плечи авторов компилятора и отсутствие совместимости между реализациями вполне нормальное явление.



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 06 июля 2017 05:30 · Поправил: dosprog
· Личное сообщение · #11

shellstorm пишет:
никто, никому, ничего не должен


Должен.
В Си точка входа в код пользователя это main(), в MSC для Windows это по аналогии WinMain().
Это стандарт. Без извратов.

shiroko пишет:
In C/C++ programs, the label “WinMain” must be used but in assembler any label can be used






Ранг: -0.7 (гость), 170thx
Активность: 0.540
Статус: Участник

Создано: 06 июля 2017 16:49
· Личное сообщение · #12

dosprog пишет: В Си точка входа в код пользователя это main(), в MSC для Windows это по аналогии WinMain().
Это стандарт. Без извратов.


main всего лишь глобальное имя и которое нельзя переопределить, перегрузить, etc но его необязательно использовать, точку входа можно указать свою, да и требования скромные, возможность передать массив указателей и возврат int'a, есть еще несколько ограничений, но в данном случае несущественные, рекурсия, ограничение на получение адреса, etc. в общем анахронизм для поддержания совместимости.
WinMain это специфика платформы и с таким же успехом можно писать zalupa и указать имя как точку входа, эта хрень вообще к языку не имеет отношения.




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 06 июля 2017 19:38
· Личное сообщение · #13

Короче снова сишная идеология ввела в заблуждение.

-----
vx




Ранг: 58.0 (постоянный), 13thx
Активность: 0.020.01
Статус: Участник

Создано: 06 июля 2017 21:15 · Поправил: reverser
· Личное сообщение · #14

читаем отцов
The name WinMain is just a convention
https://blogs.msdn.microsoft.com/oldnewthing/20061204-01/?p=28853

Raymond Chen пишет:
Although the function WinMain is documented in the Platform SDK, it's not really part of the platform. Rather, WinMain is the conventional name for the user-provided entry point to a Windows program.
The real entry point is in the C runtime library, which initializes the runtime, runs global constructors, and then calls your WinMain function (or wWinMain if you prefer a Unicode entry point).


подробнее:
https://blogs.msdn.microsoft.com/oldnewthing/20110525-00/?p=10573


 eXeL@B —› Вопросы новичков —› Вопрос по WinMain
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати