    В листинге 17.10 демонстрируется вызов прерывания BIOS, в данном случае 
для изменения формы курсора. Скомпилируйте и запустите программу для изменения 
вашего курсора из обычного тонкого в большой, который легче рассмотреть на 
заполненном информацией экране. (Для восстановления первоначальной формы 
курсора следует перезагрузиться.) 

    Листинг 17.10.  BI6C.CPP (установка большого курсора) 

    1:	main() 
    2:	{ 
    3:	asm	{ 
    4:	mov	ch,	0	//	Задать	верхнюю		строку	курсора 
    5:	mov	cl,	7	//	Задать	число	строк курсора 
    6:	mov	ah,	1	//	Задать	видеопроцедуру			BIOS	»1 
    7:  	int	0x10		//	Вызвать	BIOS	для	изменения		формы	курсора 
    8.	} 
    9:	return 0; 
    10:	} 

    Единственный оператор asm в строках 3-8 выполняет все действия в этой 
программе: вызывает видеопроцедуру BIOS для изменения формы текстового 
курсора. Сначала в строках 4, 5 инициализируются регистры ch и ci значениями, 
соответствующими числу и начальной позиции горизонтальных линий, образующих 
видимый курсор. (Если вы присмотритесь к текстовому курсору, то сможете 
рассмотреть эти линии на некоторых типах дисплеев.) Поэкспериментируйте с 
этими двумя значениями для создания множества форм курсора. 
    В строке 6 в регистре ah запоминается идентификационный номер 
видеопроцедуры BIOS, отвечающей за вменение формы курсора. После всех этих 
подготовительных действий в строке 7 вызывается обработчик прерывания BIOS с 
помощью выполнения int 0x10 аналогично тому, как в предыдущей программе 
вызывался лкпетчер функций DOS. Сразу после запуска программы должен появиться 
большой курсор. К сожалению, курсор может принять свой прежний вид, поскольку 
другие программы могут изменять, но не восстанавливать форму курсора. 

    Написание процедур обработки прерываний 

    Вдобавок к вызовам функций DOS и BIOS вы можете писать свои собственные 
процедуры обработки прерываний. Для упрощения процесса в Borland C++ 
используется ключевое слово interrupt, преобразующее функцию типа void в 
обработчик прерывания. В программах на С и C++ можно написать функцию — 
обработав прерывания следующим образом: 

    void interrupt AnyName(unsigned bp,  unsigned di,  unsigned si, unsioned ds,  
       unsigned es. unsigned dx, ^signed ex,  unsigned bx, unsigned ax, unsigned 
      ip,  unsigned cs, unsigned flags) 
   {
      // ....   операторы С или C++ 
   }

    Бeззнаковые параметры обеспечивают доступ к регистровым переменным, сохраненным в 
стеке. В случае аппаратных прерываний эти значения останутся нетронутыми, 
поскольку они отображают состояние прерванной  программы. В действительности для большей 
части обработчиков аппаратных прёрываний скорее всего, не придется объявлять ни одного 
параметра. Тем не менее, в программных прерываниях информация обычно передается в 
регистрах, и эту информацию можно получить с помощью вышеперечисленных параметров.
Вы можете включить только те параметры, которые вам необходимы, но вы должны их включать
именно в указанном порядке. Так, если вашей программе необходим регистр ах, в объявлении 
следует указать все параметры с bр по ах. 
    Компилятор добавпяет немного своего собственного кода к interrapt-функциям. В 
скомпилированном виде такие функции начинаются с преамбулы: 

push ах          ; Сохранить регистры 
push bx
push cx
push dx
push es
push ds
push si
push di
push bp
mov bp, DGROUP    ;   Задать bр равным адресу сегмента данных 
mov ds, bp                 ;   Инициализировать DS сегментом данных программы 
mov bp, sp                 ;   Адресовать локальные данные через Ьр 


    Глава 17. Оптимизация с помощью ассемблера	453 
