Прикольный калькулятор, скачал себе. Mikl___, не получается откомпилировать программу. Использую следующий BAT файл: Код (DOS): cls set masm64_path=\masm64\ set filename=%~n1 %masm64_path%bin\ml64 /Cp /c /I"%masm64_path%Include" %filename%.asm > errors.txt pause if errorlevel 1 exit %masm64_path%bin\link /SUBSYSTEM:WINDOWS /LIBPATH:"%masm64_path%Lib" ^ /entry:WinMain %filename%.obj >> errors.txt del %filename%.obj pause Ошибки при компиляции: Код (DOS): Assembling: timer02.asm timer02.asm(22) : error A2008:syntax error : pushaddr timer02.asm(45) : error A2006:undefined symbol : SYSTEMTIME timer02.asm(45) : error A2195:parameter or local cannot have void type timer02.asm(10) : error A2006:undefined symbol : IMAGE_BASE timer02.asm(61) : error A2006:undefined symbol : NtdllDefWindowProc_ timer02.asm(67) : error A2006:undefined symbol : DeleteObject invoke(56): Macro Called From timer02.asm(67): Main Line Code timer02.asm(68) : error A2006:undefined symbol : RtlExitUserProcess invoke(30): Macro Called From timer02.asm(68): Main Line Code timer02.asm(70) : error A2006:undefined symbol : IMAGE_BASE movReg64Arg(11): Macro Called From invoke(14): Macro Called From timer02.asm(70): Main Line Code timer02.asm(74) : error A2006:undefined symbol : wSecond timer02.asm(76) : error A2006:undefined symbol : wMinute timer02.asm(77) : error A2006:undefined symbol : wHour timer02.asm(86) : error A2006:undefined symbol : CreateCompatibleDC invoke(30): Macro Called From timer02.asm(86): Main Line Code timer02.asm(89) : error A2006:undefined symbol : SelectObject invoke(30): Macro Called From timer02.asm(89): Main Line Code timer02.asm(103) : error A2006:undefined symbol : BitBlt invoke(59): Macro Called From timer02.asm(103): Main Line Code timer02.asm(108) : error A2006:undefined symbol : DeleteDC invoke(30): Macro Called From timer02.asm(108): Main Line Code Также подозреваю, что есть проблема с ресурсами. Точнее не умею с ними работать. Уровень владения MASM64 - дошел тогда давно только до третьего шага второй главы Сказок Дядюшки Римуса.
MK-61? Разбор кода ИК1302 от МК-61 (МК-52) Программу эмулирования уже по разобранной схеме его работы написали на С#, но полагаю такя задачка для решения впору применения ассемблера (ранее эмулирование железа МК-61 делали по схеме микросхемы с микрокодом программы на разных контроллерах, но это не так быстро при том, что оригинальная тактовая частота где то 160КГц) P.S. Сам имел некоторый опыт эмулирования в рамках связки Форт/ассемблер x86 системы комманд процессора PDP-11.
DOSAsm386, для начала замените содержимое \masm64\bin, masm64\include и masm64\lib и попробуйте собрать снова bat-файл Код (Text): cls set masm64_path=\masm64\ set filename=%~n1 if exist errors.txt del errors.txt call :read_settings %filename% @echo %kind_of_file% goto %kind_of_file% :CONSOLE if exist %filename%.exe del %filename%.exe if exist %filename%.obj del %filename%.obj if exist errors.txt del errors.txt %masm64_path%bin\ml64 /Cp /c /I"%masm64_path%Include" %filename%.asm >> errors.txt if errorlevel 1 exit if exist %1.rc ( %masm64_path%bin\RC /r /i"%masm64_path%Include" %filename%.rc >> errors.txt %masm64_path%bin\link /LIBPATH:"%masm64_path%Lib" ^ /LARGEADDRESSAWARE:NO /BASE:0x400000 /STUB:%masm64_path%bin\stubby.exe ^ /SECTION:.text,W /ALIGN:16 /entry:WinMain /MERGE:.rdata=.text ^ /fixed /nocoffgrpinfo %filename%.obj %filename%.res >> errors.txt if exist %1.res del %1.res ) else ( %masm64_path%bin\link /SUBSYSTEM:CONSOLE /LIBPATH:"%masm64_path%Lib" ^ /entry:WinMain %filename%.obj /LARGEADDRESSAWARE:NO ^ /ALIGN:16 /SECTION:.text,W /BASE:0x400000 /STUB:%masm64_path%\bin\stubby.exe >> errors.txt ) if errorlevel 1 exit del %filename%.obj goto exit1 :GUI if exist %filename%.exe del %filename%.exe if exist %filename%.obj del %filename%.obj if exist errors.txt del errors.txt %masm64_path%bin\ml64 /Cp /c /I"%masm64_path%Include" %filename%.asm > errors.txt if errorlevel 1 exit if exist %1.rc ( %masm64_path%bin\RC /r /i"%masm64_path%\Include" %filename%.rc > errors.txt %masm64_path%bin\link /LIBPATH:"%masm64_path%Lib" ^ /LARGEADDRESSAWARE:NO /BASE:0x400000 /STUB:%masm64_path%bin\stubby.exe ^ /SECTION:.text,W /ALIGN:16 /entry:WinMain ^ /fixed /nocoffgrpinfo %filename%.obj %filename%.res >> errors.txt if exist %1.res del %1.res ) else ( %masm64_path%bin\link /SUBSYSTEM:WINDOWS /LIBPATH:"%masm64_path%Lib" ^ /LARGEADDRESSAWARE:NO /BASE:0x400000 /STUB:%masm64_path%bin\stubby.exe ^ /ALIGN:16 /entry:WinMain ^ /fixed /nocoffgrpinfo %filename%.obj >> errors.txt ) if errorlevel 1 exit goto exit1 :DLL if exist %filename%.dll del %filename%.dll %masm64_path%bin\ml64 /c /Cp /I %masm64_path%include %filename%.asm >> errors.txt if errorlevel 1 exit if exist %1.rc ( %masm64_path%bin\RC /r %filename%.rc >> errors.txt if errorlevel 1 exit %masm64_path%bin\link /SUBSYSTEM:WINDOWS /LIBPATH:%masm64_path%lib ^ /ENTRY:DllMain /DLL /DLL /section:.bss,S /stub:%masm64_path%bin\stubby.exe ^ %filename%.obj %filename%.res /DEF:%filename%.def >> errors.txt if exist %1.res del %1.res ) else ( %masm64_path%bin\link /SUBSYSTEM:WINDOWS /LIBPATH:%masm64_path%lib ^ /ENTRY:DllMain /DLL /DLL /section:.bss,S /stub:%masm64_path%bin\stubby.exe ^ %filename%.obj /DEF:%filename%.def >> errors.txt ) if errorlevel 1 exit del %filename%.exp :exit1 del %filename%.obj del errors.txt :: %filename%.exe exit :read_settings for /f "eol=# tokens=2-3" %%A in (%filename%.asm) do ( set kind_of_file=%%A if %%B == # exit /b ) exit /b
Mikl___, короче добился успешной компиляции. В качестве BAT файла взял asm2.bat из папки bin. Там тоже самое содержимое, что и в посте, только поменял set masm64_path=\masm41\ на set masm64_path=\masm64\ Немножко подредактировал BAT файл, т.к. после компиляции удалялся файл error.txt Результат все равно такой же - нет цифр. Ресурсный файл компилируется. В файле timer02.rc пробовал также прописать полный путь к файлу, результат тот же. Прикрепляю откомпилированный мной файл. Mikl___, попробуй запустить его на своей операционке, может дело в отличиях наших операционок. --- Сообщение объединено, 19 фев 2022 --- timer01.exe откомпилировался и работает нормально. Но там работы с ресурсами нет. --- Сообщение объединено, 19 фев 2022 --- timer02.exe под Win10 2004 не компилировал, но откомпилированный файл под нее запускается без цифр.
DOSAsm386, в аттаче asm-/rc-/exe-файлы timer02a.exe, timer02b.exe, timer03c.exe Экзешники собирались с ресурсами и индикаторы нормально отображаются под Windows 7 и 10. Чтобы ехе работали и под "семеркой", и под "десяткой" пришлось убрать из bat-файла разрешение на запись в секцию .code (.text,W) и выравнивание /ALIGN:16 Разница между timer02a.exe, timer02b.exe, timer03c.exe при создании ресурса в timer02a.rc ресурс типа BITMAP имеет имя "MYBP1" Код (C++): MYBP1 BITMAP "03.bmp" в timer02a.asm Код (ASM): .data aMYBP1 db "MYBP1",0 .code mov edx,offset aMYBP1 invoke LoadBitmap,IMAGE_BASE mov hBitmap,eax при создании ресурса в timer02b.rc ресурс типа BITMAP идентифицируется по номеру (100) Код (C++): #define MYBP1 100 MYBP1 BITMAP "03.bmp" в timer02b.asm Код (ASM): MYBP1 equ 100 .code invoke LoadBitmap,IMAGE_BASE,MYBP1 mov hBitmap,eax при создании ресурса в timer02c.rc ресурс типа BITMAP ассоциируется с числом 100, но которое описано как строка Код (C++): 100 BITMAP "03.bmp" в timer02c.asm Код (ASM): .data aMYBP1 db "#100",0 .code mov edx,offset aMYBP1 invoke LoadBitmap,IMAGE_BASE mov hBitmap,eax
Mikl___, ура! Все три откомпилированные тобой экзешники отображают цифры! Проверил пока на Семерке. Теперь, будет время, попробую откомпилировать экзешники самостоятельно и проверю их работоспособность! Когда скачивал аттач с исходниками и откомпилированными экзешниками, то Firefox ругался на вирус, пришлось принудительно ему сказать, чтобы скачал архив. Kaspersky Security Cloud Free вирусов не нашел.
Воспользовался советом Intro и нашел шрифт для семисегментного индикатора, теперь никаких картинок Код (ASM): ; GUI # include win64a.inc TIMER_ID = 10 W = 225 H = 95 .code WinMain proc <20> local msg:MSG xor ebx,ebx mov esi,IMAGE_BASE mov edi,offset AppName mov ecx,offset FileName invoke LoadCursorFromFileA push rax ;hIconSm push rdi ;lpszClassName push rbx push COLOR_WINDOW push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX mov eax,esi ;rsi = 400000h shl esi,9 ;rsi = 400000h << 9 = CW_USEDEFAULT invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPED or WS_VISIBLE \ or WS_CAPTION or WS_SYSMENU,rsi,rsi,W,H,rbx,rbx,rax,rbx lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc <5> hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM local ps:PAINTSTRUCT local hdc:HDC local Time:SYSTEMTIME mov hWnd,rcx cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_TIMER je wmTIMER leave jmp NtdllDefWindowProc_ wmDESTROY:;уничтожаем таймер #10 invoke KillTimer,,TIMER_ID invoke RtlExitUserProcess,NULL wmCREATE:invoke SetTimer,,TIMER_ID,1000,NULL jmp wmBYE wmTIMER:lea ecx,Time invoke GetLocalTime movzx eax,Time.wSecond movzx r9d,Time.wMinute movzx r8d,Time.wHour mov ecx,offset buffer lea edx,fmtstr invoke wsprintfA,,,,,rax invoke InvalidateRect,hWnd,NULL,TRUE jmp wmBYE wmPAINT:lea edx,ps invoke BeginPaint;,hWnd mov hdc,rax invoke SetBkMode,eax,TRANSPARENT mov ecx,offset lf invoke CreateFontIndirect mov hNewFont,rax invoke SelectObject,hdc,eax mov hOldFont,rax mov r9d,offset buffer ;line address invoke TextOut,hdc,0,5,,8 invoke DeleteObject,hNewFont invoke SelectObject,hdc,hOldFont lea edx,ps invoke EndPaint,hWnd wmBYE: leave retn WndProc endp .data AppName db 'Часы #7d',0 FileName db "br_Rabbit3.cur",0 fmtstr db "%02d:%02d:%02d",0 buffer db 50 dup(?) hOldFont dq ? hNewFont dq ? lf LOGFONT <-64,0,0,0, FW_NORMAL, 0,0,0,0, OUT_STROKE_PRECIS, \ CLIP_STROKE_PRECIS,DRAFT_QUALITY,VARIABLE_PITCH,"Fake Hope"> end в аттаче asm-/exe-файлы, курсор и ttf-файл "Fake Hope", который придется установить в систему
Немного старания и часы становятся полупрозрачными У окна расширенный стиль WS_EX_LAYERED, при инициализации окна вызывается функция SetLayeredWindowAttributes. Значение коэффициента прозрачности подбирается от 0 (полная прозрачность) до 255 (полная непрозрачность). Идея подсмотрена у Manhanter'a. Код (ASM): ; GUI # include win64a.inc WS_EX_LAYERED equ 80000h TIMER_ID = 10 W = 225 H = 95 .code WinMain proc <20> local msg:MSG xor ebx,ebx mov esi,IMAGE_BASE mov edi,offset AppName mov ecx,offset FileName invoke LoadCursorFromFileA push rax ;hIconSm push rdi ;lpszClassName push rbx push COLOR_WINDOW push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX mov eax,esi ;rsi=400000h shl esi,9 ;rsi=400000h << 9=CW_USEDEFAULT invoke CreateWindowExA,WS_EX_LAYERED,edi,edi,WS_OVERLAPPED or WS_VISIBLE \ or WS_CAPTION or WS_SYSMENU,rsi,rsi,W,H,rbx,rbx,rax,rbx lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc <5> hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM local ps:PAINTSTRUCT local hdc:HDC local Time:SYSTEMTIME mov hWnd,rcx cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_TIMER je wmTIMER leave jmp NtdllDefWindowProc_ wmDESTROY:;уничтожаем таймер #10 invoke KillTimer,,TIMER_ID invoke RtlExitUserProcess,NULL wmCREATE:invoke SetTimer,,TIMER_ID,1000,NULL ; Установка атрибута прозрачности invoke SetLayeredWindowAttributes,hWnd,0,180, LWA_ALPHA wmTIMER:lea ecx,Time invoke GetLocalTime movzx eax,Time.wSecond movzx r9d,Time.wMinute movzx r8d,Time.wHour mov ecx,offset buffer lea edx,fmtstr invoke wsprintfA,,,,,rax invoke InvalidateRect,hWnd,NULL,TRUE jmp wmBYE wmPAINT:lea edx,ps invoke BeginPaint;,hWnd mov hdc,rax invoke SetBkMode,eax,TRANSPARENT mov ecx,offset lf invoke CreateFontIndirect mov hNewFont,rax invoke SelectObject,hdc,eax mov hOldFont,rax mov r9d,offset buffer ;line address invoke TextOut,hdc,0,5,,8 invoke DeleteObject,hNewFont invoke SelectObject,hdc,hOldFont lea edx,ps invoke EndPaint,hWnd wmBYE: leave retn WndProc endp .data AppName db 'Часы #7f',0 FileName db "br_Rabbit3.cur",0 fmtstr db "%02d:%02d:%02d",0 buffer db 50 dup(?) hOldFont dq ? hNewFont dq ? lf LOGFONT <-64,0,0,0,FW_NORMAL,0,0,0,0,OUT_STROKE_PRECIS,CLIP_STROKE_PRECIS,\ DRAFT_QUALITY,VARIABLE_PITCH,"Fake Hope"> end В аттаче asm-/exe-файлы, курсор и ttf-файл "Fake Hope", который придется установить в систему
Шрифты можно в ресурсах держать : https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-addfontmemresourceex
Да семисигментный цифровой код вообще можно так нарисовать, 2 типа полигонов через FillPolygon заливать.
Спасибо, интересная идея единственное пожелание - глаз замечает легкое подрагивание перерисовки раз в секунду Есть ли метод убрать? и еще - зачем в коде на строке 3 дефиниция WS_EX_LAYERED equ 80000h ведь она есть в стандартном win64.inc в поставке MASM64
alex_dz, попробуйте закомментировать ее (3-ью строку), у меня компилятор ругнулся на неизвестную ему WS_EX_LAYERED. По поводу "убрать перерисовку раз в секунду", подумаю...
Пасиб, видимо у нас разные masm64 SDK кстати, уже столько лет, а релиз Хатч так и не сделал ни разу... Очень занятной концепт, еще пару идей на подумать 1) поверх всех окон - так и проситься (ведь оно полупрозрачое и просто обязано стать королем десктопа ) 2) более фунциольно наполненное - сделать а) count down timer b) reminder + wav балаламка на событие 2а очень даже практично (использую прямо в хроме countdown timer на регулярной основе) но здесь более интересно - оффлайн и все такое
Вот моя реализация, можно перетаскивать за любое место формы, цифры реализованы битмапами которые собраны в атласе. Чисто старый WinAPI, должен работать под Win95, но надо дистрибутив от мелкософта установить, на свежей 95-й будет ругаться на отсуствия MSVCR100.dll Не уверен что всё хорошо сделано, но пока так. Наверное лучше загружать черно-белую картинку из ресурсов и раскрашивать и потом загружать в HBITMAP. Ну или сразу в 32 цвете, тогда приложение будет больше весить, а хочется чтобы несколько кб. ЗЫ А забыл сказать, UASM и там мои библиотеки нужны, я кажется в теме ассемблер выкладывал.
alex_dz, можно просто заменить в библиотеке _exit на ExitProcess, входящий параметр тот же, просто в функции _exit калбек на завершения срабатывает, но тут это не нужно. Пока не проверял на 95-й.
То есть у вас из большой дллки MSVCR100.dll зависимость всего на 1 функцию? тогда точно надо от нее избавлятся
Как часики на плюсах сделать https://habr.com/ru/post/706954/ По мне стрелочные часы, (аналоговый это не правильно, у нас всё равно эмуляция цифровых часов) лучше сделать на библиотеках, где поддерживают спрайты с прозрачностью и возможность произвольного вращения и масштабирования. OpenGL должен справиться, есть спрайт фона часов и стрелок(собственно спрайты стрелок и вращаем). Две кнопки сворачивания и закрытия, так же надо добавить свойство поверх всех окон. И можно использовать приложение по назначения, а не просто чтобы потренироваться.
Сорокалетний GDI это все поддерживает. Хотя, да, надо обязательно на qt писать (на петоне, конечно же, с биндингами к qt), а то шо это за часы. если файл весит всего 50к и памяти меньше гига жрет?..