Использование программы Debug 1. Просмотр памяти Проверка объема основной памяти DOS Эта информация после загрузки DOS находится в 413 и 414 байтах памяти (младший и старший байты). Зададим адрес сегмента: 400 (последний нуль следует “отбросить”) и смещения: 13. Набираем команду _d (display) 40:13 и нажать Enter. Ввод данных строчными или прописными буквами не имеет значения, поскольку DOS в командной строке воспринимает символы ASCII, независимо от выбранного регистра. На эту команду получаем следующую картину на экране дисплея: В каждой строке текста содержатся адреса 16-ти байтов, их шестнадцатеричное и символьное представление, если таковое существует в коде ASCII. Как и должно получиться в первом (413) и втором (414) байтах распечатки содержатся цифры 80 и 02, то есть с учетом “вращения байтов” получаем число 0280h Кбайт в шестнадцатеричном представлении. Переводим в десятичное представление 2*16*16+8*16+0=640 Кб. Что и должно быть! Проверка “серийного номера и даты копирайта” Эта информация находится в ПЗУ, начиная с адреса FE000h. Здесь находятся: семизначный номер компьютера, дата копирайта, фирма изготовитель. Данная информация является символьной. Аналогично наберем адрес памяти:_d FE00:0 <Enter>. На эту команду получаем следующее: Проверка даты “прошивки” ROM BIOS Информация находится по адресу: FFFF5h. Формат даты – американский, то есть mm/dd/yy. 1 Вводим адрес и выполняем команду:_d FFFF:5 <Enter>. По этой команде должна быть выдана информация о дате “прошивки” ПЗУ (ROM BIOS). В верхней строке в символьном представлении читаем интересующую нас дату. Еще одна полезная операция! Если требуется определить местоположение в памяти какой-либо информации (например, какого-то слова), то можно набрать и выполнить команду S (Search – поиск), задав адресные границы поиска и “ключевое слово”. Например, выполнение команды: _s F000:0 L FFFF ”IBM”, в которой F000:0 – начальный адрес памяти ПЗУ, FFFF – конечный адрес, а ”IBM” – ключевое слово, позволяет получить следующие результаты: _s F000:0 L FFFF ”IBM” <Enter> Ниже выполненной команды следует перечень адресов, в которых содержится искомое ключевое слово. Проверьте этот факт, набрав эти адреса памяти. Команду S (Search) можно использовать, например, для поиска вирусов, если известны их “следы” и т.п. Выводы: 1). Эти три операции объективно позволяют определить “модель и возраст компьютера”. 2). Пользуясь этими командами можно просмотреть содержимое любой ячейки памяти. Работа часов реального времени Время, измеряемое компьютером, формируется на основе отсчетов счетчика часов реального времени. Четыре байта этого счетчика располагаются в оперативной памяти, начиная с адреса 0046Сh. Значения счетчика времени корректируется по каждому сигналу от таймера с частотой 18,2 имп/с (более точно 18,206481). Тактовая частота системного таймера персонального компьютера составляет 1,19318Мгц. Она кратна основной частоте, принятой в телевидении f =14,31818 Мгц, и составляет 1/12 этой частоты. Определим значение счетчика с помощью программы debug. 2 Изменение значений байтов счетчика наглядно показывает, что время неотвратимо “бежит вперед”. Задание. Запишите два показания счетчика примерно через одну минуту. С учетом шестнадцатеричного представления чисел определите разницу этих значений. Переведите полученный результат в десятичную систему счисления, поделите на величину 60*18,2 и убедитесь, что темп изменения отсчетов действительно соответствует темпу изменения реального времени. 2. Выявление связей между ассемблерным кодом программы, ее машинным кодом и содержимым основных регистров при выполнении команд программы. Задача. Пусть имеется следующая программа: Адреса 0100 0103 0106 0108 010A 010C 010E 010F Ассемблерный код MOV AX,123 ADD AX,0025 MOV BX,AX ADD BX,AX MOV CX,AX SUB CX,AX SUB AX,AX NOP RETF Машинный код B8 2301 05 2500 89 C3 01 C3 89 C1 29 C1 29 C0 90 CB Содержание (AX):= 123h (AX):= 123h + 25h =148h (BX):= AX (BX):= BX + AX=290h (CX):= BX (CX):= CX – AX=148h (AX):= 0 Обратить внимание при выполнении следующих заданий на следующие моменты: 1). Как вычисляются адреса команд? 2). Как числовая информация размещается в памяти? 3). Как должно меняться и меняется содержимое регистров AX, BX, CX? 3 Ввод программы в память ПК. Прежде всего необходимо задать значение регистра CS в диапазоне (0400…9FF0). За пределами этого диапазона находятся зоны, контролируемые DOS. Последовательно строку за строкой ввести машинные коды программы. Для этого используется команда _E (Edit – редактирование). _E CS:100 _E CS:106 _E CS:10C B8 23 01 05 25 00 <Enter> 89 C3 01 C3 89 C1 <Enter> 29 C1 29 C0 90 CB <Enter> Затем подадим команду _R (Registr) – команду чтения содержимого регистров, включая и регистр флагов. Это позволит просмотреть исходное состояние всех регистров общего назначения перед выполнением программы. Содержимое регистров CS и IP определяет адрес очередной выполняемой команды MOV AX,123, адрес, машинный код и содержание которой приведено после перечня регистров. -r Если теперь подать команду Т (трассировка, то есть покомандное выполнение программы с остановками), то можно увидеть последовательное изменение содержания регистров в соответствии с командами программы. Повторять выполнение команды _Т и анализировать выполнение каждой очередной команды до тех пор, пока не будет выполнена последняя команда программы. 4 Обратить внимание: 1) Как и почему меняется содержимое регистров после выполнения очередной команды программы? 2) Как и почему меняется содержимое регистра флагов? Если потребуется повторить трассировку указанной программы, то следует выполнить следующее: набираем и выполняем команду _R IP, для того, чтобы просмотреть содержимое регистра IP; вводим 0100 и нажимаем клавишу <Enter>. Этим самым регистр IP вновь получает значение 0100, и можно снова повторить трассировку. 3. Пример выполнения программы BIOS 5 Рассмотрим фрагмент программы BIOS, определяющей объем основной памяти DOS компьютера (так же, как это было в примере 1.1.), но не вручную, а по прошитой программе. Программа работает по прерыванию INT 12h. В ранних версиях DOS это прерывание обрабатывалось обработчиком прерываний по следующей программе: STI PUSH DS MOV AX,0040 MOV DS, AX MOV AX, [0013] POP DS IRET В этой программе обратим внимание на начало и конец, где командой PUSH DS обеспечивается сохранение старого значения регистра DS, а командой POP DS восстанавливается это значение. Командой IRET возвращается управление прерванной программе. Рассмотрим, какой последовательностью команд под управлением Windows реализуется теперь обработка этого прерывания. Рассмотрим и сам механизм обращения к обработчику прерывания по его вектору. Известно, что в IBM PC возможно возникновение 256 видов прерываний с номерами от 0 до 255 (или в шестнадцатеричной системе от 0h до FFh). Они занимают младшие адреса оперативной памяти с 0h до 3FFh (1Кбайт). Каждый вектор имеет размер четыре байта, первые два байта определяют значение IP, другие – значение CS программы - обработчика прерывания. При возникновении прерывания любого типа определяется его номер, а затем по его вектору определяется адрес программы обработки этого вида прерывания. Продемонстрируем этот процесс. Поскольку каждый вектор занимает четыре байта, то, увеличив его двоичный номер в четыре раза, получим адрес его вектора. Адрес вектора INT 12h будет равным 100102*4=10010002 или 48h. Посмотрим содержимое этого вектора, послав команду –d 0:48. Определяем, что программа-обработчик этого прерывания имеет адрес IP=09AA, CS=0210. Именно по этому адресу должно быть передано управление. Посмотрим, как это происходит. Запишем в любую область памяти команду, содержащую INT 12h. Она подразумевает вызов обработчика 12h (100102 или 1810) прерывания. Подадим команду R для того, чтобы определить значение регистра CS, а затем введем команду: _E CS:0100 CD 12 CB <Enter>, которая должна обеспечить выполнение 12h (100102 =1810) прерывания. Проследим последовательность обработки этого прерывания, выполняя трассировку. -r 6 Данный фрагмент программы показывает, что после выполнения команды по адресу 0b19:0100, содержащей INT 12h, произошла передача управления на обработку прерывания. После выполнения этой программы регистр АХ будет содержать значение (0280) объема памяти DOS. Это уже известные байты с адресами 0413 и 0414 памяти DOS в шестнадцатеричном формате (см. пример 1.1). Обратите внимание: на адреса местонахождения команд программы и передачу управления им; возможно некоторое расхождение в полученной последовательности команд программы, связанное с тем, что запуск программы Debug осуществлялся из другой версии Windows. Но результат выполнения программы полностью остается тем же. 7 4. Ввод ассемблерных программ в память ПК и перевод их в машинный код Для ввода и перевода программ используются команды Debug’ a: _A (Assemble ассемблирование) и _U (Unassemble - дисассемблирование). Введем команду _А 100 <Enter> По этой команде будет установлен начальный адрес в виде хххх:0100 (хххх – означает произвольное, текущее значение регистра CS). После этого можно вводить покомандно всю программу, например: xxxx:0100 xxxx:0102 xxxx:0104 xxxx:0106 MOV AL,25 MOV BL,32 ADD AL,BL RET <Enter> <Enter> <Enter> <Enter> После окончания ввода всей программы следует еще раз нажать на клавишу <Enter> и операция ввода будет прекращена. Введем команду дисассемблирования _U 0100,106 , где 100 и 106 обозначают соответственно начальный и конечный адреса фрагмента программы, подлежавшего переводу в машинный код. На эту команду будет выдана информация, содержащая ассемблерный и машинный коды программы: xxxx:0100 xxxx:0102 xxxx:0104 xxxx:0106 B025 B332 00D8 C3 MOV AL,25 MOV BL,32 ADD AL,BL RET Наберем и выполним команду _D xxxx:0100 <Enter> Теперь можно рассмотреть соответствие ассемблерных и машинных кодов команд программы, а также их представление в памяти ПК. 8