<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=410162&amp;view=findpost&amp;p=3701204</guid>
        <pubDate>Mon, 09 Jan 2017 19:55:39 +0000</pubDate>
        <title>Механизм исключения неиспользуемых процедур из кода</title>
        <link>https://forum.sources.ru/index.php?showtopic=410162&amp;view=findpost&amp;p=3701204</link>
        <description><![CDATA[Jin X: <strong class='tag-b'>Версия 1.01</strong>. Добавил пару нюансов (обновлено в первом сообщении) ;)<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>v1.01 (09.01.2017)<br>
[+] Добавлена проверка версии callx: для этого ПЕРЕД включением файла callx.inc в проект нужно определить константу callx_ver_req, хранящую минимально требуемую версию callx.<br>
[*] Все примеры переведены из кодировки Windows-1251 в DOS-866.</div></div>]]></description>
        <author>Jin X</author>
        <category>Assembler</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=410162&amp;view=findpost&amp;p=3700993</guid>
        <pubDate>Fri, 06 Jan 2017 20:33:46 +0000</pubDate>
        <title>Механизм исключения неиспользуемых процедур из кода</title>
        <link>https://forum.sources.ru/index.php?showtopic=410162&amp;view=findpost&amp;p=3700993</link>
        <description><![CDATA[Jin X: В отличие от языков высокого уровня, в программы на ассемблере включается весь код, который содержится в исходнике, в том числе процедуры и данные, которые реально не используются. <strong class='tag-b'>В первую очередь, я имею в виду include-файлы, а не библиотеки (*.lib).</strong> Поэтому я решил сделать механизм, который будет исключать неиспользуемый код из финального релиза.<br>
<br>
Пользуйтесь на здоровье (см. аттач)&#33;&#33;&#33; ;)<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">############################################</div><div class="code_line">## &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;##</div><div class="code_line">## &nbsp; &nbsp; &nbsp; &nbsp;-= CALLX for MASM/TASM =- &nbsp; &nbsp; &nbsp; ##</div><div class="code_line">## &nbsp; &nbsp; &nbsp; &nbsp; [ v1.01 :: 09.01.2017 ] &nbsp; &nbsp; &nbsp; &nbsp;##</div><div class="code_line">## &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;##</div><div class="code_line">## &nbsp;(c) 2017 by Jin X (jin.x@sources.ru) &nbsp;##</div><div class="code_line">## &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; http://xk7.ru/p/a/i &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;##</div><div class="code_line">## &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;##</div><div class="code_line">############################################</div><div class="code_line">&nbsp;</div><div class="code_line">------------------------------------------------------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">:: ПОДРОБНОЕ ОПИСАНИЕ ::</div><div class="code_line">&nbsp;</div><div class="code_line">В отличие от языков высокого уровня, в программы на ассемблере включается весь код, который содержится в исходнике,</div><div class="code_line">в том числе процедуры и данные, которые реально не используются. В первую очередь, я имею в виду include-файлы, а не</div><div class="code_line">библиотеки (*.lib). Поэтому я решил сделать механизм, который будет исключать неиспользуемый код из финального релиза.</div><div class="code_line">&nbsp;</div><div class="code_line">Данный файл callx.inc реализует механизм, который включает в код только используемые процедуры include-файлов.</div><div class="code_line">Для использования данного механизма необходимо включить в начало главного модуля следующие строки:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;include callx.inc &nbsp; ; механизм исключения неиспользуемых процедур из кода</div><div class="code_line">&nbsp;&nbsp; &nbsp;usecallx &nbsp; &nbsp; &nbsp; &nbsp;; запустить механизм</div><div class="code_line">&nbsp;</div><div class="code_line">Можно также сделать универсальный вариант, при котором программа будет компилироваться и работать даже при отсутствии</div><div class="code_line">файла callx.inc (если закомментировать первую строку, разумеется), однако в этом случае программа будет включать в себя</div><div class="code_line">все процедуры всех include-файлов. Для этого используйте следующие строки вместо приведённых выше:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;include callx.inc &nbsp; ; механизм исключения неиспользуемых процедур из кода (в случае отсутствия данного файла просто закомментируйте эту строку)</div><div class="code_line">&nbsp;&nbsp; &nbsp;ifdef &nbsp; callx_ver &nbsp; ; проверка наличия callx.inc</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;usecallx &nbsp; &nbsp; &nbsp;; запустить механизм</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;callx &nbsp; &nbsp; equ call</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;invokex &nbsp; equ invoke</div><div class="code_line">&nbsp;&nbsp; &nbsp;endif</div><div class="code_line">&nbsp;</div><div class="code_line">Строку &#39;invokex equ invoke&#39; имеет смысл добавлять только для MASM.</div><div class="code_line">&nbsp;</div><div class="code_line">В include-файлы включаются следующие строки:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;include callx.inc &nbsp; ; в случае отсутствия данного файла просто закомментируйте эту строку</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ifdef &nbsp; ?usecallx &nbsp; ; проверка использования механизма исключения неиспользуемых процедур из кода</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;modulex ИмяМодуля; имя модуля</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;prelx ИмяМодуля, Процедура, &#60;Используемые, Процедуры&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pdefx ИмяМодуля, &#60;Список, Всех, Процедур&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pchkx &nbsp; &nbsp; equ &#60;?dummy =&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;endif</div><div class="code_line">&nbsp;</div><div class="code_line">Действительно, данный механизм построен таким образом, что даже при отсутствии файла callx.inc программа будет</div><div class="code_line">компилироваться и работать, однако в этом случае она будет включать в себя все процедуры include-файла.</div><div class="code_line">&nbsp;</div><div class="code_line">Итак, давайте разберёмся в этих строках...</div><div class="code_line">&nbsp;</div><div class="code_line">Макрос modulex задаёт имя модуля (идентификатор include-файла ?callx_ИмяМодуля). Это нужно для проверки идентификатора</div><div class="code_line">включения всех процедур модуля (?inclAll_ИмяМодуля, задаваемого макросом inclx_All, см. ниже) и проверки корректности</div><div class="code_line">имени модуля в макросах prelx, pdefx и inclx_All.</div><div class="code_line">В принципе, макрос modulex можно не использовать, а макросам prelx и pdefx вместо имени модуля передать пустую строку</div><div class="code_line">(&#39;prelx, Процедура, &#60;Используемые, Процедуры&#62;&#39; и &#39;pdefx, &#60;Список, Всех, Процедур&#62;&#39; - обратите внимание на запятую сразу</div><div class="code_line">после названия макроса), однако в этом случае использовать макрос inclx_All можно будет либо без указания имени модуля</div><div class="code_line">(без параметра), либо указав знак вопроса (см. ниже).</div><div class="code_line">&nbsp;</div><div class="code_line">Макрос prelx создаёт зависимость первой указанной &quot;Процедуры&quot; от других процедур в списке.</div><div class="code_line">Таким образом, если &quot;Процедура&quot; будет включена в код, то вместе с ней будут включены и все остальные процедуры из списка.</div><div class="code_line">Данный макрос должен быть выполнен для каждой такой зависимой процедуры (отдельной строкой), но может и отсутствовать</div><div class="code_line">вовсе, если таких процедур нет.</div><div class="code_line">&nbsp;</div><div class="code_line">Макрос pdefx проверяет созданные ранее идентификаторы и определяет при необходимости идентификатор исключения процедур</div><div class="code_line">из кода (?exclИмяПроцедуры).</div><div class="code_line">&nbsp;</div><div class="code_line">* Список процедур в макросах prelx и pdefx (а также в inclx и exclx, см. ниже) можно не заключать в &#60;угловые скобки&#62;,</div><div class="code_line">но я рекомендую делать это для наглядности, чтобы отделить список процедур от имени модуля и зависимой процедуры.</div><div class="code_line">&nbsp;</div><div class="code_line">Определение pchkx (через equ) задано здесь на случай отсутствия файла callx.inc (см. ниже).</div><div class="code_line">&nbsp;</div><div class="code_line">Далее перед кодом каждой процедурой, для которой требуется использовать данный механизм, необходимо вставить строку:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ifndef &nbsp;?exclИмяПроцедуры</div><div class="code_line">&nbsp;&nbsp; &nbsp;pchkx &nbsp; ИмяПроцедуры</div><div class="code_line">&nbsp;</div><div class="code_line">После кода процедуры соответственно:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;endif ; ?exclИмяПроцедуры</div><div class="code_line">&nbsp;</div><div class="code_line">Макрос pchkx в данном случае проверяет - указана ли процедура в списке макроса pdefx.</div><div class="code_line">Это сделано лишь для удобства программиста, чтобы он не забыл включить процедуру в этот список, поэтому при желании</div><div class="code_line">данный макрос (вместе со строками &#39;else&#39; + &#39;pchkx equ ...&#39; в заголовке include-файла) можно не использовать.</div><div class="code_line">&nbsp;</div><div class="code_line">Такие же условные директивы (&#39;ifndef ?exclИмяПроцедуры&#39; + &#39;endif&#39;, но без макроса pchkx) можно использовать и для других</div><div class="code_line">необходимых для работы процедуры конструкций (например, для данных).</div><div class="code_line">&nbsp;</div><div class="code_line">!!! В основном коде такие процедуры должны вызываться не с помощью call или invoke, а через макросы callx или invokex:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;callx &nbsp; ИмяПроцедуры, Параметры</div><div class="code_line">&nbsp;&nbsp; &nbsp;invokex ИмяПроцедуры, Параметры</div><div class="code_line">&nbsp;</div><div class="code_line">В TASM параметры, содержащие пробелы, должны заключаться в &#60;угловые скобки&#62; (например, &#39;callx MyProc, &#60;word ptr [bx]&#62;&#39;),</div><div class="code_line">иначе компилятор заменит пробелы запятыми.</div><div class="code_line">&nbsp;</div><div class="code_line">Также в TASM при необходимости передачи первого параметра (например, идентификатора языка) через пробел сразу после</div><div class="code_line">имени процедуры, имя процедуры должно быть заключено вместе с этим параметром в &#60;угловые скобки&#62; (например, макрос</div><div class="code_line">&#39;callx &#60;MyProc pascal&#62; ax, dx&#39; будет преобразован в вызов &#39;call MyProc pascal, ax, dx&#39;) !!!</div><div class="code_line">&nbsp;</div><div class="code_line">Файл callx.inc и прочие указанные выше строки рекомендуется включать в начало исходника (т.е. ДО первого использования</div><div class="code_line">callx/invokex), а include-файлы, использующие данный механизм, должны включаться в конце главного модуля (т.е. ПОСЛЕ</div><div class="code_line">всех вызовов callx/invokex). Если же такой include-файл необходимо включить выше того места, где вызываются описанные</div><div class="code_line">в нём процедуры, то перед его включением (но после строк инициализации, указанных в начале этого текста) должен быть</div><div class="code_line">выполнен макрос &#39;inclx Список, Включаемых, Процедур, Через, Запятую&#39; либо комбинация макросов &#39;inclx_All ИмяМодуля&#39;</div><div class="code_line">и &#39;exclx Список, Исключаемых, Процедур, Через, Запятую&#39;. В этих случаях вызывать процедуры можно стандартным образом</div><div class="code_line">(с помощью call/invoke, а не через макросы callx/invokex).</div><div class="code_line">&nbsp;</div><div class="code_line">p.s. Макрос inclx_All можно использовать без указания имени модуля (т.е. без параметра) - в этом случае в код будут</div><div class="code_line">включены все процедуры всех модулей. Также можно передать макросу в качестве параметра знак вопроса (&#39;inclx_All ?&#39;) -</div><div class="code_line">в этом случае в код включатся все процедуры всех безымянных модулей (не использующих modulex, см. выше).</div><div class="code_line">&nbsp;</div><div class="code_line">При необходимости реализации механизма исключения неиспользуемых процедур _главного_модуля_ (а не стороннего include-</div><div class="code_line">файла) помимо строк &#39;include callx.inc&#39; + &#39;usecallx&#39; также необходимо включить следующие строки:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;modulex ИмяМодуля; имя модуля</div><div class="code_line">&nbsp;&nbsp; &nbsp;prelx &nbsp; ИмяМодуля, Процедура, &#60;Используемые, Процедуры&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;pdefx &nbsp; ИмяМодуля, &#60;Список, Всех, Процедур&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">При этом использовать проверку &#39;ifdef ?usecallx&#39; (как в include-файлах) нет никакого смысла. Если же нужно сделать</div><div class="code_line">универсальный вариант, при котором программа будет компилироваться и работать даже при отсутствии файла callx.inc,</div><div class="code_line">эти строки должны быть дополнены соответствующими проверками (похожими на те, что были приведены в начале):</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ifdef &nbsp; callx_ver &nbsp; ; проверка наличия callx.inc</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;modulex ИмяМодуля; имя модуля</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;prelx ИмяМодуля, Процедура, &#60;Используемые, Процедуры&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pdefx ИмяМодуля, &#60;Список, Всех, Процедур&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pchkx &nbsp; &nbsp; equ &#60;?dummy =&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;endif</div><div class="code_line">&nbsp;</div><div class="code_line">Если макрос pchkx в главном модуле не используется, строки &#39;else&#39; + &#39;pchkx&#39; следует исключить.</div><div class="code_line">&nbsp;</div><div class="code_line">Важно также отметить, что вызов макроса modulex может располагаться как в самом начале (вместе с usecallx), так и</div><div class="code_line">непосредственно перед prelx и pdefx, сами же вызовы макросов prelx и pdefx должны располагаться ПОСЛЕ всех вызовов</div><div class="code_line">callx/invokex, но ДО кода процедур, в которых используется данный механизм.</div><div class="code_line">&nbsp;</div><div class="code_line">Поскольку в callx.inc могут появляться новые функции, перед включением этого файла можно определить константу с именем</div><div class="code_line">callx_ver_req, присвоив ей номер минимально требуемой версии callx. Если версия включаемого файла callx.inc будет ниже</div><div class="code_line">указанной, компилятор выдаст сообщение об ошибке.</div><div class="code_line">&nbsp;</div><div class="code_line">Для наглядной демонстрации использования механизма callx в папке examples созданы примеры (для DOS и Windows).</div><div class="code_line">Примеры использования механизма исключения для процедур главного модуля смотрите в папке examples\Windows (1,2,B,C,Y,Z).</div><div class="code_line">&nbsp;</div><div class="code_line">------------------------------------------------------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">:: ИСТОРИЯ ВЕРСИЙ ::</div><div class="code_line">&nbsp;</div><div class="code_line">v1.01 (09.01.2017)</div><div class="code_line">[+] Добавлена проверка версии callx: для этого ПЕРЕД включением файла callx.inc в проект нужно определить константу</div><div class="code_line">&nbsp;&nbsp; &nbsp;callx_ver_req, хранящую минимально требуемую версию callx.</div><div class="code_line">[*] Все примеры переведены из кодировки Windows-1251 в DOS-866.</div><div class="code_line">&nbsp;</div><div class="code_line">v1.00 (07.01.2017)</div><div class="code_line">[!] Самая первая версия.</div><div class="code_line">&nbsp;&nbsp; &nbsp;Поддерживается возможность написания кода, который компилируется и работает даже при отсутствии файла callx.inc.</div><div class="code_line">&nbsp;</div><div class="code_line">------------------------------------------------------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">:: СВЯЗЬ С АВТОРОМ ::</div><div class="code_line">&nbsp;</div><div class="code_line">Данный include-файл написан Евгением Красниковым в 2017 году.</div><div class="code_line">Замечания и предложения присылайте на e-mail: jin.x@sources.ru.</div><div class="code_line">Самую свежую версию можно скачать на сайте: http://xk7.ru/p/a/i.</div><div class="code_line">Мои проекты на ассемблере можно найти также на форумах (cyberforum.ru, forum.sources.ru, wasm.in, programmersforum.ru) по метке/ключевому слову asm7x.</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<span class="b-attach" data-size="38142" data-hits="191" data-attach-id="51309" data-attach-post-id="3700993">
			<span class="b-attach__title"></span><a class='b-attach-link' href='https://forum.sources.ru/index.php?act=Attach&amp;type=post&amp;id=3700993&amp;attach_id=51309' title='Скачать файл' target='_blank'>callx_1.01.zip</a> (, : 191)
		</span><br>
<br>
<span class='tag-size' data-value='7' style='font-size:7pt;'><span class="tag-color tag-color-named" data-value="gray" style="color: gray">Старые версии:<br>
<span class="b-attach" data-size="37517" data-hits="192" data-attach-id="51285" data-attach-post-id="3700993">
			<span class="b-attach__title"></span><a class='b-attach-link' href='https://forum.sources.ru/index.php?act=Attach&amp;type=post&amp;id=3700993&amp;attach_id=51285' title='Скачать файл' target='_blank'>callx_1.00.zip</a> (, : 192)
		</span></span></span>]]></description>
        <author>Jin X</author>
        <category>Assembler</category>
      </item>
	
      </channel>
      </rss>
	