Tooprogram.ru

Компьютерный справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Прерывания в ассемблере

ПРЕРЫВАНИЯ АССЕМБЛЕРА

Дата добавления: 2014-11-28 ; просмотров: 5319 ; Нарушение авторских прав

Ассемблер имеет возможность, которой завидуют все, кто программирует только на языках высокого уровня. Имеется ввиду возможность оптимальным образом использовать прерывания операционной системы. Ведь это ничто иное, как готовые процедуры. Однако вместо того, чтобы вызывать их по CALL, они вызываются командой INT.

INT 21H вызывает прерывание с шестнадцатеричным номером 21. Имеется ряд таких прерываний, как в базовой системе ввода/вывода, так и в операционной системе, причем некоторые из этих процедур необычайно мощны. На самом деле некоторые из них настолько тесно связаны с системой, что Вы практически не можете сами написать эквивалентную процедуру. Языки высокого уровня позволяют использовать многие из этих прерываний. Они используют их для вывода на экран, приема ввода с клавиатуры и доступа к дискам. Но многие действительно полезные прерывания игнорируются языками высокого уровня, например такие, которые позволяют запустить из одной программы другую.

Перед вызовом прерывания некоторая информация должна быть помещена в регистры процессора. Например, прерывание, вертикально сдвигающее экран, должно знать размеры сдвигаемого окна, число строк на которое его надо сдвинуть и т.д. Эти значения часто называют входными регистрами. Часто Вы будете встречать слова “при входе AX должен содержать . ”, описывающие спецификацию входных регистров. Аналогично, при возврате из прерывания некоторые регистры возвращают значения или информацию о состоянии процессора. Они называются выходными регистрами и мы описываем их словами “при выходе AX содержит . ”. Зачастую одно прерывание содержит много функций. В частности, операционная система включила практически все свои возможности в прерывание 21H. Поэтому при вызове прерывания необходимо указывать номер функции. Все прерывания (как BIOS так и DOS) передают номер функции в AH (иногда в AL содержится номер подфункции).

Ниже перечислены функции DOS, которые могут оказаться полезными для операций ввода — вывода. Код функции устанавливается в регистре AH и затем выдается команда INT 21H.

AH=01: Ввод с клавиатуры с эхоотображением. Данная функция возвращает значение ASCII-кода нажатой клавиши в регистре AL. Нулевое значение в регистре L свидетельствует о том, что на клавиатуре была нажата специальная функциональная клавиша, например, Home, F1 или PageUp.

AH=02: Вывод символа. Для вывода необходимо код символа поместить в регистр DL.

AH=07: Ввод с клавиатуры без эхоотображения. Данная функция аналогична функции 01, но введенный символ не отображается на экране.

AH=09: Вывод на экран строки символов. Адрес строки, заканчивающейся знаком $, должен быть в регистре DX.

AH=0A: Буферизированный ввод с клавиатуры строки символов. Адрес буфера должен быть в регистре DX. Первый байт буфера указывает рабочий размер буфера. Во втором байте буфера находится счетчик символов (фактическое число байтов, введенных с клавиатуры без учета кода Enter). Третий байт — начало входной строки, состоящей из символов ASCII. Конец входной строки — символ возврата каретки (Enter).

Прерывания в ассемблере

Это очень важная глава — здесь описываются средства взаимодействия с OS, а также средства которые позволят сделать ваши программы более читабельными!

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

Достоинством такого метода является возможность разработки программ значительно большего объема небольшими функционально законченными частями. Кроме того, эти подпрограммы можно использовать в других программах, не прибегая к переписыванию частей программного кода. В довершение ко всему, так как размер сегмента не может превышать 64К, то при разработке программ с объемом кода более 64К, просто не обойтись без модульного принципа.

Язык программирования Ассемблера поддерживает применение процедур двух типов – ближнего (near) и дальнего (far).

Читать еще:  Безопасная проверка пароля spa

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

При вызове процедуры в стеке сохраняется адрес возврата в вызывающую программу:

1) при вызове ближней процедуры – слово, содержащее смещение точки вызова относительно текущего кодового сегмента;

2) при вызове дальней процедуры – слово, содержащее адрес сегмента, в котором расположена точка возврата, и слово, содержащее смещение точки возврата в этом сегменте.

В общем случае группу команд, образующих подпрограмму, можно никак не выделять в тексте программы. Для удобства восприятия в языке Ассемблера процедуры принято оформлять специальным образом. Описание процедуры имеет следующий синтаксис:
PROC

ENDP

Следует обратить внимание, что в директиве PROC после имени не ставится двоеточие, хотя имя и считается меткой.

Параметр, указываемый после ключевого слова PROC, определяет тип процедуры: ближний (NEAR) или дальний (FAR). Если параметр отсутствует, то по умолчанию процедура считается ближней.

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

Передавать фактические параметры процедуре можно несколькими способами. Простейший способ – передача параметров через регистры: основная программа записывает параметры в какие-либо регистры, а процедура по мере необходимости извлекает их из этих регистров и использует в своей работе. Такой способ имеет один основной недостаток: передавать параметры через регистры можно если их немного (если много, то просто не хватит регистров). Решить это проблему можно, передавая параметры через стек. В этом случае основная программа записывает параметры в стек и вызывает подпрограмму, подпрограмма работает с параметрами и, возвращая управление, очищает стек.

Для работы с подпрограммами в систему команд процессора включены специальные команды, это вызов подпрограммы CALL и возврат управления RET.

Все команды вызова CALL безусловны. Внутрисегментный вызов NEAR CALL используется для передачи управления процедуре, находящейся в том же сегменте. Он указывает новое значение регистра IP и сохраняет старое значение счетчика команд (IP) в стеке в качестве адреса возврата. Межсегментный вызов FAR CALL используется для передачи управления процедуре, находящейся в другом сегменте или даже программном модуле. Он задает новые значения сегмента CS и смещения IP для дальнейшего выполнения программы и сохраняет в стеке как регистр IP, так и регистр CS.

Все возвраты RET являются косвенными переходами, поскольку извлекают адрес перехода из вершины стека. Внутрисегментный возврат извлекает из стека одно слово и помещает его в регистр IP, а межсегментный возврат извлекает из стека два слова, помещая слова из меньшего адреса в регистр IP, а слово из большего адреса – в регистр CS. Команда RET может иметь операнд, который представляет собой значение, прибавляемое микропроцессором к содержимому указателя стека SP после извлечения адреса возврата (очистка стека).

Другим видом процедур являются прерывания DOS и BIOS. Прерывания это обычные процедуры, написанные разработчиками операционной системы (прерывания DOS) или разработчиками аппаратных средств компьютера (прерывания BIOS). Поэтому к этим процедурам можно обращаться точно так же, как и к другим процедурам. Отличает их лишь форма вызова: вместо команды CALL ProcName используется команда типа INT Number, где Number – номер прерывания, например INT 10h, INT 21h и т.п. Эта команда вызывает прерывание с номером Number (0

В связи с тем, что в состав операционной системы входит много стандартных процедур и для них не хватает допустимых векторов прерываний, они (процедуры) объединяются в группы, вызываемые по прерыванию с одним и тем же номером. Подпрограммы одной группы называют функциями прерывания. Чтобы различать функции прерывания перед его вызовом в регистр AH заносится номер необходимой функции:
MOV AH,
INT

Читать еще:  Сложение в ассемблере

Для выполнения вызванной таким образом процедуры может потребоваться определенная информация (например, для функции вывода символа на экран – код символа). Такая информация передается через регистры микропроцессора.

Ниже приведен пример использования прерывания 21H функции 02 для вывода символа на экран.
.
MOV AH,02h ;AH – номер функции
MOV DL,’a’ ;DL – выводимый символ
INT 21h ;инициализация прерывания
.

Прерывания в ассемблере

В прошлом шаге мы использовали команду INT:

Int — это сокращение слова Interrupt что на русский переводиться как прерывание. Выглядит это команда так:

То есть у каждого прерывания есть номер. И все таки, что это такое? Появилось понятие прерывания вместе с созданием ЭВМ. Тогда стала задача о совместной работе процессора и медленных внешних устройств. Хорошим примеров может служить клавиатура. Когда пользователь нажмет клавишу не известно. Это может случиться в любой момент, вот когда он нажимает клавишу и сообщается процессору что нужно бы обработать это дело и получить клавишу, которая нажата. Отсюда можно сделать вывод, что прерывания рождают внешние устройства. Но мы же с Вами использовали прерывание в программе. Конечно, кроме получения информации от устройства, этим устройствами нужно еще и управлять. Устройства медленные и помимо прочего еще нужно будет дождаться окончание выполнения операции. Это то же реализуется с помощью прерываний только вызываем их мы из программы. Итак, прерывания бывают двух типов:

  • Программные
  • Аппаратные

Я еще как бы хочу акцентировать внимание на проблемах, которые были связанны с появлением прерываний. Устройств всяких много — клавиатура, монитор, дисковод и так далее. Если не пользоваться прерываниями, то постоянно операционная система должна опрашивать устройства, нажата ли клавиша, хотите ли вывести данные на монитор и так далее. Намного проще оговорить некоторый механизм который и будет обращаться внимание операционной системы и процессора на необходимость проведения некоторых действий. Итак, давайте посмотрим на все это в динамике. Ваша программа что то считает. В этот момент нажимается клавиша. Программа должны быть прервана. И это будет сделано, управление будет передано специальному коду (процедура обработки прерывания) а потом Ваша программа будет выполняться дальше. То же самое когда мы вызываем прерывание для вывода символов на монитор (int 21h 04Ch) то сами генерируем прерывание. Зачем ? В этот момент может происходить считывание с дисковода или вывод других символов на экран. А тут мы не с того не с сего со своими символами. Так как прерывания могут наступать одновременно, то есть приоритет их обработки. Есть прерывание, которые выполняться в любом случае даже если идет обработка другого прерывания. Процедура обработки прерывания это программа. Вопрос в том только где она храниться. Базовая обработка прерывания храниться в BIOS и в самих микросхемах оборудования. Но использовать их довольно тяжело. Представьте, для того , что бы записать файл нужно завести двигатель дисковода, установить головку, дать команду перейти в тот сектор прочитать таблицу файлов, проверить что там нет файла и так далее так далее. Все эти задачи облегчает операционная система, которая предоставляет Вам прерывания более высоко уровня. Используя эти прерывания, Вы можете одним заходом создать файл, например. Различают прерывания по номерам:

Вот когда Вы вызываете прерывание (INT) Вы указываете еще и номер (21h) то есть, кто будет выполнять это действие.

Иллюстрированный самоучитель по Assembler

Система прерываний

Самое начало оперативной памяти от адреса 0000h до 03FFh отводится под векторы прерываний – четырехбайтовые области, в которых хранятся адреса обработчиков прерываний (ОбрПр на рис. 1.12). В два старшие байта каждого вектора записывается сегментный адрес обработчика, в два младшие – смещение (относительный адрес) точки входа в обработчик. Векторы, как и соответствующие им прерывания, имеют номера, причем вектор с номером 0 располагается, начиная с адреса 0, вектор 1 – с адреса 4, вектор 2 – с адреса 8 и т.д. Вектор с номером п занимает, таким образом, байты памяти от n*4 до n*4+3. Всего в выделенной под векторы области памяти помещается 256 векторов.

Читать еще:  Язык си длина строки

Получив сигнал на выполнение процедуры прерывания с определенным номером, процессор сохраняет в стеке выполняемой программы текущее содержимое трех регистров процессора: регистра флагов, CS и IP. Два последних числа образуют полный адрес возврата в прерванную программу. Далее процессор загружает CS и IP из соответствующего вектора прерываний, осуществляя, тем самым, переход на обработчик прерывания, связанный с этим вектором.

Обработчик прерываний всегда заканчивается командой iret (interrupt return, возврат из прерывания), выполняющей обратные действия – извлечение из стека сохраненных там слов и помещение их назад в регистры IP и CS, а также в регистр флагов. Это приводит к возврату в основную программу в ту самую точку, где она была прервана.

В действительности запросы на обработку прерываний могут иметь различную природу. Помимо описанных выше аппаратных прерывания от периферийных устройств, называемых часто внешними, имеются еще два типа прерываний: внутренние и программные.

Внутренние прерывания возбуждаются цепями самого процессора при возникновении одной из специально оговоренных ситуаций, например, при выполнении операции деления на ноль или при попытке выполнить несуществующую команду. За каждым из таких прерываний закреплен определенный вектор, номер которого известен процессору. Например, за делением на 0 закреплен вектор 0, а за неправильной командой – вектор 6. Если процессор сталкивается с одной из таких ситуаций, он выполняет описанную выше процедуру прерывания, используя закрепленный за этой ситуацией вектор прерывания.

Наконец, еще одним чрезвычайно важным типом прерываний являются программные прерывания. Они вызываются командой hit с числовым аргументом, который рассматривается процессором, как номер вектора прерывания. Если в программе встречается, например, команда: int 13h то процессор выполняет ту же процедуру прерывания, используя в качестве номера вектора операнд команды int. Программные прерывания применяются в первую очередь для вызова системных обслуживающих программ – функций DOS и BIOS. С командой int 2In вызова DOS мы уже сталкивались в Примере 1.1 и будем встречаться еще многократно. В дальнейшем будут также приведены примеры использования команды int для вызова прикладных обработчиков программных прерываний.

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

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

Как видно из таблицы, векторы прерываний можно условно разбить на следующие группы:

  • векторы внутренних прерываний процессора (0lh, 02h и др.);
  • векторы аппаратных прерываний (08h…0Fh и 70h…77h);
  • программы BIOS обслуживания аппаратуры компьютера (10h, 13h, 16h и др.);
  • программы DOS (21h, 22h, 23h и др.);
  • адреса системных таблиц BIOS (IDh, lEh и др.).

Системные программы, адреса которых хранятся в векторах прерываний, в большинстве своем являются всего лишь диспетчерами, открывающими доступ к большим группам программ, реализующих системные функции. Так, видеодрайвер BIOS (вектор 10h) включает программы смены видеорежима, управления курсором, задания цветовой палитры, загрузки шрифтов и многие другие. Особенно характерен в этом отношении вектор 21h, через который осуществляется вызов практически всех функций DOS: ввода с клавиатуры и вывода на экран, обслуживания файлов, каталогов и дисков, управления памятью и процессами, службы времени и т.д.

Для вызова требуемой функции надо не только выполнить команду int с соответствующим номером, но и указать системе в одном из регистров (для этой цели всегда используется регистр АН) номер вызываемой функции. Иногда для «многофункциональных» функций приходится указывать еще и номер подфункции (в регистре AL).

Ссылка на основную публикацию
Adblock
detector