<?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=214452&amp;view=findpost&amp;p=3576547</guid>
        <pubDate>Mon, 23 Feb 2015 19:05:17 +0000</pubDate>
        <title>Использование стандартного отладчика debug.exe</title>
        <link>https://forum.sources.ru/index.php?showtopic=214452&amp;view=findpost&amp;p=3576547</link>
        <description><![CDATA[winsoft: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=214452&view=findpost&p=3102803'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>asminog &#064; <time class="tag-quote__quoted-time" datetime="2012-03-25T00:56:31+04:00">24.03.12, 20:56</time></span><div class='quote '>Здравствуйте&#33;<br>
А у меня такой вот вопрос возник. Набираю в debug команду:<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">U 0116:108A</div><div class="code_line">&nbsp;</div><div class="code_line">0116:108A 90 &nbsp; &nbsp; NOP</div><div class="code_line">0116:108B 90 &nbsp; &nbsp; NOP</div><div class="code_line">0116:108C E8E000 CALL 116F</div><div class="code_line">0116:108F 2E &nbsp; &nbsp; CS:</div><div class="code_line">............................</div><div class="code_line">............................</div><div class="code_line">.........</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><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">0116:108F 2E &nbsp; &nbsp; CS:</div></ol></div></div></div></div><br>
НЕ МОГУ НАЙТИ НИ В ОДНОМ СПРАВОЧНИКЕ&#33;  :) <br>
<br>
СПАСИБО&#33;</div></div><br>
<strong class='tag-b'>asminog</strong>, это обращение к сегменту кода вместо сегмента данных. В следующей строке может быть, скажем, что-то типа<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">MOV DS, [3DE7]</div></ol></div></div></div></div><br>
записывающее в DS значение, находящееся в сегменте кода по смещению 3DE7.]]></description>
        <author>winsoft</author>
        <category>Assembler FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=214452&amp;view=findpost&amp;p=3102803</guid>
        <pubDate>Sat, 24 Mar 2012 20:56:31 +0000</pubDate>
        <title>Использование стандартного отладчика debug.exe</title>
        <link>https://forum.sources.ru/index.php?showtopic=214452&amp;view=findpost&amp;p=3102803</link>
        <description><![CDATA[asminog: Здравствуйте&#33;<br>
А у меня такой вот вопрос возник. Набираю в debug команду:<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">U 0116:108A</div><div class="code_line">&nbsp;</div><div class="code_line">0116:108A 90 &nbsp; &nbsp; NOP</div><div class="code_line">0116:108B 90 &nbsp; &nbsp; NOP</div><div class="code_line">0116:108C E8E000 CALL 116F</div><div class="code_line">0116:108F 2E &nbsp; &nbsp; CS:</div><div class="code_line">............................</div><div class="code_line">............................</div><div class="code_line">.........</div></ol></div></div></div></div><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">0116:108F 2E &nbsp; &nbsp; CS:</div></ol></div></div></div></div><br>
НЕ МОГУ НАЙТИ НИ В ОДНОМ СПРАВОЧНИКЕ&#33;  :) <br>
<br>
СПАСИБО&#33;]]></description>
        <author>asminog</author>
        <category>Assembler FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=214452&amp;view=findpost&amp;p=1796033</guid>
        <pubDate>Sat, 08 Dec 2007 15:40:43 +0000</pubDate>
        <title>Использование стандартного отладчика debug.exe</title>
        <link>https://forum.sources.ru/index.php?showtopic=214452&amp;view=findpost&amp;p=1796033</link>
        <description><![CDATA[winsoft: <div class='tag-align-center'><span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Использование стандартного отладчика debug.exe</strong></span></span></div><br>
Сегодня мы рассмотрим стандартный отладчик <strong class='tag-b'>debug.exe</strong>, входящий в любую версию DOS/Windows. Должен заметить, что этот отладчик не такой мощный, как гиганты SoftICE или Turbo Debugger. Однако, в то же время <strong class='tag-b'>debug.exe</strong> очень прост и доступен, и поэтому идеально подходит для начинающих программистов на языке Ассемблер.<br>
Итак, запускаем <strong class='tag-b'>debug.exe</strong> (для этого заходим в Пуск-&gt;Выполнить и выполняем команду <strong class='tag-b'>debug</strong>) и начинаем изучать этот замечательный отладчик :) <br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='11' style='font-size:11pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>Команды debug.exe</strong></span></span></div><br>
Для начала разберемся с правилами набора команд <strong class='tag-b'>debug.exe</strong>:<ul class="tag-list"><li>В <strong class='tag-b'>debug.exe</strong> не различается регистр букв.</li><li>Пробелы в командах используется только для разделения параметров.</li><li>Вводимые числа должны быть в шестнадцатеричной системе счисления, причем <em class='tag-i'>без</em> завершающей буквы <strong class='tag-b'>h</strong>.</li><li>Сегмент и смещение записываются с использованием двоеточия, в формате <strong class='tag-b'>сегмент:смещение</strong>, например, <strong class='tag-b'>CS:3C1</strong> (смещение <strong class='tag-b'>3C1h</strong> в сегменте кода) или <strong class='tag-b'>40:17</strong> (смещение <strong class='tag-b'>17h</strong> в сегменте, адрес начала которого - <strong class='tag-b'>40[0]h</strong>).</li></ul><br>
Разобравшись с правилами, давайте перейдем к изучению команд <strong class='tag-b'>debug.exe</strong>. Замечу, что работа с командами <strong class='tag-b'>debug.exe</strong> в чем-то похожа на работу с командной строкой DOS. Поcле загрузки отладчика на экране появится приглашение, выглядещее в виде дефиса:<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></ol></div></div></div></div><br>
Регистры <strong class='tag-b'>CS</strong>, <strong class='tag-b'>DS</strong>, <strong class='tag-b'>ES</strong>, <strong class='tag-b'>SS</strong> в этот момент инициализированы <em class='tag-i'>адресом 256-байтного префикса сегмента програмы</em>, а рабочая области в памяти будет начинаться с <em class='tag-i'>адреса этого префикса + 100h</em>.<br>
Команды <strong class='tag-b'>debug.exe</strong> вводятся сразу после приглашения на месте, которое отмечено курсором. Каждая команда состоит из идентификатора и параметров, идентификатор состоит из одной буквы.<br>
<br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Краткая таблица всех команд debug.exe</strong></span><br>
<table class='post_table tag-table'><tr><th>Команда</th><th>Описание</th><th>Формат</th></tr><tr><td>A (Assemble)</td><td>Транслирование команд ассемблера в машинный код;<br>
адрес по умолчанию - <strong class='tag-b'>CS:0100h</strong>.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>A [&lt;адрес_начала_кода&gt;]</strong></span></td></tr><tr><td>C (Compare)</td><td>Сравнение содержимого двух областей памяти; по умолчанию используется <strong class='tag-b'>DS</strong>.<br>
В команде указывается либо длина участков, либо диапазон адресов.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>C &lt;начальный_адрес_1&gt; L&lt;длина&gt; &lt;начальный_адрес_2&gt; </strong></span><br>
<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>C &lt;начальный_адрес_1&gt; &lt;конечный_адрес_1&gt; &lt;начальный_адрес_2&gt; </strong></span></td></tr><tr><td>D (Display/Dump)</td><td>Вывод содержимого области памяти в шестнадцатеричном и ASCII-форматах.<br>
По умолчанию используется <strong class='tag-b'>DS</strong>; можно указывать длину или диапазон.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>D [&lt;начальный_адрес&gt; [L&lt;длина&gt;]]</strong></span><br>
<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>D [начальный_адрес конечный_адрес]</strong></span></td></tr><tr><td>E (Enter)</td><td>Ввод в память данные или инструкции машинного кода;<br>
по умолчанию используется <strong class='tag-b'>DS</strong>.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>E [&lt;адрес&gt; [&lt;инструкции/данные&gt;]]</strong></span></td></tr><tr><td>F (Fill)</td><td>Заполнение области памяти данными из списка; по умолчанию используется <strong class='tag-b'>DS</strong>.<br>
Использовать можно как длину, так и диапазон.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>F &lt;начальный_адрес_1&gt; L&lt;длина&gt; &#39;&lt;данные&gt;&#39; </strong></span><br>
<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>F &lt;начальный_адрес&gt; &lt;конечный_адрес&gt; &#39;&lt;данные&gt;&#39; </strong></span></td></tr><tr><td>G (Go)</td><td>Выполнение отлаженной программы на машинном языке до указанной точки останова;<br>
по умолчанию используется <strong class='tag-b'>CS</strong>. При этом убедитесь, что <strong class='tag-b'>IP</strong> содержит корректный адрес.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>G [=&lt;начальный_адрес&gt;] &lt;адрес_останова&gt; [&lt;адрес_останова&gt; ...]</strong></span></td></tr><tr><td>H (Hexadecimal)</td><td>Вычисление суммы и разности двух шестнадцатеричных величин.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>H &lt;величина_1&gt; &lt;величина_2&gt;</strong></span></td></tr><tr><td>I (Input)</td><td>Считывание и вывод одного байта из порта.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>I &lt;адрес_порта&gt;</strong></span></td></tr><tr><td>L (Load)</td><td>Загрузка файла или данных из секторов диска в память; по умолчанию - <strong class='tag-b'>CS:100h</strong>.<br>
Файл можно указать с помощью команды <strong class='tag-b'>N</strong> или аргумента при запуске <strong class='tag-b'>debug.exe</strong>.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>L [&lt;адрес_в_памяти_для_загрузки&gt;]</strong></span><br>
<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>L [&lt;адрес_в_памяти_для_загрузки&gt; [&lt;номер_диска&gt; &lt;начальный_сектор&gt; &lt;количество_секторов&gt;]]</strong></span></td></tr><tr><td>M (Move)</td><td>Копирование содержимого ячеек памяти; по умолчанию используется <strong class='tag-b'>DS</strong>.<br>
Можно указывать как длину, так и диапазон.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>M &lt;начальный_адрес&gt; L&lt;длина&gt; &lt;адрес_назначения&gt;</strong></span><br>
<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>M &lt;начальный_адрес&gt; &lt;конечный_адрес&gt; &lt;адрес_назначения&gt;</strong></span></td></tr><tr><td>N (Name)</td><td>Указание имени файла для команд <strong class='tag-b'>L</strong> и <strong class='tag-b'>W</strong>.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>N &lt;имя_файла&gt;</strong></span></td></tr><tr><td>O (Output)</td><td>Отсылка байта в порт.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>O &lt;адрес_порта&gt; &lt;байт&gt;</strong></span></td></tr><tr><td>P (Proceed)</td><td>Выполнение инструкций <strong class='tag-b'>CALL</strong>, <strong class='tag-b'>LOOP</strong>, <strong class='tag-b'>INT</strong> или повторяемой строковой инструкции<br>
с префиксами <strong class='tag-b'>REPnn</strong>, переходя к следующей инструкции.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>P [=&lt;адрес_начала&gt;] [&lt;количество_инструкций&gt;]</strong></span></td></tr><tr><td>Q (Quit)</td><td>Завершение работы <strong class='tag-b'>debug.exe</strong>.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>Q</strong></span></td></tr><tr><td>R (Register)</td><td>Вывод содержимого регистров и следующей инструкции.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>R &lt;имя_регистра&gt;</strong></span></td></tr><tr><td>S (Search)</td><td>Поиск в памяти символов из списка; по умолчанию используется <strong class='tag-b'>DS</strong>.<br>
Можно указывать как длину, так и диапазон.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>S &lt;начальный_адрес&gt; L&lt;длина&gt; &#39;&lt;данные&gt;&#39;</strong></span><br>
<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>S &lt;начальный_адрес&gt; &lt;конечный_адрес&gt; &#39;&lt;данные&gt;&#39;</strong></span></td></tr><tr><td>T (Trace)</td><td>Пошаговое выполнение программы. Как и в команде <strong class='tag-b'>P</strong>, по умолчанию используется<br>
пара <strong class='tag-b'>CS:IP</strong>. Замечу, что для выполнения прерываний лучше пользоваться командой <strong class='tag-b'>P</strong>.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>T [=&lt;адрес_начала&gt;] [&lt;количество_выполняемых_команд&gt;]</strong></span></td></tr><tr><td>U (Unassemble)</td><td>Дизассемблирование машинного кода; по умолчанию используется пара <strong class='tag-b'>CS:IP</strong>. К сожалению,<br>
<strong class='tag-b'>debug.exe</strong> некорректно дизассемблирует специфические команды процессоров <strong class='tag-b'>80286+</strong>,<br>
хотя они все равно выполняются корректно.</td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>U [&lt;начальный_адрес&gt;]</strong></span><br>
<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>U [&lt;начальный_адрес конечный_адрес&gt;]</strong></span></td></tr><tr><td>W (Write)</td><td>Запись файла из <strong class='tag-b'>debug.exe</strong>; необходимо обязательно задать имя файла командой <strong class='tag-b'>N</strong>, если<br>
он не был загружен. <strong class='tag-b'>А программы записываются только в виде файлов .COM&#33;</strong></td><td><span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>W [&lt;адрес&gt; [&lt;номер_диска&gt; &lt;начальный_сектор&gt; &lt;количество_секторов&gt;]]</strong></span></td></tr></table><br>
<strong class='tag-b'>Примечание.</strong> Символами <span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>[]</strong></span> отмечены необязательные параметры.<br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='11' style='font-size:11pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>Просмотр областей памяти</strong></span></span></div><br>
В этой части нашей статьи мы рассмотрим подробно работу команды <strong class='tag-b'>D</strong>, позволяющей просматривать содержимое отдельных областей памяти.<br>
Этот пример использует команду <strong class='tag-b'>D</strong> для просмотра области памяти, начиная с <strong class='tag-b'>0159:0240</strong>:<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">-d 0159:0240</div><div class="code_line">0159:0240 &nbsp;00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 &nbsp; ..........l.....</div><div class="code_line">0159:0250 &nbsp;00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 &nbsp; ................</div><div class="code_line">0159:0260 &nbsp;00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 &nbsp; ................</div><div class="code_line">0159:0270 &nbsp;00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 &nbsp; ................</div><div class="code_line">0159:0280 &nbsp;00 00 00 00 00 00 00 00-00 FF FF FF FF 00 00 00 &nbsp; ................</div><div class="code_line">0159:0290 &nbsp;FF 00 00 00 00 00 00 00-00 00 4E 4F 20 4E 41 4D &nbsp; ..........NO NAM</div><div class="code_line">0159:02A0 &nbsp;45 20 20 20 20 00 26 81-4F 03 00 01 CB 00 00 00 &nbsp; E &nbsp; &nbsp;.&amp;.O.......</div><div class="code_line">0159:02B0 &nbsp;00 00 00 00 00 00 00 00-00 00 00 01 07 04 FF 02 &nbsp; ................</div><div class="code_line">-_</div></ol></div></div></div></div><br>
<br>
Здесь на запрос просмотра участка памяти мы получили восемь строк, в которых указано содержимое выбранной области памяти. Каждая строка состоит из трех частей:<ul class="tag-list"><li>Адрес первого слева показанного байта в формате <strong class='tag-b'>сегмент:смещение</strong>.</li><li>Шестнадцатеричное представление параграфа (16 байт), начинающегося с указанного в начале строки байта.</li><li>Символы этого же параграфа в ASCII-формате.</li></ul><br>
Адрес, указанный в строке, относится исключительно к первому байту в параграфе, а адреса последующих байтов следует вычислять самостоятельно. Шестнадцатеричное представление содержит по два знака в каждом байте, а сами байты разделены пробелами для облегчения чтения. Кроме того, следует отметить, что восьмой и девятый байты разделены дефисом, разделяя тем самым параграф на две части и облегяая вычисление адресов байтов в параграфе.<br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='11' style='font-size:11pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>Полезные приемы с командой D</strong></span></span></div><br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Проверка параллельных и последовательных портов</strong></span><br>
Первые 16 байт области данных BIOS содержат адреса параллельных и последовательных портов. Поэтому с помощью следующей команды можно проверить эти порты:<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">-D 40:00_</div></ol></div></div></div></div><br>
Первые выведенные восемь байтов указывают на адреса последовательных портов COM1-COM4. Следующие 8 байтов указывают на адреса параллельных портов LPT1-LPT4.<br>
Например, если на вашем компьютере есть один параллельный порт, то первые два байта будут, скорее всего, такими: <strong class='tag-b'>7803</strong>. Адрес порта записывается в обращенной последовательности, т.е. <strong class='tag-b'>0378</strong>.<br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Проверка оборудования</strong></span><br>
Первые два байта, располагающиеся в BIOS по адресу 410h, содержат информацию об установленном в системе оборудовании. Находим эти байты командой:<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">-D 40:10_</div></ol></div></div></div></div><br>
Предположим, что первые два байта окажутся <strong class='tag-b'>23 44</strong>. Расшифруем эти байты для получения информации об установленных устройствах. Для этого обратим эти байты (<strong class='tag-b'>44 23</strong>), затем переведем их в двоичную систему счисления. Получаем:<br>
<table class='post_table tag-table'><tr><td><strong class='tag-b'>Значение бита</strong></td><td><div class='tag-align-right'>0</div></td><td><div class='tag-align-right'>1</div></td><td><div class='tag-align-right'>0</div></td><td><div class='tag-align-right'>0</div></td><td><div class='tag-align-right'>0</div></td><td><div class='tag-align-right'>1</div></td><td>0</td><td>0</td><td>0</td><td>0</td><td>1</td><td>0</td><td>0</td><td>0</td><td>1</td><td>1</td></tr><tr><td><strong class='tag-b'>Позиция бита</strong></td><td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>9</td><td>8</td><td>7</td><td>6</td><td>5</td><td>4</td><td>3</td><td>2</td><td>1</td><td>0</td></tr></table><br>
<br>
Что означают эти биты? Продолжаем расшифровывать:<br>
<table class='post_table tag-table'><tr><th>Биты</th><th>Устройство</th></tr><tr><td>15, 14</td><td>Число параллельных портов (<strong class='tag-b'>01</strong> = 1 порт, ...)</td></tr><tr><td>11, 10, 9</td><td>Число последовательных портов (..., <strong class='tag-b'>010</strong> = 2 порта, ...)</td></tr><tr><td>7, 6</td><td>Число дисководов (<strong class='tag-b'>00</strong> = 1 дисковод, <strong class='tag-b'>01</strong> = 2, <strong class='tag-b'>10</strong> = 3, <strong class='tag-b'>11</strong> = 4)</td></tr><tr><td>5, 4</td><td>Начальный видеорежим (<strong class='tag-b'>01</strong> = 40х25 цветной, <strong class='tag-b'>10</strong> = 80х25 цветной, <strong class='tag-b'>11</strong> = 80х25 монохромный)</td></tr><tr><td>1</td><td>Присутствие математического сопроцессора (<strong class='tag-b'>0</strong> = нет, <strong class='tag-b'>1</strong> = есть)</td></tr><tr><td>0</td><td>Наличие привода для дискет (<strong class='tag-b'>0</strong> = нет, <strong class='tag-b'>1</strong> = есть)</td></tr></table><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Проверка состояния регистра клавиатуры</strong></span><br>
В области данных BIOS по адресу <strong class='tag-b'>417h</strong> находится первый байт, который хранит состояние регистра клавиатуры. Выключаем Num Lock и Caps Lock, затем набираем команду:<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">-d 40:17_</div></ol></div></div></div></div><br>
Первый байт будет равен <strong class='tag-b'>00</strong>. Включив Num Lock и Caps Lock, снова выполняем команду. Теперь первый байт должен равняться <strong class='tag-b'>60</strong>. Опытным путем установлено, что при включенном Num Lock первый байт равен <strong class='tag-b'>20</strong>, а при Caps Lock - <strong class='tag-b'>40</strong>. :)<br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Проверка состояния видеосистемы</strong></span><br>
По адресу 449h в BIOS находится первая область видеоданных. Для проверки набираем:<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">-d 40:49_</div></ol></div></div></div></div><br>
Первый байт показывает текущий видеорежим (к примеру, <strong class='tag-b'>03</strong> - цветной), а второй - число столбцов (например, <strong class='tag-b'>50</strong> - режим с 80 столбцами). Число строк можно найти по адресв <strong class='tag-b'>484h</strong> (<strong class='tag-b'>40:84</strong>).<br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Проверка копирайта BIOS и серийного номера</strong></span><br>
Сведения об авторских правах на BIOS встроены в ROM BIOS по адресу <strong class='tag-b'>FE00:0</strong>. Строку с копирайтом можно легко найти в ASCII-последовательности, а серийный номер - в виде шестнадцатеричного числа. Хотя, строка с указанием авторских прав может быть длинной и не умещаться в выведенную область памяти. В таком случае следует просто ввести еще раз <strong class='tag-b'>D</strong>.<br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Проверка даты произвоства BIOS</strong></span><br>
Эта дата также записана в ROM BIOS начиная с адреса FFFF:5. После выполнения соответствующей команды в ASCII-последовательности будет находиться эта дата, записанная в формате мм/дд/гг.<br>
<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">-d FFFF:5</div><div class="code_line">FFFF:0000 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 31 31 2F-32 38 2F 30 35 00 FC 00 &nbsp; &nbsp; &nbsp; &nbsp;11/28/05...</div><div class="code_line">FFFF:0010 &nbsp;34 12 00 00 00 00 00 00-00 00 00 00 00 00 00 00 &nbsp; 4...............</div><div class="code_line">...</div><div class="code_line">&nbsp;</div><div class="code_line">-_</div></ol></div></div></div></div><br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='11' style='font-size:11pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>Непосредственный ввод программы в память с помощью debug.exe</strong></span></span></div><br>
<strong class='tag-b'>debug.exe</strong> позволяет вводить программу непосредственно в память машины, а затем следить и управлять ее выполнением. Мы будем вводить программу в машинных кодах, используя команду <strong class='tag-b'>E</strong>. При этом будьте бдительны - <strong class='tag-b'>ввод ошибочных данных по ошибочному адресу чреват непредсказумыми последствиями</strong>&#33; Хотя к серьезным проблемам в системе это вряд ли приведет, но потерять все данные, введенные в <strong class='tag-b'>debug.exe</strong>, можно потерять запросто.<br>
Программа, которую мы сейчас будем вводить, использует данные, заложенные непосредственно в теле инструкций. Далее показан листинг программы на Ассемблере, в комментариях указаны аналоги команд языка в машинных кодах, а также объяснение каждй команды. Замечу, что в числах нет символа <strong class='tag-b'>h</strong>, поскольку, как было сказано выше, <strong class='tag-b'>debug.exe</strong> понимает только числа в шестнадцатеричной системе.<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">MOV AX, 0123 ; код B82301: заносим значение 0123h в AX</div><div class="code_line">ADD AX, 0025 ; код 052500: прибавляем 0225h к значению AX</div><div class="code_line">MOV BX, AX &nbsp; ; код 8BD8: заносим значение AX в BX</div><div class="code_line">ADD BX, AX &nbsp; ; код 03D8: прибавляем значение AX к BX</div><div class="code_line">MOV CX, BX &nbsp; ; код 8BCB: заносим значение BX в CX</div><div class="code_line">SUB CX, AX &nbsp; ; код 2BC8: отнимаем значение AX из CX</div><div class="code_line">SUB AX, AX &nbsp; ; код 2BC0: очищаем AX</div><div class="code_line">JMP 100 &nbsp; &nbsp; &nbsp;; код EBEE: переходим к началу программы</div></ol></div></div></div></div><br>
Как можно заметить, каждая машинная инструкция имеет длину от 1 до 3 байтов. Первый байт указывает операцию, последующие - ее операнды. Исполнение программы начинается соответственно с первой инструкции и последовательно проходит через все инструкции одну за другой.<br>
Теперь можно ввести программу в память. Разделим машинный код на три части по шесть байт и введем каждую, используя команду <strong class='tag-b'>E</strong> и начиная с адреса <strong class='tag-b'>CS:100</strong>.<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">-E CS:100 B8 23 01 05 25 00</div><div class="code_line">-E CS:106 8B D8 03 D8 8B CB</div><div class="code_line">-E CS:10C 2B C8 2B C0 EB EE</div><div class="code_line">-_</div></ol></div></div></div></div><br>
Теперь, когда программа введена в память, попробуем управлять ее выполнением. Для начала проверим текущее состояние регистров и флагов, для этого вводим команду <strong class='tag-b'>R</strong>. Отладчик выведет содержимое регистров в шестнадцатеричной форме; на разных машинах содержимое регистров может различаться.<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">-r</div><div class="code_line">AX=0000 &nbsp;BX=0000 &nbsp;CX=0000 &nbsp;DX=0000 &nbsp;SP=FFEE &nbsp;BP=0000 &nbsp;SI=0000 &nbsp;DI=0000</div><div class="code_line">DS=15D7 &nbsp;ES=15D7 &nbsp;SS=15D7 &nbsp;CS=15D7 &nbsp;IP=0100 &nbsp; NV UP EI PL NZ NA PO NC</div><div class="code_line">15D7:0100 B82301 &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; AX,0123</div><div class="code_line">-_</div></ol></div></div></div></div><br>
Итак, как можно видеть, <strong class='tag-b'>debug.exe</strong> инициализировал сегменты <strong class='tag-b'>DS</strong>, <strong class='tag-b'>ES</strong>, <strong class='tag-b'>SS</strong>, <strong class='tag-b'>CS</strong> одним и тем же адресом. Регистр <strong class='tag-b'>IP</strong> содержит <strong class='tag-b'>0100</strong>, указывая на то, что инструкции выполняются со смещения <strong class='tag-b'>100h</strong> относительно <strong class='tag-b'>CS</strong> (а мы, вводя инструкции в память, как раз указали этот адрес).<br>
Здесь же указаны и значения флагов переполнения, направления, прерывания, знака, нуля, дополнительного переноса, четности и переноса:<br>
<table class='post_table tag-table'><tr><th>Значение</th><th>Описание</th></tr><tr><td>NV</td><td>Отсутствие переполнения</td></tr><tr><td>UP</td><td>Направление вверх или вправо</td></tr><tr><td>EI</td><td>Разрешение прерываний</td></tr><tr><td>PL</td><td>Положительный знак</td></tr><tr><td>NZ</td><td>Ненулевое значение</td></tr><tr><td>NA</td><td>Отсутствие дополнительного переноса</td></tr><tr><td>PO</td><td>Нечетное слово</td></tr><tr><td>NC</td><td>Отсутствие переноса</td></tr></table><br>
<br>
После регистров и состояния флагов <strong class='tag-b'>debug.exe</strong> выводит информацию о первой инструкции, которая будет выполняться:<ul class="tag-list"><li> Адрес инструкции, в нашем случае это <strong class='tag-b'>15D7:0100</strong>, где <strong class='tag-b'>15D7</strong> - адрес сегмента кода.</li><li> Машинный код, соответствующей этой инструкции (<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>B82301</strong></span>).</li><li> Собственно инструкция, записанная на ассемблере (<span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>MOV AX,0123</strong></span>).</li></ul><br>
Теперь, после анализа содержимого регистров и флагов, давайте перейдем к выполнению программу. Выполнять программу мы будем пошагово, используя команду <strong class='tag-b'>T</strong>. Использовав в первый раз команду <strong class='tag-b'>T</strong>, мы выполняем инструкцию <span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>MOV</strong></span>. Здесь машинный код операнда инструкции - <strong class='tag-b'>2301</strong>. Операция помещает <strong class='tag-b'>23</strong> в <strong class='tag-b'>AL</strong> (младшая половина <strong class='tag-b'>AX</strong>), а <strong class='tag-b'>01</strong> - в <strong class='tag-b'>AH</strong> (старшая).<br>
После этого <strong class='tag-b'>debug.exe</strong> снова выводит информацию о регистрах:<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">-t</div><div class="code_line">AX=0123 &nbsp;BX=0000 &nbsp;CX=0000 &nbsp;DX=0000 &nbsp;SP=FFEE &nbsp;BP=0000 &nbsp;SI=0000 &nbsp;DI=0000</div><div class="code_line">DS=15D7 &nbsp;ES=15D7 &nbsp;SS=15D7 &nbsp;CS=15D7 &nbsp;IP=0103 &nbsp; NV UP EI PL NZ NA PO NC</div><div class="code_line">15D7:0100 B82301 &nbsp; &nbsp; &nbsp; &nbsp;ADD &nbsp; &nbsp; AX,0025</div><div class="code_line">-_</div></ol></div></div></div></div><br>
Теперь <strong class='tag-b'>AX</strong> содержит <strong class='tag-b'>0123h</strong>, <strong class='tag-b'>IP</strong> - <strong class='tag-b'>0103h</strong> (следовательно, длина выполненной инструкции: <strong class='tag-b'>0103h</strong> - <strong class='tag-b'>0100h</strong> = <strong class='tag-b'>3</strong> <em class='tag-i'>байта</em>), а в качестве следующей инструкции указана операция <span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>ADD</strong></span>.<br>
Так, раз за разом выполняя команду <strong class='tag-b'>T</strong>, мы дойдем до последней инструкции <span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>JMP 100</strong></span>. Она установит регистр <strong class='tag-b'>IP</strong> в <strong class='tag-b'>100h</strong>, и <strong class='tag-b'>debug.exe</strong> вернется к началу программы. Возвращаясь к началу программы, следует заметить, что в <strong class='tag-b'>DS</strong>, <strong class='tag-b'>ES</strong>, <strong class='tag-b'>SS</strong> и <strong class='tag-b'>CS</strong> содержится один и тот же адрес. Дело в том, что <strong class='tag-b'>debug.exe</strong> рассматривает введенные программы исключительно как программы <strong class='tag-b'>.COM</strong>. А в программах <strong class='tag-b'>.COM</strong>, в отличие от <strong class='tag-b'>.EXE</strong>, стек, код и данные хранятся в одном сегменте.<br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='11' style='font-size:11pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>Ассемблирование и дизассемблирование</strong></span></span></div><br>
В прошлом примере мы вводили программу в машинных кодах, однако, <strong class='tag-b'>debug.exe</strong> вполне способен понимать инструкции, записанные на ассемблере. Для работы с такими программами в <strong class='tag-b'>debug.exe</strong> используются команды <strong class='tag-b'>A</strong> и <strong class='tag-b'>U</strong>.<br>
Команда <strong class='tag-b'>A</strong> запрашивает инструкции на ассемблере и преобразовывает их в машинный код. Для начала инициализируем начальный адрес для ввода инструкций (<strong class='tag-b'>100h</strong>):<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">-a 100_</div></ol></div></div></div></div><br>
Отладчик выведет адрес сегмента кода и смещения (например, <strong class='tag-b'>13F2:0100</strong>). Теперь мы должны ввести следующие инструкции на ассемблере в память, после каждой строки нажимая <strong class='tag-b'>Enter</strong>:<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">MOV CL, 42</div><div class="code_line">MOV DL, 2A</div><div class="code_line">ADD CL, DL</div><div class="code_line">JMP 100</div></ol></div></div></div></div><br>
После ввода последней инструкции нажимаем <strong class='tag-b'>Enter</strong> дважды, чтобы указать отладчику, что мы закончили вводить текст программы. Теперь программу можно запускать, используя команды <strong class='tag-b'>R</strong> для просмотра регистров и <strong class='tag-b'>T</strong> для трассировки. Замечу, что в своих программах при наличии инструкций <span class="tag-font" data-value="Courier" style="font-family:Courier"><strong class='tag-b'>INT</strong></span> их следует обрабатывать не командой <strong class='tag-b'>T</strong>, а командой <strong class='tag-b'>P</strong>, которая обрабатывает все прерывание сразу.<br>
<br>
Перейдем к процедуре дизассемблирования, а в качестве примера возьмем только что введенную программу. Используем адреса первой и последней инструкций для указания диапазона, который мы собираемся дизассемблировать, т.е. <strong class='tag-b'>100h</strong> и <strong class='tag-b'>107h</strong>.<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">-u 100, 107_</div></ol></div></div></div></div><br>
После выполнения этой команды <strong class='tag-b'>debug.exe</strong> выведет инструкции, находящиеся в указанном диапазоне, на ассемблере, в машинных кодах, а также адрес каждой инструкции:<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">13F2:0100 B142 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; CL, 42</div><div class="code_line">13F2:0102 B22A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MOV &nbsp; &nbsp; DL, 2A</div><div class="code_line">13F2:0104 00D1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ADD &nbsp; &nbsp; CL, DL</div><div class="code_line">13F2:0106 EBF8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;JMP &nbsp; &nbsp; 0100</div></ol></div></div></div></div><br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='11' style='font-size:11pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>Итог</strong></span></span></div><br>
А теперь, после небольшого обзора возможностей стандартного отладчика <strong class='tag-b'>debug.exe</strong> давайте подведем итоги. Итак:<ul class="tag-list"><li><strong class='tag-b'>debug.exe</strong> можно применять для наблюдений и отладки программ на ассемблере и машинных кодах.</li><li><strong class='tag-b'>debug.exe</strong> позволяет трассировать программу, устанавливать точки останова, просматривать области памяти, вводить программы непосредственно в память компьютера.</li><li><strong class='tag-b'>debug.exe</strong> представляет загружаемые программы как программы <strong class='tag-b'>.COM</strong>.</li><li><strong class='tag-b'>debug.exe</strong> воспринимает только числа в шестнадцатеричной системе.</li><li><strong class='tag-b'>debug.exe</strong> не различает регистр букв.</li></ul><br>
<strong class='tag-b'>Дополнительные материалы:</strong><br>
<em class='tag-i'>Абель П.</em> АССЕМБЛЕР: Язык и программирование для IBM PC. - К.: Век+, 2003.<br>
<a class='tag-url' href='http://www.allasm.ru/low_prog_01.php' target='_blank'>http://www.allasm.ru/low_prog_01.php</a> - низкоуровневое программирование для дZенствующих - DZebug: руководство юZверя<br>
<a class='tag-url' href='http://thestarman.pcministry.com/asm/debug/debug.htm' target='_blank'>http://thestarman.pcministry.com/asm/debug/debug.htm</a> - A Guide to DEBUG, by Daniel B. Sedory]]></description>
        <author>winsoft</author>
        <category>Assembler FAQ</category>
      </item>
	
      </channel>
      </rss>
	