
- •Задания к лабораторной работе №1
- •Лабораторная работа №2 «Способы адресации и их применение при пересылке данных»
- •Режимы адресации данных
- •Команды пересылки данных
- •Задания к лабораторной работе №2
- •Лабораторная работа №3 «Инструкции для выполнения арифметических операций сложения и вычитания»
- •Команды сложения и вычитания, их воздействие на флаги Команды обращения знака и расширения знака, их воздействие на флаги
- •Задания к лабораторной работе №3
- •Лабораторная работа №4 «Инструкции для выполнения арифметических операций умножения и деления»
- •Команды умножения и деления, их воздействие на флаги
- •Задания к лабораторной работе №4
- •Задания к лабораторной работе №5
- •Список литературы
- •Оглавление
Лабораторная работа №1 «Архитектура IBM PC-совместимого персонального компьютера. Отладчик DEBUG»
Цель работы:
Изучение архитектуры процессора Intel 8086.
Изучение возможностей системного отладчика DEBUG.
Краткие теоретические сведения:
Организация процессора Intel 8086
Программно-доступные регистры процессора
Режимы адресации памяти в процессорах Intel 8086
Команды программы DEBUG для разработки и отладки программ в машинных кодах и в мнемокодах
Программа DEBUG обеспечивает интерактивную отладку программ в формате .ЕХЕ- и .СОМ-файлов. Для запуска отладчика DEBUG из командной строки следует набрать debug и, если необходимо, имя файла, с которым мы будем работать, например debug prog.com. Появление на экране символа-приглашения в виде дефиса свидетельствует о готовности программы DEBUG для приема команд. После набора каждой команды следует нажимать <Enter>.
Основные правила использования программы DEBUG:
DEBUG не различает строчные и заглавные буквы.
DEBUG воспринимает все вводимые числа как шестнадцатеричные, поэтому вводить завершающую букву h не нужно.
Пробелы используются в командах только для разделения параметров.
Регистры CS, DS, ES и SS будут инициализированы адресом 256-байтового (100h) префикса программного сегмента (PSP) и рабочая область памяти начинается с адреса PSP+100h. На рис. 1 приведена screen-копия окна программы DEBUG после выполнения команды просмотра содержимого регистров R (Registers). Из-за различий в конфигурациях компьютеров содержимое регистров на вашей машине может отличаться от приведенного на рисунке. Заметьте, что регистры CS, DS, ES и SS содержат один и тот же адрес сегмента, потому что DEBUG рассматривает весь введенный код как программу .СОМ, хранящую данные, стек и код в одном сегменте. Регистр IP должен показывать 0100, указывая, что выполнение инструкций начинается со смещения 100h с учетом размера PSP.
Рис. 1. Просмотр начального состояния регистров, флагов и следующей выполняемой инструкции с помощью команды R.
DEBUG отображает значения флагов следующим образом:
Таблица .
Используемые отладчиком DEBUG мнемокоды значений флагов
Флаг |
Имя флага |
Установлен |
Сброшен |
OF |
Переполнение (да/нет) |
OV |
NV |
DF |
Направление (уменьш./увелич.) |
DN |
UP |
IF |
Прерывания (вкл./откл.) |
EI |
DI |
SF |
Знак (отриц./полож.) |
NG |
PL |
ZF |
Нуль (да/нет) |
ZR |
NZ |
AF |
Вспомогательный перенос (да/нет) |
АС |
NA |
PF |
Четность (четн./нечетн.) |
РЕ |
PO |
Ссылка на память может задаваться в виде сегмент:смещение, например, DS:120, или в виде только смещения, например, 120. Можно также напрямую обращаться к адресам в памяти, например, 0040:0017, воспринимается как сегмент 40[0]h (то есть 400, с отброшенным младшим разрядом) плюс смещение 17h.
Нажатие клавиши F1 в окне отладчика воспроизводит последнюю команду по одной букве за нажатие, а F3 – целиком.
Набор команд программы DEBUG позволяет выполнять такие полезные операции, как просмотр, ввод в память и пошаговое выполнение программы. Далее в алфавитном порядке перечислены необходимые нам команды DEBUG:
A (Assemble)
Транслирует ассемблерные команды в машинный код. Операция особенно полезна при написании и тестировании маленьких программ на ассемблере и для изучения небольших фрагментов кода. Адрес начала кода по умолчанию – CS:0100.
Формат команды:
A [адрес]
где адрес по умолчанию равен 100h.
DEBUG поддерживает следующие возможности:
определение элементов данных с помощью команд DB и DW;
операнд в квадратных скобках, например, [12E], указывает адрес (смещение) в памяти;
оператор PTR можно использовать для указания байта или слова, например, MOV WORD PTR [120],25.
Можно применять все виды косвенной адресации с использованием регистров, например, [BP+DI] или 25[BX].
Ниже приведен пример создания маленькой ассемблерной программы из пяти инструкций, при этом DEBUG указывает адрес сегмента кода (показанный в виде хххх:) и смещения, начиная со 100h:
-
A 100 <Enter>
xxxx:0100 MOV CX,[10D] <Enter>
; Прочитать в CX значение из DS:10D
xxxx:0104 ADD CX,1A <Enter>
; Прибавить к содержимому CX
; непосредственное значение
xxxx:0107 MOV [10D],CX <Enter>
; Поместить содержимое CX в DS:10D
xxxx:010B JMP 100 <Enter>
; Вернуться к началу программы
xxxx:010D DW 2500 <Enter>
; Определение элемента данных
; по адресу DS:10D
<Enter>
С учетом размера PSP DEBUG устанавливает IP равным 100h, и инструкции программы начинаются с этого адреса. Последнее нажатие <Enter> (два <Enter> подряд) указывает DEBUG, что ввод программы завершен. Теперь можно при необходимости использовать команды U (Unassemble) для просмотра машинного кода или T (Trace) для наблюдения за выполнением программы.
Можно заменять любые введенные команды или элементы данных, при условии, что инструкции или элементы будут иметь ту же длину. Например, чтобы заменить инструкцию ADD, расположенную по адресу 104h, на SUB, введите
A 104 <Enter>
xxxx:0104 SUB CX,1A <Enter> <Enter>
D (Display или Dump)
Выводит на экран содержимое области памяти в шестнадцатеричной и ASCII-формах. Регистр по умолчанию – DS.
Команда D без параметров выводит 8 строк данных, по 16 байт в каждой, начиная с адреса конца последней выведенной области:
Адрес |
Шестнадцатеричное представление |
ASCII-коды |
хххх:хх00 |
хх ………… хх-хх ………… хх |
х..…………х |
хххх:хх10 |
хх ………… хх-хх ………… хх |
х..…………х |
хххх:хх20 |
хх ………… хх-хх ………… хх |
х..…………х |
… |
|
х..…………х |
хххх:хх70 |
хх ………… хх-хх ………… хх |
х..…………х |
Рис. 2. Формат информации, выводимой с помощью команды D.
В левой части каждой строки будет указан адрес первого слева показанного байта в форме сегмент:смещение. Основную часть строки, в центре, занимает шестнадцатеричное представление данных, начинающихся с указанного в начале строки байта. Справа эти же данные выведены в коде ASCII для облегчения интерпретации шестнадцатеричной записи. Помните, что шестнадцатеричная цифра занимает половину байта, поэтому шестнадцатеричное представление байта показано в виде хх.
Адрес слева относится только к первому байту в строке, адреса последующих байтов могут быть легко найдены простым счетом: например, если адрес первого байта – 0159:0240h, то одиннадцатый байт в строке имеет адрес 0159:024Аh (увеличиваем адрес на 10). При просмотре содержимого памяти байты разделяются пробелами, кроме того восьмой и девятый байты разделяет дефис, то есть разделяются группы по 8 байт. Поэтому, например, если нужно найти байт со смещением хх13h, то нужно начать с байта хх10h и найти третий после него байт.
Можно также последовательно просматривать память, повторно вводя D. При этом будут выводиться 128 байт, следующих за последними просмотренными.
Команду D можно также использовать, указывая длину или диапазон. Можно указывать начальный адрес с необязательной длиной (длина по умолчанию 128 (80h) байт):
D [начальный_адрес [L длина]]
Примеры использования:
-
D 200
Вывести 80h байт, начиная с адреса DS:200h.
D CS:150
Вывести 80h байт, начиная с адреса CS:150h.
D DS:20 L5
Вывести 5 байт, начиная с адреса DS:20h.
Можно указать диапазон:
D [начальный_адрес конечный_адрес]
Пример:
-
D 300 32C
Вывести байты, начиная с 300h, и заканчивая 32Сh.
E (Enter)
Позволяет вводить в память данные или инструкции машинного кода. Регистр по умолчанию – DS.
Формат команды:
E адрес [список]
Команда предоставляет две возможности: заменять байты на указанные в списке и последовательно редактировать байты.
Примеры использования:
-
E 105 13 3A 21
Ввести три байта, начиная с адреса DS:105h.
E CS:211 21 2A
Ввести два байта, начиная с адреса CS:211h.
E 12C
Просмотреть содержимое байта DS:12Ch. Операция будет ожидать ввода с клавиатуры одного или нескольких байтов, разделенных пробелами, в шестнадцатеричной форме (рис. ). DEBUG также позволяет нажать <Enter>, чтобы оставить старое значение байта.
Рис. . Ввод нового значения по адресу 12C с помощью команды E.
G (Go)
Выполняет программу на машинном языке вплоть до указанной точки останова. Регистр по умолчанию – CS.
Формат команды:
G [=начальный_адрес] [адрес_останова]
Начальный адрес указывать не обязательно, например, команда G 11A выполнит программу, начиная с адреса, заданного в IP, и заканчивая адресом 11Ah. При отсутствии параметра адрес_останова программа выполняется до конца. Программа будет при необходимости вызывать требуемые обработчики прерываний и останавливаться в ожидании, например, ввода с клавиатуры.
H (Hexadecimal)
Вычисляет сумму и разность двух шестнадцатеричных величин, указанных как H значение_1 значение_2. Например, H 14F 22 выведет в качестве результата 171 (сумму) и 12D (разность).
L (Load)
Загружает фал в память. Файл можно загрузить одним из двух способов: указав имя файла в качестве аргумента при запуске DEBUG, или из запущенного DEBUG командой N (Name).
Формат команды загрузки из уже указанного файла:
L [адрес]
Параметр адрес указывает, по какому адресу загрузить в память файл. Если адрес не указан, файл загружается начиная с адреса CS:100h. Чтобы загрузить файл, не указанный при запуске DEBUG, его необходимо предварительно указать (см. команду N):
-
N имя_файла
Указать файл.
L
Загрузить указанный файл, начиная с адреса CS:100h.
N (Name)
Объявление имени файла, который вы хотите прочитать с диска или записать на диск. Команда используется как N имя_файла, тип программы должен быть .COM, например:
N C:\SAM.COM
Операция сохраняет введенное имя по адресу CS:80h в PSP. Первый байт (по адресу CS:80h) содержит длину, за ним следует пробел и имя файла. Для чтения файла используется команда L (Load), для записи – W (Write).
P (Proceed)
Продолжить или выполнить группу связанных инструкций. По умолчанию используется пара регистров CS:IP.
Формат команды:
P [=адрес] [значение]
Необязательный операнд =адрес указывает адрес начала, а значение – необязательное количество инструкций, которые необходимо выполнить. Если адрес не указывается, используется текущий адрес из пары CS:IP, а если не указано значение, выполняется одна инструкция.
Например, для выполнения обработчика прерываний INT используйте P, и он выполнится вплоть до следующей инструкции.
Q (Quit)
Завершить сеанс работы с DEBUG. Операция не сохраняет файлы, для этого необходимо применять команду W.
R (Register)
Выводит содержимое регистров, флагов, адрес следующей инструкции, ее машинный код и мнемокод.
Формат команды:
R [имя_регистра]
Примеры использования:
-
R
Вывести значения всех регистров.
R DX
Вывести значение DX.
DEBUG позволяет нажать <Enter>, чтобы оставить содержимое регистра неизменным, или ввести от одной до четырех шестнадцатеричных цифр, которые будут записаны в DX.
R IP
Вывести значение IP (можно ввести другое значение с клавиатуры).
R F
Вывести состояние флагов.
T (Trace)
Пошагово выполняет программу. По умолчанию адрес следующей инструкции содержится в паре регистров CS:IP. После выполнения команды T изменяется значение регистра IP.
Формат команды:
T [=адрес] [значение]
Необязательный операнд =адрес указывает DEBUG, откуда начинать пошаговое выполнение, а значение – количество команд, которые необходимо выполнить. Если операнды отсутствуют, DEBUG выполняет одну инструкцию и выводит значения регистров.
Примеры использования:
-
T
Выполнить одну следующую инструкцию.
T 10
Выполнить следующие 10h (16) инструкций.
U (Unassemble)
Дизассемблирует машинный код, то есть преобразует его в соответствующие символьные инструкции ассемблера. По умолчанию используются регистры CS:IP.
Формат команды:
U [начальный_адрес]
или
U [начальный_адрес конечный_адрес]
Примеры использования:
-
U 100
Дизассемблировать 32 байта, начиная с адреса CS:100.
U
Дизассемблировать 32 байта, начиная с адреса,
на котором закончилась последняя команда U,
если она была.
U 100 140
Дизассемблировать команды из адресов с CS:100
до CS:140.
W (Write)
Записывает файл из DEBUG. Необходимо заранее задать имя файла, если он не был загружен. По умолчанию используется регистр CS.
Формат команды:
W [адрес [диск начальный_сектор число_секторов]]
Программы можно записывать только в виде .COM файлов. Чтобы изменить программу типа .EXE, необходимо временно изменить ее расширение. Записывать файлы из DEBUG можно в двух случаях:
В первом случае, после загрузки программы в память машины и ее модификации необходимо сохранить измененный вариант. Для этого следует:
Загрузить программу по ее имени:
DEBUG имя_файла
Просмотреть программу с помощью команды D и внести изменения с помощью команд E.
Командой W записать на диск измененную программу.
Во втором случае, необходимо с помощью DEBUG написать небольшую по объему программу и сохранить ее на диске. Для этого следует:
С помощью команд A (Assemble) и E (Enter) ввести требуемые инструкции.
Ввести имя программы командой:
N имя_файла.com
Расширение файла обязательно должно быть COM.
Поскольку только программист знает, где действительно кончается его программа, указать отладчику длину программы в байтах в паре регистров BX:CX. Например:
хххх:0100 MOV CL,42
хххх:0102 MOV DL,2A
хххх:0104 ADD CL,DL
хххх:0106 JMP 100
хххх:0108
Хотя вводятся символьные инструкции, DEBUG преобразует их в машинный код, и именно машинный код будет записан в файл. Поскольку длина последней инструкции, JMP 100, составляет два байта, размер программы равен 8 байтам.
С помощью команды R BX просмотрите значение BX и введите 0, чтобы очистить его.
Командой R CX просмотрите содержимое регистра CX. DEBUG выведет значение CX и запросит новое. Введите размер программы, 8.
Ведите команду W <Enter>, чтобы записать программу на диск.
В обоих случаях DEBUG выдает сообщение "Writing nnnn bytes." (Запись nnnn байтов). Если nnnn равно 0, то произошла ошибка при вводе длины программы, и необходимо повторить запись снова.
Порядок выполнения лабораторной работы:
Изучите назначение регистров процессора Intel 8086, используя приведенный в п. 1. – п. 1. материал (используя [1, 2, 3]).
Изучите режимы адресации памяти в процессорах Intel 8086, используя приведенный в п. 1. материал (используя [1, 2, 3]).
Изучите способ сегментирования памяти процессора Intel 8086, используя приведенный в п. 1. материал (используя [1, 2, 3]).
Изучите команды отладчика DEBUG, используя приведенный в п. 1.4 материал.
Выполните задания I – VIII согласно варианту. Результаты выполнения заданий оформите в виде отчета в редакторе Microsoft Word. Отчет должен содержать ответы на задания и результаты, полученные после ввода каждой команды DEBUG.
Задания к лабораторной работе №1
Объясните значение терминов:
сегмент;
абсолютный адрес;
граница адреса сегмента;
смещение;
слово памяти;
прерывание.
Укажите, какие регистры можно использовать для выполнения следующих действий:
сложение и вычитание;
подсчет числа циклов;
умножение и деление;
адресация сегментов;
индикация нулевого результата;
адресация выполняемой команды.
Определите, какие флаги затрагиваются произошедшим событием:
арифметическая сумма равна 0;
арифметическая сумма отрицательна;
строковые данные просматриваются слева направо;
арифметическое переполнение;
перенос из старшего разряда при выполнении арифметической операции;
блокировка прерываний.
Вычислите абсолютный адрес, формируемый заданными значениями:
значение SS 2AB4h и значение SP 24h;
значение CS 2BC3h и значение IP 3Ah;
значение DS 13C6h и смещение 1ABBh;
значение DS 045Fh и смещение 32h;
значение DS 4FC5h и смещение 10Bh;
значение DS 038Eh и смещение 32h.
Напишите команду DEBUG для выполнения заданного действия:
просмотреть содержимое всех регистров;
просмотреть содержимое регистра IP и установить его в 0100h;
просмотреть данные, хранящиеся в памяти, начиная со смещения 2BCh в сегменте данных;
просмотреть данные, находящиеся в памяти, начиная с ячейки с адресом 3AFh;
дизассемблировать символьный код по адресам от 100h до 12Bh;
ввести A63Bh в сегмент данных, начиная с адреса 18Ah.
Просмотрите ячейки памяти из области данных BIOS, используя команду D для дампа памяти:
Определите размер доступной для работы памяти, который находится в области данных BIOS по адресу 0040:0013h. Слово, расположенное по данному адресу (в ячейках с адресами 0040:0013h и 0040:0014h), содержит размер памяти в килобайтах и в шестнадцатеричном представлении, причем байты располагаются в обратной последовательности. Определите размер доступной памяти в десятичном представлении.
Просмотрите сведения об авторском праве и определите серийный номер компьютера, записанный в ROM BIOS по адресу FE00:0000h. В зависимости от производителя компьютера будет выведена строка в формате ASCII и серийный номер в виде шестнадцатеричного числа. Строка, с указанием авторских прав может быть длиннее, чем показанный участок памяти, в этом случае для просмотра непоказанной части снова введите D и нажмите <Enter>. Выпишите серийный номер компьютера.
Определите и выпишите дату производства BIOS в формате мм/дд/гг, которая находится по адресу FFFF:0005.
Первый байт для хранения признаков нажатия (флагов) управляющих клавиш клавиатуры находится в области данных BIOS по адресу 0040:0017h (см. табл.). Просмотрите и выпишите содержимое этого байта при включенных и выключенных режимах Num Lock и Caps Lock.
Таблица .
Назначение битов 1-го байта флагов клавиатуры (0040:0017h)
Биты |
Назначение бита |
0 |
Нажата правая клавиша Shift |
1 |
Нажата левая клавиша Shift |
2 |
Нажата любая клавиша Ctrl |
3 |
Нажата любая клавиша Alt |
4 |
Режим Scroll Lock активен |
5 |
Режим Num Lock активен |
6 |
Режим Caps Lock активен |
7 |
Режим Insert активен |
Первые 16 байт области данных BIOS, начиная с адреса 0040:0000h содержат адреса параллельных и последовательных портов. Введите команду просмотра этих байт и определите адреса последовательных (COM) и параллельных (LPT) портов. Адреса портов хранятся в словах памяти в обратной (с переставленными байтами) последовательности.
Слово состояния оборудования расположено в области данных BIOS по адресу 0040:0010h в байтах с адресами 0040:0010h и 0040:0011h (см. табл.). Введите команду просмотра этих байт и интерпретируйте содержащиеся в них шестнадцатеричные значения для получения информации о присутствующих в системе устройствах.
Таблица .
Слово конфигурации оборудования в области данных BIOS
Биты |
Устройства |
15, 14 |
Число обнаруженных LPT-портов: 00 – 0, ..., 11 – 3 |
13 |
Наличие внутреннего модема: 0 – нет, 1 – есть |
12 |
Наличие игрового адаптера (джойстика): 0 – нет, 1 – есть |
11-9 |
Число обнаруженных СОМ-портов: 000 – 0, ..., 111 – 7 |
8 |
Наличие контроллера DMA: 0 – нет, 1 – есть |
7, 6 |
Число обнаруженных дисководов (FDD): 00 – 1,..., 11 – 4 |
5, 4 |
Начальный видеорежим: 00 – не используется, 01 – 4025, цветной, 10 – 8025, цветной, 11 – 8025, монохромный |
3 |
Не используется в IBM PC AT |
2 |
Наличие устройства указания (мыши): 0 – нет, 1 – есть |
1 |
Наличие математического сопроцессора: 0 – нет, 1 – есть |
0 |
Наличие дисковода (FDD): 0 – нет, 1 – есть |
Введите в область сегмента данных, начиная со смещения 200h, последовательность ASCII-кодов символов строки, используя кодовую таблицу ASCII и команду E.
Замечание. Для проверки правильности введенных кодов символов строки используйте команду D.
'Hello, World!'
'Coffee Break'
'Good Morning'
'Good Afternoon'
'Good Evening'
'Welcome!'
Используйте DEBUG для ввода программы и трассировки ее выполнения. Каков результат работы программы? Объясните, как он получился. Сохраните программу из отладчика на диск.
Замечание. Введите программу, состоящую из символьных инструкций, используя команду A 100 для ввода выражений на языке Ассемблера в память. Дизассемблируйте инструкции программы командой U для просмотра созданного DEBUG машинного кода. Поместите результат дизассемблирования в отчет. Выполните пошаговую трассировку программы вплоть до команды JMP. Начните с ввода команды R для просмотра содержимого регистров и первой инструкции программы. Убедитесь, что IP установлен в 100h. Используйте команду T для выполнения отдельной инструкции программы, или команду P для выполнения всей подпрограммы INT. Остановите выполнение, когда дойдете до команды JMP. Для повторного выполнения программы введите еще раз команду T, программа DEBUG выполнит инструкцию JMP и перейдет к началу введенной программы. При необходимости используйте команду E для очистки ячеек памяти и команду R для очистки регистров. Для завершения работы с DEBUG введите Q.
MOV AX,0123
ADD AX,0025
MOV BX,AX
ADD BX,AX
MOV CX,BX
SUB CX,AX
SUB AX,AX
JMP 100
MOV AH,09
MOV DX,109
INT 21
JMP 100
DB 'Coffee Break', '$'
MOV AH,02
MOV DX,23
INT 21
JMP 100
MOV AH,02
MOV DX,2A
INT 21
JMP 100
MOV BX,25
ADD BX,30
SHL BX,1
SUB BX,22
JMP 100
MOV DX,2E
ADD DX,1F
SHL DX,1
SUB DX,BA
JMP 100