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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 06.01.2017, 23:39   #1
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
Хорошо Механизм исключения неиспользуемых процедур из кода (MASM/TASM)

В отличие от языков высокого уровня, в программы на ассемблере включается весь код, который содержится в исходнике,
в том числе процедуры и данные, которые реально не используются. В первую очередь, я имею в виду include-файлы, а не
библиотеки (*.lib). Поэтому я решил сделать механизм, который будет исключать неиспользуемый код из финального релиза.

Пользуйтесь на здоровье (см. аттач)!!!

Код:
############################################
##                                        ##
##        -= CALLX for MASM/TASM =-       ##
##         [ v1.00 :: 07.01.2017 ]        ##
##                                        ##
##  (c) 2017 by Jin X (jin.x@sources.ru)  ##
##           http://xk7.ru/p/a/i          ##
##                                        ##
############################################

------------------------------------------------------------------------------------------------------------------------

:: ПОДРОБНОЕ ОПИСАНИЕ ::

В отличие от языков высокого уровня, в программы на ассемблере включается весь код, который содержится в исходнике,
в том числе процедуры и данные, которые реально не используются. В первую очередь, я имею в виду include-файлы, а не
библиотеки (*.lib). Поэтому я решил сделать механизм, который будет исключать неиспользуемый код из финального релиза.

Данный файл callx.inc реализует механизм, который включает в код только используемые процедуры include-файлов.
Для работы данного механизма необходимо включить в начало главного модуля следующие строки:

	include	callx.inc	; механизм исключения неиспользуемых процедур из кода
	usecallx		; запустить механизм

Можно также сделать универсальный вариант, при котором программа будет компилироваться и работать даже при отсутствии
файла callx.inc (если закомментировать первую строку, разумеется), однако в этом случае программа будет включать в себя
все процедуры всех include-файлов. Для этого используйте следующие строки вместо приведённых выше:

	include	callx.inc	; механизм исключения неиспользуемых процедур из кода (в случае отсутствия данного файла просто закомментируйте эту строку)
	ifdef	callx_ver	; проверка наличия callx.inc
	  usecallx		; запустить механизм
	else
	  callx		equ	call
	  invokex	equ	invoke
	endif

Строку 'invokex equ invoke' имеет смысл добавлять только для MASM.

В include-файлы включаются следующие строки:

	include	callx.inc	; в случае отсутствия данного файла просто закомментируйте эту строку

	ifdef	?usecallx	; проверка использования механизма исключения неиспользуемых процедур из кода
	  modulex ИмяМодуля	; имя модуля
	  prelx	ИмяМодуля, Процедура, <Используемые, Процедуры>
	  pdefx	ИмяМодуля, <Список, Всех, Процедур>
	else
	  pchkx		equ	<?dummy =>
	endif

Действительно, данный механизм построен таким образом, что даже при отсутствии файла callx.inc программа будет
компилироваться и работать, однако в этом случае она будет включать в себя все процедуры include-файла.

Итак, давайте разберёмся в этих строках...

Макрос modulex задаёт имя модуля (идентификатор include-файла ?callx_ИмяМодуля). Это нужно для проверки идентификатора
включения всех процедур модуля (?inclAll_ИмяМодуля, задаваемого макросом inclx_All, см. ниже) и проверки корректности
имени модуля в макросах prelx, pdefx и inclx_All.
В принципе, макрос modulex можно не использовать, а макросам prelx и pdefx вместо имени модуля передать пустую строку
('prelx, Процедура, <Используемые, Процедуры>' и 'pdefx, <Список, Всех, Процедур>' - обратите внимание на запятую сразу
после названия макроса), однако в этом случае использовать макрос inclx_All можно будет либо без указания имени модуля
(без параметра), либо указав знак вопроса (см. ниже).

Макрос prelx создаёт зависимость первой указанной "Процедуры" от других процедур в списке.
Таким образом, если "Процедура" будет включена в код, то вместе с ней будут включены и все остальные процедуры из списка.
Данный макрос должен быть выполнен для каждой такой зависимой процедуры (отдельной строкой), но может и отсутствовать
вовсе, если таких процедур нет.

Макрос pdefx проверяет созданные ранее идентификаторы и определяет при необходимости идентификатор исключения процедур
из кода (?exclИмяПроцедуры).

* Список процедур в макросах prelx и pdefx (а также в inclx и exclx, см. ниже) можно не заключать в <угловые скобки>,
но я рекомендую делать это для наглядности, чтобы отделить список процедур от имени модуля и зависимой процедуры.

Определение pchkx (через equ) задано здесь на случай отсутствия файла callx.inc (см. ниже).

Далее перед кодом каждой процедурой, для которой требуется использовать данный механизм, необходимо вставить строку:

	ifndef	?exclИмяПроцедуры
	pchkx	ИмяПроцедуры

После кода процедуры соответственно:

	endif ; ?exclИмяПроцедуры

Макрос pchkx в данном случае проверяет - указана ли процедура в списке макроса pdefx.
Это сделано лишь для удобства программиста, чтобы он не забыл включить процедуру в этот список, поэтому при желании
данный макрос (вместе со строками 'else' + 'pchkx equ ...' в заголовке include-файла) можно не использовать.

Такие же условные директивы ('ifndef ?exclИмяПроцедуры' + 'endif', но без макроса pchkx) можно использовать и для других
необходимых для работы процедуры конструкций (например, для данных).

!!! В основном коде такие процедуры должны вызываться не с помощью call или invoke, а через макросы callx или invokex:

	callx	ИмяПроцедуры, Параметры
	invokex	ИмяПроцедуры, Параметры

Конструкции, содержащие пробелы, должны быть заключены в <угловые скобки> (например, 'callx MyProc, <word ptr [bx]>'),
иначе компилятор заменит пробелы запятыми.

При необходимости передачи первого параметра (например, идентификатора языка) через пробел сразу после имени процедуры,
имя процедуры заключается вместе с этим параметром в <угловые скобки> (например, макрос 'callx <MyProc pascal> ax, dx'
будет преобразован в вызов 'call MyProc pascal, ax, dx') !!!

Файл callx.inc и прочие указанные выше строки рекомендуется включать в начало исходника (т.е. ДО первого использования
callx/invokex), а include-файлы, использующие данный механизм, должны включаться в конце главного модуля (т.е. ПОСЛЕ
всех вызовов callx/invokex). Если же такой include-файл необходимо включить выше того места, где вызываются описанные
в нём процедуры, то перед его включением (но после строк инициализации, указанных в начале этого текста) должен быть
выполнен макрос 'inclx Список, Включаемых, Процедур, Через, Запятую' либо комбинация макросов 'inclx_All ИмяМодуля'
и 'exclx Список, Исключаемых, Процедур, Через, Запятую'. В этих случаях вызывать процедуры можно стандартным образом
(с помощью call/invoke, а не через макросы callx/invokex).

p.s. Макрос inclx_All можно использовать без указания имени модуля (т.е. без параметра) - в этом случае в код будут
включены все процедуры всех модулей. Также можно передать макросу в качестве параметра знак вопроса ('inclx_All ?') -
в этом случае в код включатся все процедуры всех безымянных модулей (не использующих modulex, см. выше).
Вложения
Тип файла: zip callx.zip (36.6 Кб, 7 просмотров)
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru
7in вне форума Ответить с цитированием
Старый 06.01.2017, 23:39   #2
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Продолжение...
Код:
При необходимости реализации механизма исключения неиспользуемых процедур _главного_модуля_ (а не стороннего include-
файла) помимо строк 'include callx.inc' + 'usecallx' также необходимо включить следующие строки:

	modulex ИмяМодуля	; имя модуля
	prelx	ИмяМодуля, Процедура, <Используемые, Процедуры>
	pdefx	ИмяМодуля, <Список, Всех, Процедур>

При этом использовать проверку 'ifdef ?usecallx' (как в include-файлах) нет никакого смысла. Если же нужно сделать
универсальный вариант, при котором программа будет компилироваться и работать даже при отсутствии файла callx.inc,
эти строки должны быть дополнены соответствующими проверками (похожими на те, что были приведены в начале):

	ifdef	callx_ver	; проверка наличия callx.inc
	  modulex ИмяМодуля	; имя модуля
	  prelx	ИмяМодуля, Процедура, <Используемые, Процедуры>
	  pdefx	ИмяМодуля, <Список, Всех, Процедур>
	else
	  pchkx		equ	<?dummy =>
	endif

Если макрос pchkx в главном модуле не используется, строки 'else' + 'pchkx' следует исключить.

Важно также отметить, что вызов макроса modulex может располагаться как в самом начале (вместе с usecallx), так и
непосредственно перед prelx и pdefx, сами же вызовы макросов prelx и pdefx должны располагаться ПОСЛЕ всех вызовов
callx/invokex, но ДО кода процедур, в которых используется данный механизм.

Для наглядной демонстрации к файлу callx.inc прилагаются примеры в папке examples (как для DOS, так и для Windows).
Примеры использования механизма исключения для процедур главного модуля смотрите в папке examples\Windows (1,2,B,C,Y,Z).

------------------------------------------------------------------------------------------------------------------------

:: ИСТОРИЯ ВЕРСИЙ ::

v1.00 (07.01.2017)
[!] Самая первая версия.
    Поддерживается возможность написания кода, который компилируется и работает даже при отсутствии файла callx.inc.

------------------------------------------------------------------------------------------------------------------------

:: СВЯЗЬ С АВТОРОМ ::

Данный include-файл написан Евгением Красниковым в 2017 году.
Замечания и предложения присылайте на e-mail: jin.x@sources.ru.
Самую свежую версию можно скачать на сайте: http://xk7.ru/p/a/i.
p.s. На github.com пока не залил (так что, ссылка пока нерабочая), но сделаю это в ближайшее время.
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru
7in вне форума Ответить с цитированием
Старый 07.01.2017, 03:13   #3
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
В отличие от языков высокого уровня, в программы на ассемблере включается весь код, который содержится в исходнике,
в том числе процедуры и данные, которые реально не используются.
Выйти и долго биться головой об стену до просвещения... Давайте я поделюсь секретом: в масме и С++ от мелкомягких один и тот же линкер.
p51x вне форума Ответить с цитированием
Старый 07.01.2017, 12:34   #4
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

p51x, линкер-то один, а вот компиляторы, которые обрабатывают исходник и решают что брать, а что нет - разные.

Если я сделаю include-файл, в котором будет 50 математических функций, и подключу его к asm-проекту, но использую только 2 функции, то в итоге в проге будет зашито все 50 функций, что не очень-то и разумно. Разве не так? И причём тут линкер?
А если сделать то же самое на C или Pascal/Delphi, то зашиты будут именно эти 2 функции (если не говорить о виртуальных методах).
Об этом и речь...
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru

Последний раз редактировалось 7in; 07.01.2017 в 12:37.
7in вне форума Ответить с цитированием
Старый 07.01.2017, 12:54   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Компилируйте каждую функцию в отдельный сегмент, остальное сделает линкер.
waleri вне форума Ответить с цитированием
Старый 07.01.2017, 13:24   #6
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
и решают что брать, а что нет - разные.
Это делает линкер

Цитата:
Если я сделаю include-файл, в котором будет 50 математических функций, и подключу его к asm-проекту, но использую только 2 функции, то в итоге в проге будет зашито все 50 функций, что не очень-то и разумно. Разве не так?
Нет. include в масме и С++ делают одно и тоже - подставляют заданный файл на свое место. В inc-файла обычно лежат прототипы функции, они ничего не зашивают. Это так же, как в h-файле для С++ объвить функцию.

Цитата:
И причём тут линкер?
Почитайте кто чем занимается во время компиляции.

Цитата:
А если сделать то же самое на C или Pascal/Delphi, то зашиты будут именно эти 2 функции (если не говорить о виртуальных методах).
То же будет и в асме, без всяких выкрутасов. Откройте любой пример из масма32 и глазками посмотрите сколько inc, lib он импортирует и сколько реально импортирует готовый exe.

Цитата:
Об этом и речь...
p51x вне форума Ответить с цитированием
Старый 07.01.2017, 16:50   #7
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
То же будет и в асме, без всяких выкрутасов. Откройте любой пример из масма32 и глазками посмотрите сколько inc, lib он импортирует и сколько реально импортирует готовый exe.
Я же написал:
Цитата:
Сообщение от 7in Посмотреть сообщение
В первую очередь, я имею в виду include-файлы, а не библиотеки (*.lib).
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru
7in вне форума Ответить с цитированием
Старый 07.01.2017, 16:53   #8
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Inlcude-файлы с функциями (процедурами). Есть плюсы и минусы как у lib'ов, так и у inc'ов. Главный плюс inc'а - это то, что это исходник, которой можно изменить или можно в него встроить кучу всяких if/ifdef и т.п., сконфигурировав финальный код по-своему. Или просто взять какой-то кусок и вырезать для своей программы. Ну и т.д.
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru
7in вне форума Ответить с цитированием
Старый 07.01.2017, 21:05   #9
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Вы пост читайте до конца, а? inc в асме содержат прототипы функций, в них обычно кода нет (кроме макросов)
p51x вне форума Ответить с цитированием
Старый 07.01.2017, 22:48   #10
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
inc в асме содержат прототипы функций, в них обычно кода нет (кроме макросов)
Это кто так решил?
inc в асме могут содержать всё, что угодно, в т.ч. сами функции. Или Вы такого не встречали?
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru

Последний раз редактировалось 7in; 07.01.2017 в 23:03.
7in вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Эллипс в DOS (masm, tasm, fasm) Mikl___ Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 14 13.12.2014 09:06
Номер первого положительного числа / Assembler, MASM, TASM schibeki Помощь студентам 1 04.03.2014 12:13
Конвертер с языка masm на язык tasm максат Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 6 14.06.2011 14:27
Обьясните различия между - FASM, WASM, VASM, MASM, TASM Amancha Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 9 17.01.2009 15:38
Чем отличается Tasm от Masm veter_s_morya Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 17 21.07.2008 16:55