Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.139.239.67] |
|
Сообщ.
#1
,
|
|
|
В отличие от языков высокого уровня, в программы на ассемблере включается весь код, который содержится в исходнике, в том числе процедуры и данные, которые реально не используются. В первую очередь, я имею в виду include-файлы, а не библиотеки (*.lib). Поэтому я решил сделать механизм, который будет исключать неиспользуемый код из финального релиза.
Пользуйтесь на здоровье (см. аттач)!!! ############################################ ## ## ## -= CALLX for MASM/TASM =- ## ## [ v1.01 :: 09.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 ИмяПроцедуры, Параметры В TASM параметры, содержащие пробелы, должны заключаться в <угловые скобки> (например, 'callx MyProc, <word ptr [bx]>'), иначе компилятор заменит пробелы запятыми. Также в TASM при необходимости передачи первого параметра (например, идентификатора языка) через пробел сразу после имени процедуры, имя процедуры должно быть заключено вместе с этим параметром в <угловые скобки> (например, макрос '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, см. выше). При необходимости реализации механизма исключения неиспользуемых процедур _главного_модуля_ (а не стороннего 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 могут появляться новые функции, перед включением этого файла можно определить константу с именем callx_ver_req, присвоив ей номер минимально требуемой версии callx. Если версия включаемого файла callx.inc будет ниже указанной, компилятор выдаст сообщение об ошибке. Для наглядной демонстрации использования механизма callx в папке examples созданы примеры (для DOS и Windows). Примеры использования механизма исключения для процедур главного модуля смотрите в папке examples\Windows (1,2,B,C,Y,Z). ------------------------------------------------------------------------------------------------------------------------ :: ИСТОРИЯ ВЕРСИЙ :: v1.01 (09.01.2017) [+] Добавлена проверка версии callx: для этого ПЕРЕД включением файла callx.inc в проект нужно определить константу callx_ver_req, хранящую минимально требуемую версию callx. [*] Все примеры переведены из кодировки Windows-1251 в DOS-866. v1.00 (07.01.2017) [!] Самая первая версия. Поддерживается возможность написания кода, который компилируется и работает даже при отсутствии файла callx.inc. ------------------------------------------------------------------------------------------------------------------------ :: СВЯЗЬ С АВТОРОМ :: Данный include-файл написан Евгением Красниковым в 2017 году. Замечания и предложения присылайте на e-mail: jin.x@sources.ru. Самую свежую версию можно скачать на сайте: http://xk7.ru/p/a/i. Мои проекты на ассемблере можно найти также на форумах (cyberforum.ru, forum.sources.ru, wasm.in, programmersforum.ru) по метке/ключевому слову asm7x. Прикреплённый файлcallx_1.01.zip (37,25 Кбайт, скачиваний: 135) Старые версии: Прикреплённый файлcallx_1.00.zip (36,64 Кбайт, скачиваний: 124) |
Сообщ.
#2
,
|
|
|
Версия 1.01. Добавил пару нюансов (обновлено в первом сообщении)
Цитата v1.01 (09.01.2017) [+] Добавлена проверка версии callx: для этого ПЕРЕД включением файла callx.inc в проект нужно определить константу callx_ver_req, хранящую минимально требуемую версию callx. [*] Все примеры переведены из кодировки Windows-1251 в DOS-866. |