Сист. прогр. Ч2 (1085771), страница 5
Текст из файла (страница 5)
Деление вычитанием
Если частное слишком велико, то деление можно выполнить с помощью циклического вычитания. Метод заключается в том, что делитель вычитается из делимого и в этом же цикле частное увеличивается на 1. Вычитание продолжается до тех пор, пока делимое остается больше делителя. В следующем примере делитель находится в регистре АХ, а делимое - в ВХ, частное вырабатывается в СХ:
SUB СХ,СХ ;0чистка частного
С20: СМР АХ, ВХ ;Если делимое < делителя,
JB СЗО ; то выйти
SUB АХ,ВХ ;Вычит.делит.из делимого ,
INC СХ ;Инкремент частного
JMP C20 ;Повторить цикл
СЗО: RET ;Частное в СХ,остаток в АХ
В конце подпрограммы регистр, СХ будет содержать частное, а АХ - остаток. Пример умышленно примитивен, цель его продемонстрировать данный способ деления. Если частное получается в регистровой паре DX:AX, то необходимо сделать два дополнения:
В метке С20 сравнивать АХ и ВХ только при нулевом DX.
После команды SUB вставить команду SBB DX,00.
Примечание: очень большое частное и малый делитель могут вызвать тысячи циклов.
ПРЕОБРАЗОВАНИЕ ЗНАКА
Команда NEG обеспечивает преобразование знака двоичных чисел из положительного в отрицательное и наоборот. Практически команда NEG устанавливает противоположные значения битов и прибавляет 1. Примеры:
NEG АХ
NEG BL
NEG BINAHT ;{байт или слово в памяти)
Преобразование знака для 32-битового (или большего) числа включает большее количество шагов. Предположим, что регистровая пара DX:AX содержит 32-битовое двоичное, число. Так как команда NEG не может обрабатывать два регистра одновременно, то ее использование приведет к неправильному результату. Ниже показано применение команды NOT:
NOT DX ;Инвертирование битое
NOT AX ;Инвертирование битов
ADD АХ, 1 ;Прибавление 1 к АХ
ADC DX, 0 ;прибавление переноса к DX
Остается одна незначительная проблема: над числами, представленными в двоичном формате, удобно выполнять арифметические операции, если сами числа определены в программе. Данные, вводимые в программу с дискового файла, могут также иметь двоичный формат. Но данные, вводимые с клавиатуры, представлены в ASCII-формате. Хотя ASCII-коды удобны для отображения и печати, они требуют специальных преобразований в двоичный формат для арифметических вычислений.
ПРОЦЕССОРЫ INTEL 8087 И 80287 ДЛЯ МАТЕМАТИЧЕСКИХ ОПЕРАЦИЙ
Системная плата компьютера содержит пустое гнездо, зарезервированное для числового процессора Intel 8087 (или 80287). Сопроцессор 8087 действует совместно с 8088, а сопроцессор 80287 действует совместно с 80286. Каждый сопроцессор имеет собственный набор команд и средства для выполнения операций с плавающей запятой, таких, как экспоненциальные, логарифмические и тригонометрические функции. Сопроцессор содержит восемь 80-битовых регистров с плавающей запятой, которые могут представить числовые значения до 10400. Математические вычисления в сопроцессоре выполняются примерно в 100 раз быстрее, чем в основном процессоре.
Основной процессор выполняет специальные операции и передает числовые данные в сопроцессор, который осуществляет необходимые вычисления и возвращает результат. Для ассемблирования команд сопроцессора с помощью транслятора MASM необходимо добавлять параметр /Е или /R:
MASM /R.
ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ
Будьте особенно внимательны при использовании однобайтовых регистров. Знаковые значения здесь могут быть от -128 до - 127.
Для многослойного сложения используйте команду ADC для учета переносов от предыдущих сложений. Если операция выполняется в цикле, то с помощью команды CLC, установите флаг переноса в 0.
11. МАКРОЯЗЫК И МАКРОПРОЦЕССОР
Программист, пишущий на ассемблере, часто встречается с необходимостью повторять некоторые последовательности команд в программе много раз. Такая последовательность, например, может состоять из команд, служащих для сохранения или смены содержимого групп регистров, установления связей, выполнения ряда арифметических операций. В подобных случаях можно воспользоваться аппаратом макрокоманд.
Макрокоманды (иногда называемые макро) являются однострочными сокращениями для группы команд. Используя макросы, программист по существу определяет одну «команду» для представления последовательности команд. Вместо каждого вхождения этой однострочной макрокоманды макропроцессор подставит в программу всю последовательность команд.
Определяя соответствующие макрокоманды, программист, использующий ассемблер, может удобным образом вводить свои собственные средства более высокого уровня, без дополнительных забот о структуре своей программы. Он может достигнуть краткости и простоты программирования, присущих языкам высокого, уровня, не теряя при этом основных преимуществ программирования на ассемблере. Крупные макрооперации упрощают отладку и модификацию программ и облегчают, стандартизацию. Многие разработчики вычислительных машин используют макрокоманды для автоматизации составления «подходящих» операционных систем в процессе, называемом генерацией системы.
Макрокоманды обычно рассматриваются как расширение языка ассемблера, а макропроцессор — как расширение основного алгоритма ассемблера. Однако, как особая форма языков программирования, макроязыки значительно отличаются от языков ассемблирования и компилируемых алгебраических языков. Некоторая аналогия может быть найдена в языках высокого уровня и системах редактирования текстов.
Для каждой закодированной команды ассемблер генерирует одну команду на машинном языке. Но для каждого закодированного оператора компиляторного языка ПАСКА/lb или СИ генерируется одна или более (чаще много) команд машинного языка. В этом отношении можно считать, что компиляторный язык состоит из макрооператоров.
Ассемблер MASM также имеет макросредства, но макросы здесь определяются программистом. Для этого задается имя макроса, директива MACRO, различные ассемблерные команды, которые должен генерировать данный макрос, и для завершения макропределения - директива MEND, Затем в любом месте программы, где необходимо выполнение определенных в макрокоманде команд, достаточно закодировать имя макроса. В результате ассемблер сгенерирует необходимые команды.
Использование макрокоманд позволяет:
* упростить и сократить исходный текст программы;
* сделать программу более понятной;
* уменьшить число возможных ошибок кодирования.
Примерами макрокоманд могут быть операции ввода-вывода, связанные с инициализацией регистров и выполнением прерываний, преобразования ASCII- и двоичного форматов данных, арифметические операции над длинными полями, обработка строковых данных, деление с помощью вычитания.
12. Прерывания BIOS и DOS
Цель: описать функции, доступные через прерывания BIOS и DOS,
ВВЕДЕНИЕ
Прерывание представляет собой операцию, которая
приостанавливает выполнение программ для специальных системных
действий. Необходимость прерываний обусловлена двумя
основными причинами: преднамеренным запросом таких действий,
как операции ввода-вывода на различные устройства, и
непредвиденными программными ошибками (например,
переполнением при делении).
Система BIOS (Basic Input/Output System) находится в ROM и управляет всеми прерываниями а системе. В предыдущих главах уже использовались некоторые прерывания для вывода на экран, дисковых операций ввода-вывода и печати. В этой главе описаны различные BIOS- и DOS-прерывания, резидентные программы и команды IN и OUT.
ОБСЛУЖИВАНИЕ ПРЕРЫВАНИЙ
В компьютерах IBM PC ROM находится по адресу FFFF0H. При включении компьютера процессор устанавливает состояние сброса, осуществляет контроль четности, устанавливает в регистре CS значение FFFFH, а в регистре IP - нуль. Первая выполняемая команда поэтому находится по адресу FFFF:0 или FFFF0, что является точкой входа в BIOS. Система BI0S проверяет различные порты компьютера для определения и инициализации подключенных устройств. Затем BIOS создает в начале памяти (по адресу 0) таблицу прерываний, которая содержит адреса обработчиков прерываний, и выполняет две операции: (NT 11Н (запрос списка присоединенного оборудования) и INT 12H (запрос размера физической памяти).
Следующим шагом BIOS определяет, имеется ли на диске или дискете операционная система DOS. Если обнаружена системная дискета, то BIOS выполняет прерывание INT 19H для доступа к первому сектору диска, содержащему блок начальной загрузки. Этот блок представляет собой программу, которая считывает системные файлы IBMBIO.COM, IBMDOS.COM и COMMAND.COM c дискa в память. После этого память имеет следующее распределение:
Таблица векторов прерываний
Данные BIOS
IBMВIO.СОМ и IBMDOS.COM
Резидентная часть COMMAND.COM
Доступная память для прикладных программ
Транзитная честь COMMAND .COM
Конец RAM (ОЗУ)
rom basIk:
ROM BIOS
Внешние устройства передают сигнал внимания через контакт INTR в процессор. Процессор реагирует на этот запрос, если флаг прерывания IF установлен в 1 (прерывание разрешено), и (в большинстве случаев) игнорирует запрос, если флаг IF установлен в 0 (прерывание запрещено).
Операнд в команде прерывания, например INT 12H, содержит тип прерывания, который идентифицирует запрос. Для каждого типа система содержит адрес в таблице векторов прерываний, начинающейся по адресу 0000. Так как в таблице имеется 256 четырехбайтовых элементов, то она занимает первые 1024 байт памяти от 0 до 3FF. Каждый элемент таблицы указывает на подпрограмму обработки указанного типа прерывания и содержит адрес кодового сегмента и смещение, которые при прерывании устанавливаются в регистры CS и IP соответственно. Список элементов таблицы векторов прерываний приведен на рис.12.1.
Адрес Функция прерывания
0-3 0 Деление на нуль
4-7 1 Пошаговый режим (трассировка DEBUG)
8-8 2 Немаскированное прерывание (NMI)
C-F 3 Точка останова (использ. в DEBUG)
10-13 4 Переполнение регистра
14-17 5 Печать экрана
18-1F 6,7 Зарезервировано
20-23 8 Сигнал от таймера
24-27 9 Сигнал от клавиатуры
28-37 A,B,C,D Используются в компьютерах AT
38-ЗВ Е Сигнал от дискетного дисковода
3C-3F F Используется для принтера
40-43 10 Управление дисплеем (см. гл. 8,9,10)
44-47 11 Запрос оборудования (см. гл. 9)
48-4В 12 Запрос размера памяти (см. гл. 2)
4C-4F 13 Дисковые операции в/в (см. гл. 18)
50-53 14 Управление коммуникац. адаптером
54-57 15 Кассетные операции и спец. функции AT
58-58 16 Ввод с клавиатуры {см. гл. 9)
5C-5F 17 Вывод на принтер (см.га.19}
60-63 18 Обращение к BASIC, встроенному в ROM
64-67 19 Перезапуск системы
68-66 1А Запрос и установка времени и даты
6C-6F 1В Прерывание от клавиатуры
70-73 1C Прерывание от таймера
74-77 ID Адрес таблицы параметров дисплея
78-7В IE Адрес таблицы параметров дисковода
7C-7F IF Адрес таблицы графических символов
80-83 20 Норм, завершение программы (DOS)
84-87 21 Обращение к функциям DOS
S8-8B 22 Адрес обраб. завершения задачи (DOS)
8C-8F 23 Адрес реакции по Ctrl/Break (DOS)
90-93 24 Адрес реакции на фат. ошибку (DOS)
94-97 25 Абсолютное чтение с диска (DOS)
98-98 26 Абсолютная запись на диск (DOS)
97-9F 27 Создание резидентной программы (DOS)
AO-FF 28-3F Другие функции DOS
100-1FF 40-7F Зарезервировано
200-217 80-85 Зарезервировано для/BASIC
218-ЗСЗ 86-FO Используются BASIC-интерпретатором
3C4-3FF F1-FF Зарезервировано
Примечание: Прерывания 00-1F относятся к BIOS, прерывания 20-FF относятся к DOS и BASIC.
Рис.12.1. Таблица адресов прерываний
Прерывание заносит в стек содержимое флагового регистра, регистра CS и, регистра IP. Например, для прерывания 12Н (которое возвращает в регистре АХ размер памяти) адрес элемента таблицы равен 0048 (12Н х 4 = 48H). Операция выделяет четырехбайтовый элемент по адресу 0048 и заносит два байта в регистр IP и два байта в регистр SS. Адрес, который получается в регистровой nape CS:IP, представляет собой адрес начала подпрограммы в области BIOS, которая получает управление. Возврат из этой подпрограммы осуществляется командой IRET (Interrupt RETurn), которая восстанавливает флаги и регистры CS и IP из стека и передает управление на команду, следующую за выполненной командой прерывания.
ПРЕРЫВАНИЯ BIOS
INT 05H. Печать экрана. Выполняет вывод содержимого экрана на печатающее устройство. Прерывание INT 05H выполняет данную операцию из программы, а нажатие клавиш Ctrl/PrtSc - с клавиатуры. Данная операция маскирует прерывания и сохраняет позицию курсора.
INT 10Н. Управление дисплеем. Обеспечивает экранные и клавиатурные операции.