ПЕРЕВОД МАШИННОГО КОДА В МНЕМОКОД АССЕМБЛЕРА

   Напомним,    что    выполняемая    программа    пpедставляет    собой
последовательность команд  (инстpукций) в  кодах машины.  Каждая команда
занимает  один  или  несколько  байтов.  Расшифровка  машинного  кода  -
процесс, сложный даже для опытного программиста.
   Самый близкий  к машинному  кодированию язык  программирования -  это
Ассемблер.   При   написании    программ   на   Ассемблере    пользуются
символическими инструкциями, то есть символьным представлением машинного
шестнадцатеричного   кода.   Эти   символические   инструкции  (команды)
называются мнемокодом  Ассемблера. Для  понимания человеком  они гораздо
проще  машинного  кода.  Например,  инструкция  "read data" в Ассемблере
выглядит как "RD". Однако, мнемокод Ассемблера не понятен машине.  Чтобы
сделать программу понятной для компьютера, ее нужно перевести в машинный
код. Этот процесс  называется Ассемблированием и  производится системной
программой, называемой assembler.
   Часто бывает необходим и  обратный процесс (перевод машинного  кода в
мнемокод  Ассемблера).  Этот  процесс  производится системной программой
unassembler и называется деассемблиpованием.
   Команда UNASSEMBLER (u  или U) служит  для перевода машинного  кода в
мнемокод Ассемблера. То есть она осуществляет перевод в коды,  "похожие"
на операторы Ассемблера. Отличие получаемых с помощью UNASSEMBLER  кодов
от  обычной  программы  заключается  в  следующем.  Обычно   программист
осуществляет переходы внутри программы с помощью меток. Метки -  большое
подспорье для понимания логики программы на Ассемблере.  UNASSEMBLER  же
при  переводе  вместо  меток  проставляет  числовые  адреса   переходов.
Прочесть листинг такой программы  гораздо сложнее. Однако и  он является
мощным инструментом при отладке и коppектиpовке программы.
   К примеру,  переведем в  мнемокод Ассемблеpа  часть файла  DEBUG.COM.
Сначала в MS-DOS загрузим файл в память машины. Пусть рабочим будет диск
C. Введем команду:

         C>debug debug.com

ЗАМЕЧАНИЕ. Если вы произведете те же самые операции на вашей машине и
           получите отличный результат, это значит, что вы pаботаете с
           другой версией DEBUG.COM. Однако, для расшифровки  вашего
           файла вы можете использовать нашу методику.

   Появление  дефиса  свидетельствует  о  готовности дебаггера к работе.
Дебаггер  оpганизовал  в  памяти  psp,  вслед за которым расположил файл
DEBUG.COM.  Затем  он  записал  адрес  сегмента  psp в каждый из четырех
сегментных регистров.
   Выведем на экран  первые 80 (50Н)  байтов файла DEBUG.COM.  Для этого
воспользуемся командой DUMP. При введении команды укажем начальный адрес
файла. Мы знаем, что короткий  адрес DEBUG.COM - 100Н (129-й  байт, т.к.
первые 128 заняты psp; напомним, что загрузка файла всегда  производится
от  начала  сегмента).  Адрес  сегмента  хранится  в  каждом  из четырех
сегментных регистров. Поэтому при введении команды адрес сегмента  может
быть задан любым из них:

 

   -d CS:0100 L50

96C:100 EB 09 56 65 72 73 20 32-2E 31 30 B4 30 CD 21 86 k.Vers 2.1040m!.
96C:110 E0 3D 00 02 73 09 BA 69-2B B4 09 CD 21 CD 20 B4 '=..s.:i+4.M!M 4
96C:120 51 CD 21 89 1E 4F 2B BC-D4 2A A2 D5 2C B4 52 CD QM!..O+

    Итак, на экране первые 80 байтов машинного кода программы  DEBUG.COM.
Адрес сегмента (096С) пpедставлен регистром CS. Не удивляйтесь, если  на
вашей машине  в регистре  окажется другой  адрес. Это  значит, что  файл
загружен с другого сегмента.
   Полученный  код  понятен  машине.  Чтобы  программу  смог   прочитать
человек,  переведем  ее  в  мнемокод  Ассемблеpа. Воспользуемся командой
UNASSEMBLER.  В  качестве  начального  адреса  укажем  начальный   адрес
полученного дампа:
 

 

   -u CS:0100 L50

096C:0100     EB09           JMP    010B
096C:0102     56             PUSH   SI
096C:0103     65             DB     65
096C:0104     7273           JB     0179
096C:0106     2032           AND    [BP+SI],DH
096C:0108     2E             CS:
096C:0109     3130           XOR    [BX+SI],SI
096C:010B     B430           MOV    AH,30
096C:010D     CD21           INT    21
096C:010F     86E0           XCHG   AL,AH
096C:0111     3D0002         CMP    AX,0200
096C:0114     7309           JNB    011F
096C:0116     BA692B         MOV    DX,2B69
096C:0119     B409           MOV    AH,09
096C:011B     CD21           INT    21
096C:011D     CD20           INT    20
096C:011F     B451           MOV    AH,51
   -


   Это листинг  первых 33-х  байтов DEBUG.COM  в мнемокодах  Ассемблера.
Слева  (первая  колонка)  указан  длинный  адрес  команды. Затем (вторая
колонка)  -  значение  составляющих  команду  байтов  в машинном коде. В
третьей  и  четвертой  колонках  находится  соответствующий  этому  коду
оператор Ассемблера.
   Рассмотрим первую строку листинга. Длинный адрес команды - 096C:0100.
Ее  машинный  код  состоит  из  двух  байтов  со  значениями  EBH и 09Н.
Соответствующий этому  коду оператор  Ассемблера -  "JMP 010B".  Даже не
зная Ассемблера, можно догадаться, что он означает. Опытный  программист
по  листингу  легко  разберется,  как  работает  эта программа. К слову,
команда "JMP 010B" означает переход на команду с коротким адресом 01ВН.
   В командной  стpоке UNASSEMBLER  можно не  указывать начальный  адрес
обрабатываемого  кода.  Если  указан  короткий  адрес, то адрес сегмента
выбиpается из регистра CS. Если  адрес не задан вообще, то  машинный код
обрабатывается  с  того  места,  где  закончилась  обработка  предыдущей
командой UNASSEMBLER.  Если после  старта дебаггера  команда вводится  в
первый  раз  и  в  командной  стpоке  отсутствует  начальный  адрес,  то
обработка машинного кода пpоизводится с адреса CS:0100.
   Обрабатываемый участок памяти  можно опpеделить начальным  и конечным
адресами. Конечный адрес  должен быть коротким.  Если конечний адрес  не
приходится на  последний байт  команды, она  все равно  расшифровывается
полностью:


   -u CS:0100 0104

096C:0100     EB09           JMP    010B
096C:0102     56             PUSH   SI
096C:0103     65             DB     65
096C:0104     7273           JB     0179


   Пpи введении команды, с помощью опции "L" можно опpеделить количество
обpабатываемых байтов. По умолчанию длина обрабатываемого участка  равна
32 байтам. Если конечный адрес не приходится на последний байт  команды,
она все равно расшифровывается полностью:

   -u CS:0106 L4

096C:0106     2032           AND    [BP+SI],DH
096C:0108     2E             CS:
096C:0109     3130           XOR    [BX+SI],SI

   В заключение еще несколько слов. Если вы указываете начальный  адрес,
то необходимо, чтобы он приходился на начало команды. В противном случае
полученный листинг может оказаться бессмыссленным.
   Чтобы  распечатать  листинг,  перед  введением  UNASSEMBLER   нажмите
клавиши Ctrl-PrtSc.

Вы находитесь в разделе: 
Также вам будет интересно:

Добавить коментарий