Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.11.2023, 18:30   #11
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,777
По умолчанию

Цитата:
Сообщение от groverx Посмотреть сообщение
а выдает после функции CreateWindowExA. я позавчера об этом писал, см.выше..
Ошибка «Недопустимый дескриптор окна» смотрится странной в этом контексте. Окно там передается одно — hWndParent, оно может быть NULL.
Цитата:
Сообщение от groverx Посмотреть сообщение
Код:
        push offset klass
Тут разве не должно быть PUSH EAX — передавать класс, полученный от регистрации?

Я посмотрел пример MINPAD от FASM, там похожий кусок выглядит так:
Код:
	invoke	RegisterClass,wc
	test	eax,eax
	jz	error

	invoke	LoadMenu,[wc.hInstance],IDR_MENU
	invoke	CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,144,128,256,256,NULL,eax,[wc.hInstance],NULL
	test	eax,eax
	jz	error
В MASM нет макроса invoke, чтобы не извращаться?
Vapaamies на форуме Ответить с цитированием
Старый 10.11.2023, 18:55   #12
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
Ошибка «Недопустимый дескриптор окна» смотрится странной в этом контексте.
Она может не мочь создать окно.

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
Тут разве не должно быть PUSH EAX — передавать класс, полученный от регистрации?
Можно либо имя класса, либо атом.

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
В MASM нет макроса invoke, чтобы не извращаться?
Все есть. Оттуда он и пошел. Даже WNDCLASS описана нормально.
p51x вне форума Ответить с цитированием
Старый 11.11.2023, 14:51   #13
groverx
Пользователь
 
Регистрация: 08.11.2023
Сообщений: 24
По умолчанию

Цитата:
Я посмотрел пример MINPAD от FASM, там похожий кусок выглядит так:
Код:
invoke RegisterClass,wc
test eax,eax
jz error

invoke LoadMenu,[wc.hInstance],IDR_MENU
invoke CreateWindowEx,0,_class,_title,WS_V ISIBLE+WS_OVERLAPPEDWINDOW,144,128, 256,256,NULL,eax,[wc.hInstance],NULL
test eax,eax
jz error
В MASM нет макроса invoke, чтобы не извращаться?
В данном случае еах - это хендл меню. А класс задается как _class
А invoke - принципиально не буду, я ж писал, что хочу, чтоб был чистый ассемблер, безо всяких
макросов.
groverx вне форума Ответить с цитированием
Старый 11.11.2023, 15:09   #14
groverx
Пользователь
 
Регистрация: 08.11.2023
Сообщений: 24
По умолчанию

Цитата:
Ошибка «Недопустимый дескриптор окна» смотрится странной в этом контексте. Окно там передается одно — hWndParent, оно может быть NULL.
Ну оно и есть 0 у меня. Я уже подумал, что, может быть, неправильно номер ошибки вывел, так нет, прогнал программу дебуггером - всё правильно, код ошибки 0578h=1400d
Где-то в справочнике встречал, что ошибка может быть, если оконная функция некорректно обрабатывает сообщение WM_CREATE, может тут у меня что-то не так?
groverx вне форума Ответить с цитированием
Старый 11.11.2023, 15:42   #15
groverx
Пользователь
 
Регистрация: 08.11.2023
Сообщений: 24
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
Тут разве не должно быть PUSH EAX — передавать класс, полученный от регистрации?
Во всех учебниках передается offset на имя класса. Но я на всякий случай попробовал, как ты говоришь, запушить еах, который после регистрации. Мне вообще выдало ошибку системы (это ту, когда "приносим извинения, ляляля, отправить отчёт, не отправлять.." Короче - фигня какая-то, тем более, как я понял, там еще надо AddGlodalAtom вызывать, короче, геморрой полный..
groverx вне форума Ответить с цитированием
Старый 14.11.2023, 19:14   #16
groverx
Пользователь
 
Регистрация: 08.11.2023
Сообщений: 24
По умолчанию

ураураураураурауоауоа
Я сделал окно только что, в пол-первоного ночи проснулся, и дошло до меня.
Оказывается, процедура окна неправильно сообщения обрабатывала.
Я пользовался учебником В.Ю.Пирогова "Assembler для Windows", а там неправильно написано:
Цитата:
MOV EBP, ESP ; теперь EBP указывает на вершину стека
PUSH DWORD PTR [EBP+14H]; LPARAM (lParam)
PUSH DWORD PTR [EBP+10H]; WPARAM (wParam)
PUSH DWORD PTR [EBP+0CH]; MES (message)
PUSH DWORD PTR [EBP+08H]; HWND (hwnd)
CALL DefWindowProcA@16
А надо:
Цитата:
push dword ptr [ebp+10h]
push dword ptr [ebp+0ch]
push dword ptr [ebp+08h]
push dword ptr [ebp+04h]
call DefWindowProcA
И всё заработало, окно нарисовалось!
Поэтому и выдавало ошибку 0578h, что DefWindowProc искала дескриптор окна по адресу ebp+8, где его отродясь не было.
Спасибо всем, кто пытался мне помочь, буду продолжать дальше,и доставать вас своими тупыми вопросами!

Последний раз редактировалось groverx; 15.11.2023 в 00:57.
groverx вне форума Ответить с цитированием
Старый 15.11.2023, 01:09   #17
groverx
Пользователь
 
Регистрация: 08.11.2023
Сообщений: 24
По умолчанию

Если кому надо - вот готовая программа для окна на чистом ассемблере
Код:
.386
.model flat,stdcall
option casemap:none
;include E:\masm32\include\windows.inc  - не нужно

include E:\masm32\include\kernel32.inc
include E:\masm32\include\user32.inc
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\user32.lib

.data
er      DB "ошшшшшибкаааа",0
er1     DB "eeeerrrrrr",0
gav     DB "GAV!!!",0
mes     DB "тут",0
klass   DB "class",0
okno    DB "tipa_okno",0
wsz     DD 30h                       
wStil   DD 4003h                       ;стиль CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
wProc   DD 0                           ;процедура окна
        DD 0
        DD 0
wProg   DD 0                           ;хендл программы
wIkon   DD 0
wKurs   DD 0
wCvet   DD 11h                         ;цвет
wMenu   DD 0
wClass  DD 0
wik     DD 0

hOkno   DD 0
hProg   DD 0
msg     DD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0               ;нули про запас, много
x       DD 0      
kod   DB 030h,031h,032h,033h,034h,035h,036h,037h,038h,039h,041h,
         042h,043h,044h,045h,046h,0
rez   DB 0,0,0,0,0

.code
start:
        push 0
        call GetModuleHandleA
        mov [hProg],eax
        mov [wProg],eax
                                              ;регистрировать класс
        push 7f00h
        push 0
        call LoadIconA
        mov [wIkon],eax
        push 7f00h
        push 0
        call LoadCursorA
        mov [wKurs],eax     
        mov eax,offset klass
        mov [wClass],eax
        mov eax,offset okProc
        mov [wProc],eax
        mov eax,offset wsz
        push eax
        call RegisterClassExA
        cmp eax,0
        jz errr1
                                              ;создать окно
        push 0
        push [hProg]
        push 0
        push 0
        push 80000000h                        ;высота
        push 80000000h                        ;ширина
        push 80000000h                        ;Y
        push 80000000h                        ;X
        push 0cf0000h                         ;WS_OVERLAPPEDWINDOW    
        push offset okno
        push offset klass
        push 0
        call CreateWindowExA
        cmp eax,0
        jz errr

        mov [hOkno],eax                   
        push 1                                ;SW_SHOWNORMAL
        push [hOkno]                         
        call ShowWindow
        push [hOkno]
        call UpdateWindow

cikl:   push 0                                ;цикл
        push 0
        push 0        
        push offset msg
        call GetMessageA        
        cmp eax,0
        jz vyh
        push offset msg
        call TranslateMessage
        push offset msg
        call DispatchMessageA
        jmp cikl

okProc: mov ebp,esp
        cmp dword ptr [ebp+08h],2               ;wm_destroy
        jz des
        push dword ptr [ebp+10h]
        push dword ptr [ebp+0ch]
        push dword ptr [ebp+08h]
        push dword ptr [ebp+04h]
        call DefWindowProcA
        jmp retur
des:    push 0
        call PostQuitMessage
retur:  ret        
        
vyh:    push 0
        call ExitProcess

soob:   push 30h
        push offset mes
        push offset gav
        push 0  
        call MessageBoxA
        ret
        
errr:   call GetLastError
        mov  [x],eax
        mov edx, [x]
     mov ebx, offset kod                                ; перевод EAX  в текст
     mov eax, edx
     and eax, 0fh
     mov al, [ebx+eax]
     mov [rez+3], al
     mov eax, edx
     and eax, 0f0h
     shr eax,4
     mov al, [ebx+eax]
     mov [rez+2], al
     mov eax, edx
     and eax, 0f00h
     shr eax,8
     mov al, [ebx+eax]
     mov [rez+1], al
     mov eax, edx
     and eax, 0f000h
     shr eax,12
     mov al, [ebx+eax]
     mov [rez], al
        push 30h
        push offset er
        push offset rez
        push 0  
        call MessageBoxA
        jmp vyh

errr1:  push 30h
        push offset er1
        push offset er1
        push 0  
        call MessageBoxA
        jmp vyh          
end start
Vapaamies, выдыхай, бобер, выдыхай! )))))

Последний раз редактировалось groverx; 15.11.2023 в 01:11.
groverx вне форума Ответить с цитированием
Старый 15.11.2023, 08:26   #18
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от groverx Посмотреть сообщение
Я пользовался учебником В.Ю.Пирогова "Assembler для Windows", а там неправильно написано
Так Пирогов сначала сохраняет EBP на стек, а потом уже отсчитывает адреса, а вы не сохраняете и не восстанавливаете EBP. И почему вы не соблюдаете stdcall, не очищая стек после вызова okProc?
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 16.11.2023, 07:30   #19
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от groverx Посмотреть сообщение
вот готовая программа для окна на чистом ассемблере
Это прикол такой?
160-строк кода, чтобы показать пустое окно? Пересмотрите свои методы программирования, или займитесь в этой жизни чем-нибудь другим. Комп с компилятором должны работать на вас, а здесь (отказываясь от invoke) наоборот вы отдаёте себя им в жертву. Боюсь представить размер этого исходника, если добавить в окно пару-тройку элементов управления, с процедурами их обработки.

Во-первых, для обычных форточек практичней использовать "диалоговые окна" вызовом DialogBoxParam(), тогда избавляешься сразу от: RegisterClass(), CreateWindow(), GetMessage(), TranslateMessage(), DispatchMessage().

Во-вторых, чтобы не создавать в последующем отдельные элементы окна чз десятки вызовов CreateWindow(), нужно использовать "секцию ресурсов". А обработчик GetLastError() в хвосте завершил всю "прелесть" данного кода. Есть-же специальные API для перевода из hex в строку (например тот-же wsprintf() из user32.dll).

Чтобы расшифровать код-ошибки и сбоксить его в текстовом виде, имеется FormatMessage(). Например такая процедура на этапе отладки, будет возвращать характер последней ошибки в более понятной форме:

Код:
; fasm-code
;------------
.data
;......
errMes     rb   256
buff       rb   32   

.code
;......
proc  GetError
        pusha
        invoke  GetLastError
        push    eax
        invoke  FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,eax,0,errMes,256,0
        pop     eax
       cinvoke  wsprintf,buff,<'Error code:  hex = 0x%08X, dec = %u',10,\
                               '%s',0>,eax,eax,errMes
        invoke  MessageBox,0,buff, <'Get-Last-Error',0>,MB_ICONWARNING
        popa
        ret
endp
Изображения
Тип файла: png eCode.png (6.5 Кб, 22 просмотров)
Нашедшего выход - затаптывают первым..

Последний раз редактировалось R71MT; 16.11.2023 в 11:34.
R71MT вне форума Ответить с цитированием
Старый 16.11.2023, 07:32   #20
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
И почему вы не соблюдаете stdcall, не очищая стек после вызова okProc?
а зачем ему это, если код и так работает?
ведь всякие там макросы и соглашения о вызовах придуманы чисто для ламеров.
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос от новичка Валерий718 Помощь студентам 4 23.10.2013 19:28
Вопрос новичка geranton Общие вопросы Delphi 2 23.03.2012 14:00
Вопрос новичка vaultboy2010 Общие вопросы C/C++ 3 02.10.2011 01:51
Создание функции вопрос от новичка C CKent Общие вопросы C/C++ 2 07.12.2008 17:31