IceStudent Речь шла о WinMain, а в 3м уроке Iczelion'а EP != WinMain, как ты сам заметил. _SaNitAr Структуры DX должны быть выровнены на границу параграфа, о чём упоминается в msdn. Поэтому не надо путать вольность с грубым нарушением правил
2 Quantum имелось ввиду заполнение D3DPRESENT_PARAMETERS ручками, без GetAdapterDisplayMode, и проверок на количество памяти, D3DCAPS9 на предмет шейдеров и тд итп. что то я не догоняю причем здесь выравнивание? невыравненные данные медленно -это да, но что б от этого не запускаться? 8[ ] что то мы не в тему уже))))
_SaNitAr И такое происходит не только в DX. Ещё при использовании DMA всегда нужно учитывать выравнивание, а нето работать не будет.
2 Quantum честно говоря про DX такого не слышал, покопаю SDK, хотя DX наверняка использует DMA? так что мэйби.
А вот так покороче будет, у меня получилось 832 байта на ml + Polink Код (Text): .686P .model flat includelib user32.lib include windows.inc extern _imp__CreateWindowExA@48:dword extern _imp__DefWindowProcA@16:dword extern _imp__DispatchMessageA@4:dword extern _imp__GetMessageA@16:dword extern _imp__PostQuitMessage@4:dword extern _imp__RegisterClassA@4:dword .code start: xchg ebx,eax lea edi,style assume edi:ptr WNDCLASSA push edi call _imp__RegisterClassA@4 mov ecx,CW_USEDEFAULT push ebx push [edi].hInstance push ebx push ebx push ecx push ecx push ecx push ecx push WS_OVERLAPPEDWINDOW + WS_VISIBLE push offset szWinTitle push [edi].lpszClassName push ebx call _imp__CreateWindowExA@48 ;создать окно add edi,sizeof WNDCLASSA;lea edi,msg message_loop: push ebx ;цикл обработки сообщений push ebx push ebx push edi call _imp__GetMessageA@16 xchg eax,ecx jecxz short exit_msg_loop push edi call _imp__DispatchMessageA@4 ;вернуть управление Windows jmp short message_loop exit_msg_loop: ret WndProc proc ;hwnd:DWORD, Msg:DWORD, wParam:DWORD, lParam:DWORD cmp dword ptr [esp+8],WM_DESTROY;cmp Msg,WM_DESTROY je short @@WM_DESTROY jmp _imp__DefWindowProcA@16 ;все сообщения, не обрабатываемые в функции WndProc, направляются на обработку по умолчанию @@WM_DESTROY: push 0 ;завершение программы call _imp__PostQuitMessage@4 retn 10h WndProc endp ;WNDCLASSA ----------------------------------------------- style dd CS_HREDRAW or CS_VREDRAW; Стиль нашего окна lpfnWndProc dd WndProc;Адрес процедуры обработки событий cbClsExtra dd 0 ;Эта хрень нам не нужна cbWndExtra dd 0 ;и эта тоже hInstance dd 400000h ;Адрес нашей проги в памяти (Windows всегда её грузит по этому адресу) hIcon dd 10003h ;Иконка окна по умолчанию hCursor dd 10011h ;Курсор окна по умолчанию (здесь указан ID обычной стрелки) hbrBackground dd COLOR_WINDOW+1 ;Фон нашего окна lpszMenuName dd 0 ;Меню у нас отсутствует lpszClassName dd szWinClass; Указатель на имя нашего класса ;---------------------------------------------------------- msg MSG <> szWinTitle db 'Our First Window',0 szWinClass db 'SimpleWinClass',0 end start тег [ code ] для кого придумали?
Кстати , по поводу Зубкова с : http://openlib.org.ua/ru/books/category/ Совсем не 18Мб.После реги там дают ссылку на Рапидшару . И с неё качается 1.2 Мб файлик . Hlp + asm примеры . "Ассемблер для dos , windows и unix " называется.
Люди помогите пожалуйста. Вот мой код: Код (Text): .386 .model flat, stdcall option casemap: none ;===== ??????? ===== include masm32\include\windows.inc; include masm32\include\user32.inc; include masm32\include\kernel32.inc; include masm32\include\gdi32.inc; include masm32\include\comdlg32.inc; include masm32\include\shell32.inc; includelib masm32\lib\user32.lib; includelib masm32\lib\kernel32.lib; includelib masm32\lib\gdi32.lib; includelib masm32\lib\comdlg32.lib; includelib masm32\lib\shell32.lib; ;===== ?????? ===== .data? $hInstance dword ? ; ????? ?????? $hIcon dword ? ; ????? ?????? $hCursor dword ? ; ????? ??????? $hbrBackground dword ? ; ????? ???? h_wnd dword ? ; ????? ???? $message dword ? $wparam dword ? $lparam dword ? $time dword ? .data $ClassName db "MyFirstClass",0 $MenuName db "Hz",0 $WindowName db "My window!",0 ;===== ?????? ???? ===== .code start: ;===== ??? ??? ????????? ===== ;===== ????? ?????? ??????, ??????, ???????, ???? ===== push 0 call GetModuleHandle mov $hInstance, eax push 0 push 0 call LoadIcon mov $hIcon, eax push 0 push 0 call LoadCursor mov $hCursor, eax push 333333h call CreateSolidBrush mov $hbrBackground, eax ;===== ???????????? ????? ===== push offset $ClassName push offset $MenuName push $hbrBackground push $hCursor push $hIcon push $hInstance push 0 push 0 push WindowProc push CS_HREDRAW or CS_VREDRAW call RegisterClass ;===== ??????? ???? ===== push 0 push $hInstance push 0 push 0 push CW_USEDEFAULT push CW_USEDEFAULT push CW_USEDEFAULT push CW_USEDEFAULT push WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SYSMENU push offset $WindowName push $ClassName push 0 call CreateWindowEx mov h_wnd, eax ;===== ?????????? ???? ? ????????? ===== push SW_SHOWNORMAL push $hwnd call ShowWindow push $hwnd call UpdateWindow ;===== ???? ????????? ===== @GetM: push 0 push 0 push 0 push $time push $lparam push $wparam push $message push $hwnd call GetMessage cmp eax, 0 je @Exit push $time push $lparam push $wparam push $message push $hwnd call TranslateMessage push $time push $lparam push $wparam push $message push $hwnd call DispatchMessage jmp @GetM @Exit: push $wparam call ExitProcess ;===== ??????? ????????? ????????? ===== WindowProc proc $wnd:dword, $message:dword, $wparam:dword, $lparam:dword cmp $message, WM_CREATE je @wm_create cmp $message, WM_DESTROY je @wm_destroy push $lparam push $wparam push $message push $wnd call DefWindowProc ret @wm_create: xor eax, eax ret @wm_destroy: push 0 call PostQuitMessage ret WindowProc endp ;===== ????? ????????? ===== end start Помогите пожалуйста найти ошибки, а то не компилится
Loginanton А что это за ассемблер со знаками $ перед переменными? И какие ошибки (какие сообщения) при компиляции выдает? И каким батничком ты компилируешь и линкуешь? А из ошибок в твоем сорце - функция GetMessage должна получить 4 параметра (три нуля и указатель на message ), а функции TranslateMessage и DispatchMessage должны получить по 1 параметру - указатель на message (т.е offset $message) функция CreateWindowEx должна поучить указатель на $ClassName, а не содержимое переменной и т.д. тут туева куча ошибок, набирай внимательней, и посмотри на мой ответ #25 в этом топике
Mikl__ это масм я просто ставлю перед переменными знак $, чтоб лучше их видеть - это удобно Насчёт входящих параметров - по количеству всё вроде правильно, просто я пушаю без использования структур, тоесть в стек не структуру MSG кладу, а каждый ею часть
Mikl__ из ошибок в твоем сорце ... Эти ошибки полезут на этапе выполнения, а тут пока еще "не компилится". Loginanton найти ошибки Разве компилятор их не нашел?
Loginanton $ - предопределенная метка, поддерживаемая большинством ассемблеров. Она всегда соответствует текущему адресу. Т.е., команда jmp $ выполняет безусловный переход на саму себя, так что создается вечный цикл из одной команды. Поэтому лучше не использовать его в именах переменных. Из перечисленных у тебя библиотек: user32.lib, kernel32.lib, gdi32.lib, comdlg32.lib, shell32.lib реально в твоей программе используются kernel32 (функции GetModuleHandle, ExitProcess) gdi32 (CreateSolidBrush) и user32 (все остальные). На твой ответ - "я написал их в расчете на будущее", могу ответить, "тогда почему ты не перечислил все библиотеки в каталоге masm32/lib там их 222?". Реально можно было обойтись только user32. Как это сделать и другие полезные советы читай здесь Ты конешно можешь делать всё, что захочешь, но вот Windows требуется адрес структуры MSG, чтобы она поместила туда свои значения для твоей программы. Если тебе охота извращаться, тогда Код (Text): ; твой код |; должно быть push offset $ClassName | push offset ClassName push offset $MenuName | push offset MenuName push $hbrBackground | push hbrBackground push $hCursor | push hCursor push $hIcon | push hIcon push $hInstance | push hInstance push 0 | push 0 push 0 | push 0 push WindowProc | push offset WindowProc <- должно быть так push CS_HREDRAW or CS_VREDRAW | push CS_HREDRAW or CS_VREDRAW call RegisterClass |push esp<-а это указатель на структуру WNDCLASS | call RegisterClass если охота расписывать структуру MSG (хотя IMHO запись message MSG <?> намного короче) тогда Код (Text): ; твой код |должен быть заменен на $message dword ? |hwnd DWORD ? $wparam dword ? |message DWORD ? $lparam dword ? |wParam DWORD ? $time dword ? |lParam DWORD ? |time DWORD ? |x DWORD ? |y DWORD ? и компилятор, кстати, жалуется на отсутствие в твоем листинге переменной hwnd а когда требуется указатель на структуру MSG, ты должен передать offset hwnd, а не заниматься самостоятельным проталкиванием в стек push $time push $lparam push $wparam push $message
Люди вот код: Код (Text): .386 .model flat, stdcall option casemap :none ;===== инклуды ===== includelib masm32\lib\user32.lib includelib masm32\lib\kernel32.lib includelib masm32\lib\gdi32.lib include masm32\include\windows.inc include masm32\include\user32.inc include masm32\include\kernel32.inc include masm32\include\gdi32.inc ;===== данные ===== ;===== значком @ я обозначаю переменные и метки ===== .data? @hInstance dword ? ; хендл модуля @hIcon dword ? ; хендл иконки @hCursor dword ? ; хендл курсора @hbrBackground dword ? ; что то типа хендла цвета фона @hwnd dword ? ; хендл создаваемого окна @lParam dword ? ; параметр какой то @wParam dword ? ; параметр какой то @message dword ? ; тут будут содержатся всякие вм_крит и т.п. .data @lpszClassName db "MyClass",0 @WindowName db "My window :D",0 .code start: ;===== код программы ===== ;===== берём хендлы всего что нам пригодится ===== push 0 call GetModuleHandle mov @hInstance, eax push 0 push 0 call LoadIcon mov @hIcon, eax push 0 push 0 call LoadCursor mov @hCursor, eax push 0ff6600h call CreateSolidBrush mov @hbrBackground, eax ;===== регистрируем класс ===== push offset @lpszClassName push 0 push offset @hbrBackground push offset @hCursor push offset @hIcon push offset @hInstance push 0 push 0 push WndProc ; адрес процесса обработки push CS_HREDRAW or CS_VREDRAW call RegisterClass ;===== создаём окно ===== push 0 push offset @hInstance push 0 push 0 push CW_USEDEFAULT push CW_USEDEFAULT push CW_USEDEFAULT push CW_USEDEFAULT push WS_VISIBLE or WS_SYSMENU push offset @WindowName push offset @lpszClassName push 0 call CreateWindowEx mov @hwnd, eax ;===== показываем окно ===== push SW_SHOWNORMAL push offset @hwnd call ShowWindow ;===== обновляем содержимое окна ===== push offset @hwnd call UpdateWindow ;===== запускаем вечный цикл приёмопередачи сообщений ===== @LOL: push 0 push 0 push 0 push offset @hwnd push offset @message push offset @wParam push offset @lParam call GetMessage cmp eax, 0 je @Exit push offset @hwnd push offset @message push offset @wParam push offset @lParam call TranslateMessage push offset @hwnd push offset @message push offset @wParam push offset @lParam call DispatchMessage jmp @LOL @Exit: push offset @wParam call ExitProcess ;===== процесс обработки сообщений ===== WndProc proc hwnd: dword, message: dword, wParam: dword, lParam: dword cmp message, WM_CREATE je @wm_create cmp message, WM_DESTROY je @wm_destroy push lParam push wParam push message push hwnd call DefWindowProc ret @wm_create: xor eax, eax ret @wm_destroy: push 0 call PostQuitMessage ret WndProc endp end start Никаких ошибок при компиляции нету, но программа ничего не делает Тоесть она не выводит никакого окна, хотя должна помогите пожалуйста разобраться и скажите что где надо дописать, чтоб всё было норм
эта программа не должна Loginanton структура и указатель на структуру - две большие разницы. Если GetMessage и RegisterClass ждут указатель на структуру, то они используют первый параметр как указатель, а так как он указывает на черт знает что, возникает исключение, и RegisterClass завершается с ошибкой, и класс окна незарегистрирован, и CreateWindowEx о нем не знает, вот и окна нету. Вот если делаете структуру в стэке, то, как советовал Mikl__, push esp тогда даст её указатель.. но тогда память в стэке кто освобождать будет? До enter/leave или add esp, sizeof WNDCLASS навряд ли дойдет... Да и в случае GetMessage простой push esp не спасет... Пока что не гонитесь за экономией, создайте структуры в секции данных, а функциям передавайте указатели на них P.S. Вот, свободу почувствовали.. нету проверки типов... С бы ругался на ваше RegisterClass(wc.style, wc.lpfnWndProc, wc.cbClsExtra, ...) вместо RegisterClass(&wc)
Loginanton зря ты отредактировал предыдущее сообщение ведь там ты клятвенно обещал, что будешь во всем разбираться. В первую очередь, нужно было без поправок набрать упражнение из 3-го урока Iczeliona, добиться чтобы оно заработало, а уже потом начинать собственные эксперименты над работающей программой. Теперь, то что касается ошибок, но это все IMHO, многие на этом форуме будут со мной несогласны Код (Text): .386 .model flat ;отсутствие stdcall компенсируется ключем "ml /Gz" ;option casemap :none можно убрать - отсутствие компенсируется ключем "ml /Cp". includelib user32.lib ; includelib kernel32.lib ;полный путь указывается в строке "link /LIBPATH:c:\masm32\lib" include windows.inc include user32.inc include kernel32.inc ;полный путь указывается в строке "ml /Ic:\masm32\include", ;обойдемся без всех данных в .data? ;.data? ;@hInstance dword ? ; хендл модуля ;@hIcon dword ? ; хендл иконки ;@hCursor dword ? ; хендл курсора ;@hbrBackground dword ? ; что то типа ;@hwnd dword ? ; хендл создаваемого окна ;@lParam dword ? ; параметр какой то ;@wParam dword ? ; параметр какой то ;@message dword ? ; .data ;@lpszClassName db "MyClass",0 обойдемся без @lpszClassName @WindowName db "My window :D",0 ;вместо MyClass можно использовать "Mywindow :D" .code start: ;push 0 без вызова GetModuleHandle можно обойтись, так как он ;call GetModuleHandle возвращает в @hInstance заранее известное число 400000h ;mov @hInstance, eax ;класически должно быть так push IDI_APPLICATION ; push NULL ; call LoadIcon ;mov @hIcon, eax ;и под Win98 и под Win XP в @hIcon будет возвращено 10003h ;класически должно быть так push IDC_ARROW ; push NULL ;call LoadCursor ;mov @hCursor, eax ;и под Win98 и под Win XP в @hCursor будет возвращено 10011h ;push 0ff6600h ; можно не вызывать ;call CreateSolidBrush ; ;mov @hbrBackground, eax ;для первого окна сойдет константа COLOR_WINDOW push offset @WindowName push 0 push COLOR_WINDOW push 10011h push 10003h push 400000h push 0 push 0 push offset WndProc ;<- должен быть offset push CS_HREDRAW or CS_VREDRAW push esp ;здесь обязательно должен быть указатель на структуру WNDCLASS ;которую создали в стеке и между прочим я об этом говорил call RegisterClass push 0 push 400000h push 0 push 0 push CW_USEDEFAULT push CW_USEDEFAULT push CW_USEDEFAULT push CW_USEDEFAULT push WS_VISIBLE or WS_OVERLAPPEDWINDOW push offset @WindowName push offset @WindowName;обходимся без @lpszClassName push 0 call CreateWindowEx ;mov @hwnd, eax ;использование стиля WS_VISIBLE делает ненужным ShowWindow ;и UpdateWindow ;push SW_SHOWNORMAL ;push offset @hwnd <- здесь должно быть push @hwnd ! ;call ShowWindow ;push offset @hwnd <- здесь должно быть push @hwnd ! ;call UpdateWindow mov ebp,esp; помещаем указатель на структуру MSG в ebp @LOL: push 0 push 0 push 0 push ebp call GetMessage ;cmp eax, 0 выход из программы обработаем в WndProc ;je @Exit ;так как, не проверяем нажатие клавиш TranslateMessage ; нам ни к чему ;push offset @hwnd <- про эту хрень тебе уже говорили ;push offset @message ;push offset @wParam ;push offset @lParam ;call TranslateMessage ; опять пытаешься пихать в стек переменные вместо указателя ;push offset @hwnd ;push offset @message ;push offset @wParam push ebp;push offset @lParam call DispatchMessage jmp @LOL ;выход из программы обработаем в WndProc ;@Exit: push offset @wParam ;call ExitProcess WndProc proc ;WndProc proc hwnd, message, wParam, lParam ;cmp message, WM_CREATE ;je @wm_create cmp dword ptr [esp+8],WM_DESTROY;cmp message, WM_DESTROY je @wm_destroy ;Для функции DefWindowProc передаются те же параметры, что и для функции WndProc, ;поэтому достаточно будет поставить jmp вместо call ;push lParam ;push wParam ;push message ;push hwnd jmp DefWindowProc;call DefWindowProc ;ret ;@wm_create: чушь собачья! ;xor eax, eax ;ret @wm_destroy: push 0 call ExitProcess;call PostQuitMessage ;ret WndProc endp end start В аттаче батник, которым программа собиралась, сорц и ехе на тот случай если кто-то будет говорить, что так не должно работать q_q спасибо за подсказку
Mikl__ + обрамить .nolist include windows.inc ... .list - никто не будет рад мегабайтной добавке к листингу.
Вот код программы: Код (Text): .386 .model flat, stdcall option casemap: none ;===== инклуды ===== include masm32\include\windows.inc include masm32\include\user32.inc include masm32\include\kernel32.inc include masm32\include\gdi32.inc includelib masm32\lib\user32.lib includelib masm32\lib\kernel32.lib includelib masm32\lib\gdi32.lib ;===== данные ===== .data? hInstance dword ? ; хендл модуля hIcon dword ? ; хендл иконки hCursor dword ? ; хендл курсора hbrBackground dword ? ; хендл фона hwnd dword ? ; хендл создаваемого окна msg CWPSTRUCT <> ; структура сообщения wc WNDCLASS <> ; структура для создания класса .data WindowName db "Моё окошко",0 lpszClassName db "Мой класс",0 .code start: ;===== код программы ===== ;===== берём хендлы ===== invoke GetModuleHandle, 0 mov hInstance, eax invoke LoadIcon, 0, 0 mov hIcon, eax invoke LoadCursor, 0, 0 mov hCursor, eax invoke CreateSolidBrush, 0ff6600h mov hbrBackground, eax ;===== создаём класс ===== mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, offset WndProc ; <================================ mov wc.cbClsExtra, 0 mov wc.cbWndExtra, 0 mov wc.hInstance, offset hInstance mov wc.hIcon, offset hIcon mov wc.hCursor, offset hCursor mov wc.hbrBackground, offset hbrBackground mov wc.lpszMenuName, 0 mov wc.lpszClassName, offset lpszClassName invoke RegisterClass, addr wc ;===== создаём окно ===== invoke CreateWindowEx, 0, addr lpszClassName, addr WindowName, WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, addr hInstance, 0 mov hwnd, eax ;===== показываем окно и обновляем содержимое ===== invoke ShowWindow, addr hwnd, SW_SHOWNORMAL invoke UpdateWindow, addr hwnd ;===== вечный цикл обмена сообщений ===== @LOL: invoke GetMessage, addr msg, 0, 0, 0 cmp eax, 0 je @Exit invoke TranslateMessage, addr msg invoke DispatchMessage, addr msg jmp @LOL @Exit: invoke ExitProcess, msg.wParam ;===== обработка сообщений ===== WndProc proc @hwnd :dword, @message :dword, @wparam :dword, @lparam :dword cmp @message, WM_DESTROY je @wm_destroy invoke DefWindowProc, @hwnd, @message, @wparam, @lparam @wm_destroy: invoke PostQuitMessage, 0 WndProc endp end start Вроде всё правильно, но линковщик пишет ошибку: fatal error LNK1104: cannot open file "prax1.exe" Помогите пожалуйста разобраться в чём дело
Loginanton Ищи ошибки сам - это не десткий сад, еще раз повторяю, где текст батника которым, ты компилируешь и линкуешь, откуда мне знать на какой ты "prax1.exe" ссылаешься invoke ShowWindow, addr hwnd, SW_SHOWNORMAL <- откуда здесь и на следующей строке invoke UpdateWindow, addr hwnd <- addr hwnd (указатель на hwnd, а не сама переменная ) CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, addr <- откуда указатель на hInstance взялся, а это что за перлы? invoke LoadIcon, 0, 0<-разве так в исходном тексте? mov hIcon, eax | invoke LoadCursor, 0, 0<- mov hCursor, eax
Loginanton Нажми Ctrl+Alt+Del и найди среди запущенных процессов prax1.exe Погаси его, удали prax1.exe, исправь ошибки и снова создай, и так до тех пор, пока не создашь своё первое окно