Прочитал 3-й урок Iczelion'a по созданию простого окна и никак не могу понять некоторых вещей. Но не могу читать дальше его уроки пока не пойму до конца как все это работает. Я в принципе не совсем новичек в ассемблере, но под Win32 первый раз пробую. По порядку: 1)До объявления главной функции WinMain все понятно, но вот внутри ее начинаются непонятки в частности : WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShowWORD Почему здесь всего 4 параметра, а не 5 и не 2, ведь это не API функция(как я понял), где число параметров строго прописано в MSDN(если не ошибаюсь), а функция которую программист сам создает, т.е. можно было и больше параметров прописать и если можно то сколько? 2)Далее непонятно где и кем используется структура wc, сначала я уже подумал что структуру использует функция CreateWindowEx, которая создает класс окна. Но потом меня одолели сомнения основанные на таком рассуждении:Каждая переменная в любом языке програмирования должна иметь 3 параметра А)Имя; Б)Тип; В)Значение; А что получается тут : mov wc.cbSize,SIZEOF WNDCLASSEX ; заполнение стpуктуpы wc. Здесь есть имя и значение переменной А вот передача первого параметра функции CreateWindowEx : invoke CreateWindowEx,NULL,\ ;так что же здесь опять передача значения переменной(параметра) функции? Я думал что эта функция берет значения из членов структуры wc.(( Или я неправ? Но если так то почему 2 значения одному параметру? И кстати зачем тут стоит слеш в конце каждого параметра? 3)Также непонятны конструкции типа: .WHILE TRUE ; ...код... .BREAK .IF (!eax) ...код... .ENDW Вообще-то я немного знаю паскаль, но причем здесь ассемблер, ведь тут должны быть loop, jnz,cmp и т.д., что значит eax с восклицательным знаком и почему регистр в скобках и вообще где взять описание таких конструкций? Вот в принципе и все, если конечно не брать мелочных вопросов касающихся названий параметров для API функций, они взяты от балды или тоже прописаны в MSDN? Уроки Iczelion'a можно скачать на этом же сайте. Уважаемые гуру и просто смертные поможите знаниями или укажите направление откуда их взять(сам знаю что www.google.ru
1) автор использовал аналог стандартной WinMain int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // pointer to command line int nCmdShow // show state of window ); 2) invoke RegisterClassEx, addr wc 3) ! - значит отрицание а .IF/.ENDIF .WHILE/.ENDW макросы, которые отличают макроассемблер от просто ассемблера
1)Что означает int, насколько я помню так вызывались прерывания в DOS'е? 2) И что означает "стандартная WinMain" - т.е. API функция из MSDN? 3)А где все таки посмотреть описание макросов, а то не понимаю до конца зачем в коде вот эта строка ".BREAK .IF (!eax)"
kos 1. WinMain proc ее вызывает операционная ситема поэтому должны быть стандарты, видимо. 2. invoke RegisterClassEx,addr wc - здесь. ОС должна же знать кто это?, отправлять сообщения, получать ответы и т.п. Вообще в функции передаются не названия, а значения параметров, так что названия носят чисто информативный характер, напр. hWnd, hDc - h обычно означает Handle, и т.д. Этот сайт практически необходимое и достаточное условие успешного программирования на асме (не считая МСДН для Вин32).
kos Это строка из МСДН, там С++, int(С++) = integer(Pascal) = DWORD, DD (ASM) То же самое, что и в паскале. .while .endw .if .elseif .elseif ... .endif Да и в комплекте с МАСМ хелп есть.
Не хотел начинать , обращаясь с подобными вопросами к местным долгожителям . Но раз топикстартер спросил , и его не расстреляли .... Ну что ж ... Тему , таки , как для меня делали . Вот наши 2 копейки : 1. С макросами и правда ничерта не ясно . Гр. Iczelion этот вопрос игнорирует . Типа разбирайтесь , как хотите .Serrgio респект , у него все понятно. Вообще , что читать , после Iczelion'a? Имея на руках подборку с Cracklab , местную и Калашникова рыпаюсь по разным руководствам , глаза разбегаются. 2. Более общее. Меня терзают смутные сомнения ... Если прога компилируется под win32 , тогда все , что я могу делать - обращаться к Api ? Т е по сути я становлюсь заложником готовых функций . Или есть более общие приемы программирования под win ? Можно ли как-то окольно обращаться к прерываниям ?
Hmm Программировать на ассемблере можно и без макросов, и я бы даже сказал, что на первых порах лучше обходиться без них, т.к. чистый код облегчает отладку и способствует усваиванию. После Iczelion'а лучше сразу переходить на фасм, т.к. на него всё равно придётся перейти рано или поздно... Можно вызывать системные функции, но у них номера меняются чуть ли не в каждом сервис-паке. Поэтому, лучше по возможности использовать стандартные API. Из 0-го кольца много чего можно делать, но нужно ли?
В справке, которая идёт с masm32. Hmm Статьи из этого сайта, посвящённые win32, компиляторам и т.п. - развивает. Практически, да - потому программы под вин32 и называются "приложениями". Хотя в процессе изучения будут проявляться ньюансы.
еще раз повторю http://openlib.org.ua/ru/books/category/10/3/ автор Зубков "Assembler язык неограниченных возможностей" весит 16мегов а лучше не пожалей денег купи книжку(это имхо лучшая книжка по асму для начинающих) совершенно согласен с Quantum, пробуй без макоросов, когда надоест писать в столбик кучу команд придут макросы)))
Благодарю почтенные. 2Qantum: Просто если потребуется вытворить чтото , что функции MS запрещают . Вот тут не совсем очевидно пока , в каком направлении люди действуют. (С другой стороны , работает же как то SoftIce). 2IceStudent: Статьи это да. Но когда они начинают повторять друг друга , вот это несколько раздражает . 2_SaNitAr: Обязательно посмотрю . Тем более , если лучшая . Весьма признателен за линку .
Hmm Каждый автор пишет по своему. У вас есть выбор. Когда вы идете в магазин, на витрине апельсиновый сок, при чем производители разные. Выбор есть. (про финансы - другой вопрос)
Вот кусок из урока .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_PAINT invoke BeginPaint,hWnd, ADDR ps mov hdc,eax invoke GetClientRect,hWnd, ADDR rect invoke DrawText, hdc,ADDR OurText,-1, ADDR rect, \ DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint,hWnd, ADDR ps .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax, eax ret конечно грубовато, но логика думаю понятна \\\.IF uMsg==WM_DESTROY cmp uMsg,WM_DESTROY \\\сравниваем c сообщением WM_DESTROY ( можно с 2, но так наглядней) jz Exit \\\ если равно переходим на метку Exit \\\.ELSEIF uMsg==WM_PAINT cmp uMsg,WM_PAINT \\\ тоже самое, что и с WM_DESTROY jz Repaint Window \\\.ELSE если не равно этим условиям(сообщениям) вызываем дефолтную обработку сообщений invoke DefWindowProc,hWnd,uMsg,wParam,lParam Exit: invoke PostQuitMessage,NULL Repaint Window:\\\ итд итп Что бы посмтреть во что на самом деле, превратились все эти .IF итд, качни отладчик Olle со странички Wasmа и посмотри код. Без отладчика будет туговато. "Просто если потребуется вытворить чтото , что функции MS запрещают " Вообщем то они больше разрешают))) В основном такая необходимость возникает при написании драйверов к девайсам. Пробовал как то, быстро остыл)))) MS основательно облегчил жисть кодеров(ну где то и осложнил конечно), поробуй написать под DOS оконный интерфейс)),время уйдет просто море, а тут раз два и все есть. Кодеры просто не отвлекаются на такие тривиальные уже весчи, занимаются тем,что в основном должны-логикой прог и удобным интерфейсом.
(Эх , траффик мой кончается , сейчас я упаду .) 2_SaNitAr: Респект от меня и всех асмовых ньюбов . Примерно так я себе это и представлял .Попробую , как только баланс пополню .
Непохоже чтобы WinMain() вызывался операционной системой. В FASM-е, например, нет никакого WinMain() и всё прекрасно работает.
2 AsmGuru62 Хе ))) WinMain() в асме это скорее дань C++, в MASM она тоже не нужна, все что тебуется это обрабатывать события.Внимательно читаем Iczelionа.+ В RadAsme удобно скрыть этот кусок, чтобы не маячил перед глазами.
AsmGuru62 Ось не может вызвать функцию, которая даже не экспортируется. Хотя есть ТАСМ, который любит всё экспортировать, но это скорее исключение из общего правила.
AsmGuru62 WinMain вызывается CRT, если приложение не консольное, поэтому и прототип соответствующий. Для консольного main, как известно. Реальная же точка входа, определённая в CRT, имеет более простой прототип: int mainCRTStartup(void); Собственно, он и вызывается системой. Quantum Ну, точках входа и без экспорта известна ведь. Вот её и вызывает система. kos Смотри внимательнее сорцы. Точка входа объявлена просто: start. А WinMain уже вызывается самостоятельно. Вообще, Iczelion пишет по аналогу с си, поэтому и пытается всячески имитировать стандартный подход. Ты же можешь писать более свободно, когда научишься.
2 IceStudent "Вообще, Iczelion пишет по аналогу с си" Ничего плохого в этом нет, лишний код чуток. Срр знать основы полезно, сорцы то в основном на нем. К тому же вольности например с заполнением структур DX, приводят к отказу запускаться на некотрых машинах. Лано палемика.