Fl-Help FZ-Bkpt F3-Hod F4-Here F5-2oon F6-Hext F?-Trace F8-Step F9-Run FlG-dem




Data Options Uindov Help

BEADY

Ё File Edit Uieu Bun Breakpoints -tiJ-flodiile: p File: p.asn 4 ~ -™

;0пиием сегмент конанд

assune CS:codes ,DS:data

;Откроен сегмент команд ;Настроим DS :на сегмент данных

codes segnent
' begin: nou AX,data

*ou DS.AX

;Выведем на экран строку текста

;Функция DOS вывода на экран;Адрес выводимой строки;Вызов DOS ;Функция DOS завершения программы ;Битов DOS ;Закроем сегмент команд

пои AH,G9h

пои DX,offset nsg

Int 21h

:Завершим программу

пои flX,4CeOh

Int 21h

codes ends
:0пинем сегмент данных
data segment.'Откроен сегиент данных

nsg db 'Программа работает!$'

data ends;Закроем сегиент данных

Fl-4telp F2-Bkpt ГЗ-Nod F4-Here FS-Zoon Fo-Next F7-Trace F8-Step FS-Run Fie-Henu

рис. 2.3. Начальный кадр отладчика с текстом отлаживаемой программы.

;0пишем сегмент стека



Глава 2


Основы программирования



 


В процессе отладки программы на экран приходится выводить много дополнительных окон; они перекрываются и часто скрывают друг друга. Чтобы увидеть их все одновременно, размер окон приходится уменьшать, а сами окна перемещать по экрану. Режим изменения размеров и положе­ния окна включается командой <Ctrl>+<F5>, после чего клавиши со стрел­ками перемешают окно по экрану, а те же клавиши при нажатой клавише <Shift> позволяют изменять его размер. Выход из режима настройки окна осуществляется нажатием клавиши <Enter>.

Начальное окно отладчика даст слишком мало информации для от­ладки программы. В нем можно выполнять программу по частям до место­положения курсора (клавиша <F4>) и команда за командой (клавиша <F8>); можно также с помощью окна Watches наблюдать изменения за­данных полей данных. Однако для отладки программы на уровне языка ассемблера необходимо контролировать все регистры процессора, вклю­чая регистр флагов, а также, во многих случаях, поля данных вне про­граммы (например, векторы прерываний или системные таблицы). Гораз­до более информативным является «окно процессора», которое вызыва­ется с помощью пункта View>CPU верхнего меню или командой <AK>+<V>+<C> (рис. 2.1).

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ё File Ш ------- Module:; Опишем се assume codes ^ begin: * : Выведен н * r U leu Run Breakpoints Data Options Uindou Help ~ — —Z^l] R EftDV 13=n сМЭ z=0 s=0 o=0 p=0 a=0 i=l  
   
ttpRbegin a cs:OOQGKB8071Z *begin: now AX, data:Hact cs:8003 8ED8 мои DS.ftX:ма сегнемт 1 cs:Q005 B409 мои ЙН.ОЭЬ; Функция DOi cs:0007 BftOOOO мои OX, offset nsg:Ащ>| cs:OOOA CDZ1 int Zlh: Вызов DOS | cs:00QC B8Q04C мои AX,4COOh; Функция 1 cs:OOOF CB21 int Zlh; Визой DOS I > cs:0011 0000 add [Ьх+sll.al I cs:0013 0000 add Ebx+sil.&l 1 cs:001S 0000 add Ebx*sU,al i cs:0017 0000 add Cbx*siJ,al | cs:OQ19 0000 add Ebx+si],al -» ds:OOQO CD 20 7D 9D 00 9ft FO FE - >3 ЪБ1 ax 0000 bx 0000 ex 0000 dx 0000 si 0000 di 0000 bp 0000 sp 0100 ds 11F5  
Оию исяоакогэ текста   Т  
ss 1209 cs 1205 Окно [тагов  
   
ip 0000      
Окно регистров    
Окно дал па памяти   _. ds:0008 ID FO 3Z OB B9 OF 6B 07 *E2fifl*R. ds:0010 H OD 28 08 14 OD 9Z OB WCQflTTff ds:0018 01 01 01 00 02 06 FF FF 933 B» ss:G10Z 04 ss: 01001-52 --------------- 1 03 FB  
   
     

Fl-Help FZ-Bkpt F3-Hod F4-Here F5-2oon F6-Hext F?-Trace F8-Step F9-Run FlG-dem

Рис. 2.4. Окно процессора с внутренними окнами.

Окно процессора состоит, в свою очередь, из 5 внутренних окон для наблюдения текста программы на языке ассемблера и в машинных кодах, регистров процессора, флагов, стека и содержимого памяти. С помощью этих окон можно полностью контролировать ход выполнения отлаживае-


мой программы. Для того чтобы можно было работать с конкретным ок­ном, например, прокручивать его содержимое, надо сделать его актив­ным, щелкнув по нему мышью. Перейти из окна в окно можно также с помощью клавиатуры, нажимая клавишу Tab. Посмотрим, какие сведе­ния можно изшгечь из содержимого окна процессора.

Содержимое сегментных регистров DS и ES одинаково и составляет llF5h. Эта значит, что программа загружена в память, начиная с физи­ческого адреса 11F50, т.е. приблизительно с 70-го килобайта. Чем заняты первые 70 Кбайт памяти' Обычно компьютер конфигурируется так, что в обычной памяти размещается только малая часть DOS (около 16 Кбайт), драйверы обслуживания расширенной памяти и резидентная часть COMMAND.COM. Основная часть DOS, остальные драйверы и необхо­димые резидентные программы (например, русификатор) переносятся в расширенную память. В этом случае системные области в начале памя­ти занимают всего 20 — 25 Кбайт. Тем не менее наша программа начина­ется не с 25-го, а с 70-го килобайта. Произошло это из-за того, что программа запущена под управлением отладчика, который сначала заг­ружается в память сам, и лишь затем загружает отлаживаемую програм­му. Но отсюда следует, что если бы мы запустили программу без отлад­чика, она попшга бы на другое место в памяти, гораздо ближе к ее нача­лу. В большинстве случаев это обстоятельство не имеет особого значения, так как любая программа должна одинаково успешно выполняться в любом месте памяти, однако необходимо отдавать себе отчет, что отлад­чик изменяет операционную среду программы (в частности, переносит ее на другое место в памяти). Строго говоря, программа под управлени­ем отладчика выполняется не совсем так, как она выполнялась бы не­посредственно в DOS.

Еще один пример «самодеятельности» отладчика можно увидеть в том же окне регистров процессора. Содержимое всех регистров общего назна­чения (АХ, BX, CX, DX, SI, DI и ВР) равно 0. Отсюда можно сделать вывод, что DOS, загружая программу в память, очищает регистры про­цессора. Однако на самом деле это совсем не так! Регистры очищает не DOS, а отладчик. При обычном запуске программы исходное содержимое регистров практически непредсказуемо, и ни в косм случае нельзя рас­считывать, что в них будут нули. Иногда можно столкнуться и с более тонким влиянием отладчика на ход выполнения программы, вплоть до того, что некоторые виды программ, например, управляющие подклю­ченной к компьютеру аппаратурой, в отладчике будут выполняться про­сто неверно.

Итак, после загрузки программы в память содержимое регистров DS и ES оказалось одинаковым. Это вполне естественно, если вспомнить, что перед выполнением оба регистра указывают на префикс программы (см. рис. 1.9). Вслед за префиксом располагается сегмент команд и поскольку префикс всегда занимает точно lOOli байт (т.е. 10h параграфов по 16 байт), то содержимое CS в нашем случае должно быть равно llF5h + 10h = 1205U. Так оно и есть (см. рис. 2.4).


Глава 2


Основы программирования



 


В нашем примере программа должна начать выполняться с метки begin, поскольку именно эту метку мы указали в качестве операнда завершаю­щей директивы end. Эта метка относится к самой первой команде сегмен­та команд и ее значение (или, что то же самое, смещение первой коман­ды программы) должно быть равно 0. Поэтому исходное значение указа­теля команд, как это видно из рис. 2.4, тоже равно 0. В дальнейшем, по мере выполнения команд, значение IP будет возрастать. Выполним две первые команды программы, дважды нажав клавишу <F8>. Состояние программы после этой операции показано на рис. 2.5.

 

 

 

Ё File Edit Uieu Run Breakpoints Data Options Uindou Help HEADY
f — Mrvlii 1^ • rt Filp' n Л4?и V— --------------------- — 1 — ---- ------ " ------ ъ IHJUUtl^' p [11C* p.tlirl • i l
^ boo ЙН.ОЭп
• пои DX, offset nsg |
    c=0
; Завершим • IpRbeg in * ax 1207 cs:QOOQ B80712 «begin: nov AX, data;Haci cs:0063 8ED8 * nou DS.AX;на сегмент cs:0065HH09 * паи AH.OSh; Функция ВО bx 0000 ex 0600 dx 0060 z=0 s=0 o=0
codes cs:6Q07 ВАЭО60 * пои DXjoffset nsg;Адр cs:060A CD21 * int Zlh; Вызов DOS cs:OQ6C B8064C * поч ftX,4CQOh; Функция cs:60QF CD21 + int Zlh; Вы зов DOS cs;0011 0060 add [bx^sil.al si 0006 di 0000 bp 0060 sp 6106 ds 1207 es 11F5 p=0 а-Л
  а-U i=i d=o
  cs:0013 0000 add U>x+si],al cs:0015 0000 add Cbx+sibal cs:0017 6000 add Ibx+sU.al cs:0619 0000 add [bx*sil,al ss 1НОЭ cs 1205 ' ip 0005  
  es:60Q6 CD 26 7D 3D 06 9ft FO ГЕ - >3 ЪЁ|    
  es:0008 ID FO 32 OB B9 OF 6B 07 -EZdfl+k* es:0010 И 6D ZQ 08 14 6D 92 OB VtQlTId es:601B 01 01 61 60 62 06 FF FF 030 B» ss:0162 0463 ss:6100>-52FB

Fl-Help FZ-Bkpt F3-t1od F4-Here F5-Zoon F6-Hext F7-Trftce F8-Step F9-Bun FlO-fleiu

Рис. 2.5. Состояние программы после выполнения двух первых команд.

Видно, что указатель команд получил значение 5 и показывает на очередную (еще не выполнявшуюся) команду mov AH,09h, относитель­ный адрес которой равен 5. Сегментный регистр DS получил значение 1207И, что должно соответствовать сегментному адресу сегмента данных. Вспомним, что сегмент команд у нас занимает llh байт и требует в памя­ти 2 параграфа. Сегмент команд имеет сегментный адрес 1205h, следова­тельно, сегментный адрес сегмента данных должен быть равен 1207U, что

мы и получили.

Обратим внимание на самую правую колонку в окне процессора, в которой индицируются состояния флагов процессора. Как уже говорилось, состояния флагов заново устанавливаются процессором после выполнения каждой команды, и по ним можно в определенной степени судить о ре­зультате команды. С самого начала у нас был устаноачен только флаг IF (i в окне отладчика), что свидетельствует о включенном механизме аппарат-


ных прерываний; остальные флаги сброшены. После выполнения двух пер­вых команд состояние регистра флагов не изменилось. Произошло это по­тому, что команда пересылки mov не изменяет состояния флагов. Поскольку в нашей программе нет никаких команд, кроме mov и hit, а команда int тоже состояния флагов обычно не изменяет, то наблюдать с помощью на­шего примера функционирование регистра флагов не удастся.

Рассмотрим теперь стек. Сегмент данных имеет у нас размер 14h байт, и под него в памяти надлежит выделить 2 параграфа. Это объясняет содер­жимое сегментного регистра стека SS — 12091г. Под стек отведено 256 байт, поэтому исходное положение SP (под дном стека) соответствует смеще­нию lOOh.

Наконец, стоит еще обратить внимание на нижнюю половину окна команд, заполненную странными командами add [bx+si],al. Таких команд, да еще в таком количестве, в нашей программе нет, их «придумал» отлад­чик, пытаясь деассемблировать промежуток между сегментом команд и сегментом данных, заполненный нулями. Код OOOOh соответствует коман­де add [bx+si],al, которую и изобразил отладчик.

Таким образом, рассмотрев информацию, предоставленную отладчи­ком, мы подтвердили все предыдущие рассуждения о расположении в памяти сегментов программы и об инициализации регистров процессора при загрузке программы в память.

Обратимся теперь к окну дампа. При запуске отладчика в окно дампа выводится содержимое памяти, начиная с адреса DS:OOOOh, т.е. начало префикса программы (см. рис. 2.4 и 2.5). Для того, чтобы вывести на экран что-либо иное, надо воспользоваться командой <Alt>+<F10>, которая для каждого внутреннего окна процессора открывает дополнительное меню. Вид этого меню зависит от того, какое окне было активным в момент ввода команды. На рис. 2.6 показано дополнительное меню окна дампа.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: