Google'ом поискал по форуму ничего не нашёл на эту тему. Пишу и компиплирую программы в TASM, сначала всё работало хорошо, всё компилировалось, но затем TASM начал выдавать ошибку "Синтаксическая ошибка в имени файла, имени папки или метке тома." При этом даже перезагрузка не помогает и программы, которые компилировались раньше, начинают выдавать ту же ошибку. Кто знает что с этим делать и от чего появляется эта ошибка?
Опс, прошу прощения, это я сам неправильно отредактировал заголовочный файл, TASM из-за этого не мог скомпилировать файл, и ошибка появлялась из-за del *.obj в bat файле. Вернул на место начальный заголовочный файл, теперь всё работает правильно. Но появился ещё один вопрос, напишу его тут же. Пишу базовое Win32 API приложение и мне компилятор выдаёт call CreateWindow, offset WindowClassName, offset WindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0, 0, wc.hInstance, 0; **Error** Assembler.asm(50) CALLPROC(2) Argument to operation or instruction has illegal size Кто знает в чём тут дело?
SerafimR Хочешь получить ответ, _полностью_ покажи минимальный код, который воспроизводит ошибку, + укажи версию tasm'а.
Эту ошибку я уже исправил, там при передаче hInstance в CreateWindow TASM почему-то не нравилась wc.hInstance, я её переписал на push ww_hInstance; Сейчас компилируется, но при запуске окно не отображается, программа проходит регистрацию класса, создание окна и отображение окна, по крайней мере test eax, eax; jz Exit; не завершает процесс и он висит в памяти, его приходится TaskMeneger'ом закрывать. Версия TASM 5.0 от tE! с его же заголовочным файлом. Может кто-нибудь может подсказать что я пишу не так? Вот код .486 .model flat, stdcall locals includelib D:\Utilities\Writing\TASM5Plus\LIB\imp32i.lib include D:\Utilities\Writing\TASM5Plus\INCLUDE\w32.inc ;===Data segment====================================================================== .DATA WindowTitle db 'Assembler', 0; WindowClassName db 'Assembler', 0; Message db 'Assembler', 0; MessageReg db 'Registered window class.', 0; MessageCreatedWindow db 'Created window.', 0; WindowMsg MSG < 0 >; wc WNDCLASS < 0 >; hWndMain dd ?; ww_hInstance dd ?; Quit dd ?; ;===Uninitialized data segment======================================================== ;.DATA? ; hWndMain dd ?; ; ww_hInstance dd ?; ; Quit dd ?; ;===Code segment====================================================================== .CODE Start : pushad call GetModuleHandle, 0; test eax, eax; jz Exit; mov ww_hInstance, eax; mov Quit, 0; ;---Registering window class-------------------------------------------------- call GetModuleHandle, 0; mov wc.w_Style, CS_HREDRAW + CS_VREDRAW + CS_OWNDC; mov wc.w_lpfnWndProc, offset WindowProc; mov wc.w_hInstance, eax; mov wc.w_lpszClassName, offset WindowClassName; call RegisterClass, offset wc; test eax, eax jz Exit call MessageBox, 0, offset MessageReg, offset WindowTitle, MB_OK; ;---CreatingWindow------------------------------------------------------------ push 0; push ww_hInstance; push 0; push 0; push 480; push 640; push CW_USEDEFAULT; push CW_USEDEFAULT; push WS_OVERLAPPEDWINDOW; push offset WindowTitle; push offset WindowClassName; push 0; call CreateWindowExA; test eax, eax jz Exit call MessageBox, 0, offset MessageCreatedWindow, offset WindowTitle, MB_OK; mov hWndMain, eax; call ShowWindow, eax, SW_SHOWNORMAL; call UpdateWindow, hWndMain; call MessageBox, 0, offset Message, offset WindowTitle, MB_OK; ;---Message loop-------------------------------------------------------------- MsgLoop : call GetMessage, offset WindowMsg, 0, 0, 0; call TranslateMessage, offset WindowMsg; call DispatchMessage, offset WindowMsg; cmp Quit, 1; je Exit; jmp MsgLoop; Exit : popad call ExitProcess, 0 RET ;===Procedures and functions========================================================== WindowProc proc _hWnd : HWND, WindowMessage : UINT, _wParam : WPARAM, _lParam:LPARAM; uses ebx, edi, esi; mov eax, WindowMessage; cmp eax, WM_CLOSE; jz close; call DefWindowProc, _hWnd, WindowMessage, _wParam, _lParam; close : mov Quit, 1; RET; WindowProc ENDP; END Start;
SerafimR > test eax, eax; > jz Exit; > не завершает процесс В твоем коде три таких куска, на какой из них ты ссылаешься? > при запуске окно не отображается, программа проходит ... и отображение окна Как тебя понимать? > приходится TaskMeneger'ом закрывать Твоя оконная процедура никуда не годится. Например, В ответ на любое сообщение она устанавливает Quit в _единицу_. ps для оформления кода в сообщениях есть специальный тег.
Код (Text): test eax, eax; jz Exit; Переводит выполнение на Код (Text): Exit : popad call ExitProcess, 0 RET , которое как раз и завершает процесс, насколько я понял, когда eax равен нолю, т.е. когда функции выполняются с ошибками, срабатывает Код (Text): test eax, eax; jz Exit; и завершает программу. Я имею ввиду все 3 этих куска кода, все их программа проходит. То, что программа проходит показ окна это значит, что она не завершается до Код (Text): mov hWndMain, eax; call ShowWindow, eax, SW_SHOWNORMAL; call UpdateWindow, hWndMain; Опеределяю я это по Код (Text): call MessageBox, 0, offset Message, offset WindowTitle, MB_OK; да и по тому что программа висит в памяти, она скорее всего доходит до цикла и в нём работает. Функцию я уже переправил на Код (Text): WindowProc proc _hWnd : HWND, WindowMessage : UINT, _wParam : WPARAM, _lParam:LPARAM; uses ebx, edi, esi; mov eax, [WindowMessage]; cmp eax, WM_CLOSE; jz close; call DefWindowProc, [_hWnd], [WindowMessage], [_wParam], [_lParam]; RET; close : mov [Quit], 1; RET; WindowProc ENDP;
В общем я взял пример отсюда http://www.wasm.ru/srclist.php?list=1, по моему этот http://www.wasm.ru/baixado.php?mode=src&id=32, взял INC файл и скрипт компиляции из этого же примера и переписал программу к виду Код (Text): .586 .model flat, stdcall locals include D:\Utilities\Writing\TASM5Plus\INCLUDE\win32.inc ;===Data segment====================================================================== .DATA WindowTitle db 'Assembler', 0; WindowClassName db 'Assembler', 0; MenuName db 0; Message db 'Assembler', 0; MessageReg db 'Registered window class.', 0; MessageCreatedWindow db 'Created window.', 0; WindowMsg MSGSTRUCT < ? >; wc WNDCLASS < ? >; ;===Uninitialized data segment======================================================== .DATA? hWndMain dd ?; ww_hInstance dd ?; Quit dd ?; ;===Code segment====================================================================== .CODE Start : ;pushad call GetModuleHandle, 0; test eax, eax; jz Exit; mov wc.clsHInstance, eax; mov Quit, 0; ;---Registering window class-------------------------------------------------- mov wc.clsStyle, CS_HREDRAW + CS_VREDRAW + CS_OWNDC; mov wc.clsLpfnWndProc, offset WindowProc; mov wc.clsCbClsExtra, 0; mov wc.clsCbWndExtra, 0; mov wc.clsHbrBackground, 0; mov dword ptr wc.clsLpszMenuName, offset MenuName; mov dword ptr wc.clsLpszClassName, offset WindowClassName; call RegisterClassA, offset wc; test eax, eax jz Exit ;---CreatingWindow------------------------------------------------------------ push 0; push wc.clsHInstance; push 0; push 0; push 480; push 640; push CW_USEDEFAULT; push CW_USEDEFAULT; push WS_OVERLAPPEDWINDOW; push offset WindowTitle; push offset WindowClassName; push 0; call CreateWindowExA; test eax, eax jz Exit mov hWndMain, eax; call ShowWindow, hWndMain, SW_SHOWNORMAL; call UpdateWindow, hWndMain; ;---Message loop-------------------------------------------------------------- MsgLoop : call GetMessageA, offset WindowMsg, 0, 0, 0; call TranslateMessage, offset WindowMsg; call DispatchMessage, offset WindowMsg; cmp Quit, 1; je Exit; jmp short MsgLoop; Exit : ;popad call ExitProcess, 0 RET ;===Procedures and functions========================================================== WindowProc proc uses ebx edi esi, _hWnd : DWORD, WindowMessage : DWORD, _wParam : DWORD, _lParam:DWORD; cmp WindowMessage, WM_CLOSE; je close; call DefWindowProc, _hWnd, WindowMessage, _wParam, _lParam; RET; close : mov Quit, 1; RET; WindowProc ENDP; END Start; И всё заработало! Но сейчас есть ещё один вопрос. В nasm можно объявлять внешние процедуры и функции так Код (Text): extern MessageBoxA; extern GetStockObject; и потом при линковке программы подключать библиотеку, а можно Код (Text): extern MessageBoxA; import MessageBoxA user32.dll; extern GetStockObject; import GetStockObject gdi32.dll; тогда при линковке можно не подключать библиотеку и размер программы существенно уменьшается. Как сделать это же самое в TASM?
SerafimR Что то вы путаете в NASM Код (Text): %define ONLY_NASM %include "nagoa+.inc" %include "defines.inc" section .text start: invoke MessageBox,0,Message,wTitle,MB_OK+MB_SYSTEMMODAL retn wTitle db 'Iczelion Tutorial #2:MessageBox',0 Message db 'Win32 Assembly with NASM is Great!',0 LAST_BEGIN __LIBS_ user32, 'user32.DLL' __IMPORT_ user32,\ MessageBox,'MessageBoxA',0 LAST_END в TASM Код (Text): .386 .model flat includelib import32.lib include windows32.inc extern MessageBoxA:PROC .code start: push MB_OK + MB_SYSTEMMODAL push offset wTitle push offset Message push eax call MessageBoxA ret ;выход из программы wTitle db 'Iczelion Tutorial #2:MessageBox',0 Message db 'Win32 Assembly with tasm is Great!',0 ends end start
Да нет в nasm я не путаю, мне нужно как раз импортирование функций из динамических библиотек во время работы программы, чтобы не использовать lib'ы. Как это в TASM написать? Я не специалист, но вроде бы у вас код Код (Text): LAST_BEGIN __LIBS_ user32, 'user32.DLL' __IMPORT_ user32,\ MessageBox,'MessageBoxA',0 LAST_END как раз и отвечает за импортирование, насколько я понял, функции можно или описывать в INC и LIB файлах, а можно просто импортировать их из dll. Я на nasm'е небольшую програмку написал без %include "nagoa+.inc", если функции описывать с помощью INC и LIB файлов, то размер программы 4 Кбайта, если загружать их из DLL, то 3 Кбайта, вот мне как раз и интересно как это сделать в TASM? Насколько я понял в верхней программе, что я привёл TASM берёт описание функций из LIB файла, по тому что она линкуется строкой Код (Text): D:\Utilities\Writing\TASM5Plus\BIN\tlink32 /Tpe /aa /c /o D:\Utilities\Writing\TASM5Plus\LIB\import32.lib Assembler,Assembler.exe, , , , Resources\Assembler.res
SerafimR В аттаче исходные файлы и exe для tasm и nasm -- сравните (nasm в двух вариантах -- стандартный и модифицированный) И API-функции не импортируются из dll -- они просто ссылаются на соответствующие системные dll (kernel32, gdi32 и т.д.) размер от этого не зависит
Аналогично код Код (Text): %INCLUDE "WIN32N.INC" EXTERN MessageBoxA EXTERN ExitProcess SECTION CODE USE32 CLASS=CODE ..start: PUSH UINT MB_OK PUSH LPCTSTR title1 PUSH LPCTSTR string1 PUSH HWND NULL CALL MessageBoxA PUSH UINT NULL CALL ExitProcess SECTION DATA USE32 CLASS=DATA string1: db 'Hello world!',13,10,0 title1: db 'Hello',0 и Код (Text): %INCLUDE "..\..\inc\win32n.inc" EXTERN MessageBoxA IMPORT MessageBoxA user32.dll EXTERN ExitProcess IMPORT ExitProcess kernel32.dll SECTION CODE USE32 CLASS=CODE ..start: PUSH UINT MB_OK PUSH LPCTSTR title1 PUSH LPCTSTR string1 PUSH HWND NULL CALL [MessageBoxA] PUSH UINT NULL CALL [ExitProcess] SECTION DATA USE32 CLASS=DATA string1: db 'Hello world!',13,10,0 title1: db 'Hello',0 Правда написано не мной, но всё-таки - первый вариант занимает на диске 3,02 Кбайта, второй - 2,51 Кбайта. Первый компилируется и линкуется строками Код (Text): D:\Utilities\Writing\nasm-2.06rc1\nasm.exe -s -Ox -f obj -iD:\Utilities\Writing\nasm-2.06rc1\INC\ -iD:\Work\Programming\Programs\Febrary\Assembler\ D:\Utilities\Writing\nasm-2.06rc1\SAMPLES\MSGBOX\MSGBOX1.ASM D:\Utilities\Writing\nasm-2.06rc1\alink\alink.exe -L D:\Utilities\Writing\nasm-2.06rc1\lib -oPE D:\Utilities\Writing\nasm-2.06rc1\SAMPLES\MSGBOX\MSGBOX1.obj win32.lib Второй - Код (Text): D:\Utilities\Writing\nasm-2.06rc1\nasm.exe -s -Ox -f obj -iD:\Utilities\Writing\nasm-2.06rc1\INC\ -iD:\Work\Programming\Programs\Febrary\Assembler\ D:\Utilities\Writing\nasm-2.06rc1\SAMPLES\MSGBOX\MSGBOX2.ASM D:\Utilities\Writing\nasm-2.06rc1\alink\alink.exe -L D:\Utilities\Writing\nasm-2.06rc1\lib -oPE D:\Utilities\Writing\nasm-2.06rc1\SAMPLES\MSGBOX\MSGBOX2.obj Сейчас попробую прикрепить их к сообщению. Загрузил.
SerafimR И что? В обоих случаях используется не самый лучший линкер alink, хотя nasm позволяет создавать com, exe, dll, sys не используя линкера. Почему-то размер exe в 3,02 Кбайта и 2,51 Кбайта тебя впечатлил, а мои экзешники в 1024 и 335 байт нет -- оба созданы "nasmw -f bin %filename%.asm -o %filename%.exe -I%nasm_path%\include\" В случае с 3,02 Kb EXE состоит из 5 секций (CODE - размер 600h, DATA - размер 800h, Imports - размер A00h, imports - размер C00h, relocs - размер 18h). В случае с 2,51 Kb EXE состоит из 4 секций (CODE - размер 600h, DATA - размер 800h, imports - размер A00h, relocs - размер 10h) содержимое секций, как и самого файла, на 90% состоит из нулей. В моих случаях только одна секция - .text. Если воспользуешься поиском, то сможешь найти рабочий PE-файл, выводящий MessageBox и в 97 байт!
Что-то у меня твой архив не закачивается, скачивается только 591 Кбайт и дальше загрузка не идёт, качаю через Opera 9.61. Мой файл закачивается нормально. Насчёт секций я не знал - я ещё только учусь программировать на ассемблере. А какой линкер генерирует самый оптимальный код по быстродействию и по размеру?
Ничего не путаешь IE нормально выкачивает -- хочешь в почту сброшу -- адрес в личку отправь при программировании на ассемблере оптимальность кода по быстродействию и размеру (это вообщето разные вещи) зависит от квалификации программиста, а не от линкера
Ты ж сам говоришь, что alink не самый лучший линкер, вот я и спрашиваю какой лучше? И как эти самые 90% нолей убрать? Да с Кбайтами я напутал конечно же - 591 байт. Послал свой E-mail в личном сообщении.
SerafimR переходи на masm Начни с Уроков Iczelion'а Разберись с Сам себе Iczelion И будет тебе счастье
Спасибо за ссылки и за исходный код. Я всё-таки использую TASM и TLINK, но у меня почему-то когда компоную с помощью Код (Text): D:\Utilities\Writing\TASM5Plus\BIN\tlink32 /Tpe /aa /c /o /V4.0 /Af:16 Assembler,Assembler.exe, , , , Resources\Assembler.res Windows говорит, что программа не является приложением Win32. Когда пишу /Af:512 всё работает хорошо.