Previous: 10.9.1 Зарегистрированные номера портов
UP:
10.9 Набор AT-команд модемов |
10.9.2 Прерывания в MS-DOS
Семенов Ю.А. (ГНЦ ИТЭФ)
Было время, когда система управления прерываниями отождествлялась с ОС. Сегодня функции ОС существенно усложнились. Сюда вошла система управления ресурсами: распределение оперативной и вируальной памятью, приоритетное распределение полосы пропускания, управление авторизацией и аутентификацией, а также обеспечение безопасности системы, включая криптографию.
Объем только ядра ОС может превышать 40 млн. строк кода, а существует еще оболочка, приложения и пользовательские программные модули. В разработке принимают участие сотни, а иной раз многие тысячи людей.
Такое усложнение привело к тому, что не существует эксперта. который бы хорощо знал и понимал, как работают все компоненты ОС.
Если принять во внимание. что на каждые 2000 строк приходится как минимум одна ошибка (после работы дебаггеров, код-чекеров и тестовых кодов), картина становится достаточно драматической.
Но вернемся к основной теме раздела - прерываниям. Прерывания бывают аппаратными и программными. Первый тип служит для управления в основном внешними устройствами: накопителями, системами отображения, каналами связи, манипуляторами или клавиатурой.
Прерывание происходит при возникновении определенных событий: изменение напряжения или температуры за пределы допустимого, нажатие клавиши, переполнение буфера, приход почтового сообщения или пакета заданного типа и т.д..
Для сигнаализации о событии на магистрали процессора имеется специальная шина. К этой шине имеют доступ все внешние устройства компьютера.
Программные прерывания происходят при определенных событиях, возникающих в процессе работы программы. Здесь нужно учитывать, что ОС может быть многопользовательской. Некоторые программные прерывания дублируют аппаратные. Через программные прерывания реализуются все обменные процессы: ввод с клавиатуры, вывод символов и строк на экран, работа с виртуальной памятью, мышкой, графическим процессором и т.д.. Эти прерывания используются в хандлерах всех внешних устройств. После завершения прерывания управление передается назад в прерванную программу. Адрес продолжения работы кода хранится в стеке возвратов.
Ниже приведен сильно сокращенный список возможных программных прерываний в ассемблере MASM (Microsoft).
00H Деление на 0
02H Немаскируемое
03H Breakpoint
04H Overflow
05H Bound exceeded (Printscreen)
06H Invalid operand
08H Двойная ошибка
09H Keyboard
10H Ошибка сопроцессора, BIOS видео драйвер
13H BIOS disk driver
16H BIOS keyboard driver
17H BIOS printer driver
19H Bootstrap
23H MS-DOS Ctrl-C
27H Terminate and stay resident
74H Mouse
Наборы таких прерываний для разных процессоров отличаются. Данный набор соответствует 8086 и 80286 и не является полным. Аппаратные прерывания бывают внутренними и внешними.
Код Адрес вектора Значение
00H 00H-03H Деление на 0
02H 08H-0BH Немаскируемое
03H 0CH-0FH Breakpoint
04H 10H-13H Overflow
05H 14H-17H Bound exceeded
06H 18H-1BH Invalid operand
07H 1CH-1FH Processor extension not available
08H 20H-23H Double fault
0BH 2CH-2FH Segment not present
0EH 38H-3BH Page fault
10H 40H-43H Numeric coprocessor error
Приведенный ниже список является неполным, но многие прерывания, присутствующие в нем, практически не используются.
INT | AX | DX | Function |
10H | 0 | - | Set AL=video mode (fix marker position) |
1 | - | Set cursor type | |
2 | Set cursor position. BH=page, DH=row, DL=column | ||
3 | Get cursor position. BH=page, DH=row, DL=column | ||
4 | Get light pen position | ||
5 | Set display page AL= active page | ||
6 | Scroll window up. AL - число строк для прокрутки, (0 = очистка), BH= атрибут цвета, СH - номер верхней строки, CL - номер левого столбца, DH - номер нижней строки, DL - номер правого столбца | ||
7 | Initialize or scroll window down | ||
8H | Read character and attribute at cursor BH=page, AH=цвет. AL=символ | ||
9H | Write character and attribute at cursor; AL=simb, BH=page, BL=color, CX=сколько раз | ||
0AH | Write character to the display at cursor position. AL -character; BX - page: BL - color; CX - count of chars to write | ||
0BH | Set palette, background or border; BH=0; BL color; | ||
0CH | Write graphics pixel; AL= pixel value; BH - page; CX= column; DX= row | ||
0DH | Read graphics pixel | ||
0EH | Write character in teletype mode | ||
0FH | Get video mode; AL= display mode; BH=page | ||
10H | 00 | Set border color Subfunction=01; Subfunction AL=00H; set palette register | |
02 | Set palette and border. Subfunction AL=02H; ES:DX= segment of color list | ||
03 | Toggle blink/intensity bit. Subfunction Al=03 | ||
07 | Get palette register. Subfunction Al=07H | ||
08 | Get border color. Subfunction Al=08H | ||
09H | Get palette and border. Subfunction Al=09H | ||
10H | Set color register. Subfunction Al=10H | ||
12H | Set block of color registers. Subfunction Al=12H | ||
Set color page state. Subfunction Al=13H | |||
Get color register. Subfunction Al=15H | |||
17H | Get block of color registers. Subfunction Al=17H | ||
1AH | Get colorpage state. Subfunction Al=1AH | ||
1BH | Set gray-scale values. Subfunction Al=1BH | ||
11H | 00 and 10H | Load user font; subfunctions. AL=11H | |
01 and 11H | Load ROM 8-by-14 font. Subfunctions Al=01 and 11H | ||
02 and 12H | Load ROM 8-by-8 font. Subfunction Al=02 and 12H | ||
03 | Set block specifier. Subfunction Al=03H | ||
04 and 14H | Load ROM 8-by-16 font. Subfunction Al=04 and 14H | ||
20H | Set Int 1FH font pointer. Subfunction Al=20H; ES:BP segment of font table | ||
21H | Set Int 43H for user’s font. Subfunction Al=21H; | ||
22H | Set Int 43H for ROM 8-by-14 font. Subfunction Al=22H | ||
23H | Set Int 43H for ROM 8-by-8 font. Subfunction Al=23H | ||
24H | Set Int 43H for ROM 8-by-16 font. Subfunction Al=24H | ||
30H | Get font information. Subfunction Al=30H | ||
12H | Get configuration information; Subfunction=10H; | ||
Select alternate printscreen. Subfunction=20H | |||
Set scan lines. Subfunction=30H | |||
Enable/disable default palette loading. Subfunction=31H | |||
1AH | Get or set display combination code; AL=00H =get display combination code; AL-01H = set code | ||
1BH | Get functionality/state information | ||
1CH | Save or restore video state | ||
11H | Get equipment configuration | ||
12H | Get conventional memory size | ||
13H | 00 | Reset disk system | |
01 | Get disk system status; DL=drive; | ||
02H | Read sector. AL- number of sectors. CH= cylinder; CL=sector; DH= head; DL=drive | ||
03H | Write sector | ||
04H | Verify sector | ||
05H | Format track. AL=interleave; CH=cylinder; DH=head; DL=drive | ||
06H | Format bad track; AL=interleave; CH=cylinder; DH=head; DL=drive | ||
07H | Format drive | ||
08H | Get drive parameters | ||
09H | Initialize fixed disk characteristics | ||
0AH | Read sector long | ||
0BH | Write sector long | ||
0CH | Seek | ||
0DH | Reset fixed disk system | ||
0EH | Read sector buffer | ||
0FH | Write sector buffer | ||
10H | Get drive status | ||
11H | Recalibrate drive | ||
12H | Controller RAM diagnostic | ||
13H | Controller drive diagnostic | ||
14H | Controller internal diagnostic | ||
15H | Get disk type | ||
16H | Get disk change status | ||
17H | Set disk type | ||
18H | Set media type for format | ||
19H | Park heads | ||
1AH | Format ESDI drive | ||
14H | 00 | Initialize communication port | |
01 | Write character to communications port (AL=character) | ||
02 | Read character from communications port | ||
03 | Get communications port status | ||
04 | Extended initialize communication port | ||
05 | Extended communication port control | ||
15H | 00 | Turn on cassette motor | |
01 | Turn off cassette motor | ||
02 | Read cassette | ||
03 | Write cassette | ||
21H | 00 | Read POST error log. Subfunction 00H | |
21H | 01 | Write POST error log. Subfunction 01H | |
80H | Device open | ||
81H | Device close | ||
82H | Process termination | ||
83H | Evrnt wait | ||
84H | Read joystick | ||
86H | Delay | ||
87H | More extended memory block | ||
88H | Get extended memory size | ||
89H | Enter protected mode | ||
90H | Device wait | ||
C0H | Get system environment | ||
C1H | Get address of extended BIOS data area | ||
C2H | 00 | Enable/disable pointing device | |
C2H | 01 | Reset pointing device | |
C2H | 02 | Set sample rate | |
C2H | 03 | Set resolution | |
C2H | 04 | Get pointing devie type | |
C2H | 05 | Initialize pointing device interface | |
C2H | 06 | Set scaling or get status pointing device interface | |
C2H | 07 | Set pointing pointing device handler address | |
C3H | Set watchdog time-out | ||
C4H | Programming option select | ||
16H | 0 | Read char from keyboard (AL - ASCII character; AH = keyboard scan code;) | |
1 | Get keyboard status. Determines whether a char is ready for input, returning a flag and char itself, if one is waiting | ||
2 | Get keyboard flags (AL) - bit0 - right shift key is down; bit2 - ctrl key is down; bit3 - alt key is down; bit4 - Scroll lock on; bit5 - Num lock on; bit6 Caps lock on; bit7 - Insert on | ||
3 | Set repeat rate | ||
4 | Set keyclick (on or off signal at key click) | ||
5 | Push char (CL) + scan code (CH) | ||
10H | Read character from enhenced keyboard | ||
11H | Get enhenced keyboard status | ||
12H | Get enhenced keyboard flags | ||
17H | 0 | Write char to printer (AL= char; DX= printer nimber) | |
01 | Init printer port | ||
02 | Get printer status | ||
18H | ROM basic | ||
19H | Reboot system | ||
1AH | 00 | Get tick count | |
01 | Set tick count | ||
02 | Get time | ||
03 | Set time | ||
04H | Get date | ||
05H | Set date | ||
06 | Set alarm | ||
07H | Reset alarm | ||
0AH | Get day count | ||
0BH | Set day count | ||
80H | Set sound source | ||
21H | 01 | Char input with echo - чтение символа из стандартного ввода (AL) | |
02 | Char output (DL) | ||
03 | Auxilary input | ||
04 | Auxilary output | ||
05 | Printer output (DL) | ||
06 | DL = звпрошенная функция; DL= 00H-FEH, if output request; DL=0FFH, if input request | ||
07 | Get character without echo | ||
08H | Character input without echo; AL - 8-bit input data | ||
09H | DS:DX | Send string of chars to display (string-addr is in DX, set with LEA or MOV offset array). Это прерывание не сохраняет содержимое DS. | |
0AH | DS:DX | Buffered keyboard input (read line from keyboard and put into user buffer) | |
0BH | Проверка состояния буфера клавиатуры. AL=0 - буфер пуст | ||
0CH | DS:DX | Flush input buffer and then input | |
0DH | Disk reset | ||
0EH | Select disk. DL - points the disk; return AL= number of logical drives in system | ||
0FH | DS:DX | Open file (FCB) | |
10H | DS:DX | Close file (FCB) | |
11H | DS:DX | Find first file (FCB) | |
12H | DS:DX | Find next file (FCB) | |
13H | DS:DX | Delete file | |
14H | DS:DX | Sequential read | |
15H | DS:DX | Sequential write | |
16H | DS:DX | Create file | |
17H | DS:DX | Rename file | |
19H | Get current disk (AL drive code) | ||
1AH | DS:DX | Fix address of disc (DTA) | |
1BH | Get default drive data/ AL= sectors per cluster | ||
1CH | Get drive data DL = drive code | ||
21H | DS:DX | Read selected record (random) | |
22H | DS:DX | Random write | |
23H | DS:DX | Get file size | |
24H | DS:DX | Set relative record number | |
25H | DS:DX | Set interrupt vector | |
27H | DS:DX | Random block read | |
28H | DS:DX | Random block write; CX=actual number of record written | |
29H | Parse filename | ||
2AH | Get date | ||
2BH | Set date | ||
2CH | Get time | ||
2DH | Set time | ||
2FH | Get DTA address | ||
30H | Get MS-DOS version number | ||
35H | Get interrupt vector | ||
36H | Get drive allocation information | ||
39H | DS:DX | Create directory | |
3AH | DS:DX | Delete directory | |
3BH | DS:DX | Set current directory | |
3CH | Create file | ||
3DH | Open file | ||
3EH | Close file (BX - handle) | ||
3FH | Read file or device | ||
40H | Write file or device (use BX=handle from previous open); CX= byte number to transfer; mov BX, stdout; mov CX, mag_len | ||
41H | DS:DX | Delete file | |
42H | Set file pointer | ||
43H | Get or set file attribute | ||
44H | 00 | IOCTL (i/o control). Get device information | |
44H | 01 | IOCTL. Set device information | |
44H | 02 | IOCTL. read control data from character device driver | |
44H | 03 | IOCTL. write control data from character device driver | |
44H | 04 | IOCTL. read control data from block device driver | |
44H | 05 | IOCTL. write control data from block device driver | |
44H | 06 | IOCTL. check input status | |
44H | 07 | IOCTL. check output status | |
44H | 08 | IOCTL. check if block device is removable | |
44H | 09H | IOCTL. check if block device is remote | |
44H | 0AH | IOCTL. check if handle is remote | |
44H | 0BH | IOCTL. check sharing retry count | |
44H | 0CH | IOCTL. generic I/O control for character devices | |
44H | 0DH | IOCTL.generic I/O control for block devices | |
44H | 0EH | IOCTL.get logical device map | |
44H | 0FH | IOCTL.set logical device map | |
45H | Dublicate handle | ||
46H | Redirect handle | ||
47H | Get current directory | ||
48 | Allocate memory block | ||
49H | Release memory block | ||
4AH | Resize memory block | ||
4BH | Execute program (EXEC) | ||
4CH | Terminate process with return code - Возврат в ОС | ||
4DH | Get return code | ||
4EH | DS:DX | Find first file | |
4FH | Find next file | ||
54H | Get verify flag | ||
56H | Rename file | ||
57H | Get or set file date and time | ||
58H | Get or set allocation strategy | ||
59H | Get extended error information | ||
5AH | Create temporary file | ||
5BH | Create new file | ||
5CH | Lock or unlock file region | ||
5EH | 00 | Get machine name (subfunction 00H) | |
5EH | 02 | Set printer setup string | |
5EH | 03 | Get printer setup string | |
5FH | 02 | Get redirection list entry | |
5FH | 03 | Redirect device | |
5FH | 04 | Cancel device redirection | |
62H | Get PSP address | ||
63H | Get DBCS lead byte table | ||
65H | Get extended country information | ||
66H | Get or set code page | ||
67H | Set handle count | ||
68H | Commit file | ||
6CH | Extended open file | ||
22H | Terminate handler address | ||
23H | 00 | Ctrl-C handler address | |
24H | Critical-error handler address | ||
25H | Absolute disk read | ||
26H | Absolute disk write | ||
27H | Terminate and stay resident | ||
2FH | 01H | Print spooler | |
2FH | 02 | Assign | |
2FH | 10H | Share | |
2FH | B7H | Append | |
33H | 00 | Reset mouse and get status | |
01 | Show mouse pointer | ||
02 | Hide mouse pointer | ||
03H | Get mouse position and button status | ||
04H | Set mouse pointer position | ||
05H | Get button press information | ||
06H | Get button release information | ||
07H | Set horizontal limits for pointer | ||
08H | Set vertical limits for pointer | ||
09H | Set graphics pointer shape | ||
0AH | Set text pointer type | ||
0BH | Read mouse motion counters | ||
0CH | Set user defined mouse event handler | ||
0DH | Turn on light pen emulation | ||
0EH | Turn off light pen emulation | ||
0FH | Set mickeys to pixels ratio | ||
10H | Set mouse pointer execution area | ||
13H | Set double speed threshold | ||
14H | Swap user-defined mouse event handlers | ||
15H | Get mouse save state buffer size | ||
16H | Save mouse driver state | ||
17H | Restore mouse driver state | ||
18H | Set alternate mouse event handler | ||
19H | Get address of altlternate mouse event handler | ||
1AH | Set mouse sensitivity | ||
1BH | Get mouse sensitivity | ||
1CH | Set mouse interrupt rate | ||
1DH | Select pointer page | ||
1EH | Get pointer page | ||
1FH | Disable mouse driver | ||
20H | Enable mouse driver | ||
21H | Reset mouse driver | ||
22H | Set language for mouse driver messages | ||
23H | Get language number | ||
24H | Get mouse information | ||
67H | 40H | Get status | |
41H | Get page frame address | ||
42H | Get number of pages | ||
43H | Allocate handle and pages | ||
44H | Map expanded memory page | ||
45H | Release handle and expended memory | ||
46H | Get version | ||
47H | Save page map | ||
48H | Restore page map | ||
4BH | Get handle count | ||
4CH | Get handle pages | ||
4DH | Get pages for all handles | ||
4EH | 00 | Save page map. Subfunction 00. | |
01 | Restore page map. Subfunction 01H | ||
02 | Subfunction 02H, Save and restore page map | ||
03 | Subfunction 03H. Get size of page map information | ||
4FH | 00 | Subfunction 00. Save partial page map | |
01 | Subfunction 01. Restore partial page map | ||
02 | Subfunction 02H. Get size of partial page map information | ||
50H | Map multiple pages by address | ||
51H | Reallocate pages for handle | ||
52H | 00 | Get handle attribute. Subfunction 00 | |
01 | Set handle attribute. Subfunction 01 | ||
02 | Get attribute capability. Subfunction 02 | ||
53H | 00 | Get handle name. Subfunction 00 | |
01H | Set handle name. Subfunction 01 | ||
54H | 00 | Get all handle names. Subfunction 00 | |
01 | Search for handle name. Subfunction 01 | ||
02 | Get total handles. Subfunction 02 | ||
55H | 00,01 | Map pages and jumps. Subfunction 00 and 01 | |
56H | 00,01 | Map pages and call. Subfunction 00 and 01 | |
02 | Get stack space for map page and call. Subfunction 02 | ||
57H | 00 | Move memory region. Subfunction 00 | |
01 | Exchange memory regions. Subfunction 01 | ||
58H | 00 | Get addresses of mappable pages. Subfunction 00 | |
01H | Get number of mappable pages. Subfunction 01 | ||
59H | 00 | Get hardware configuration. Subfunction 00 | |
01H | Get number of raw pages. Subfunction 01 | ||
5AH | 00 | Allocate handle and standard pages. Subfunction 00 | |
01H | Allocate handle and raw pages. Subfunction 01 | ||
5BH | 00 | Get alternate map register. Subfunction 00 | |
01 | Set alternate map register. Subfunction 01 | ||
02H | Get size of alternate map register save area. Subfunction 02 | ||
03H | Allocate alternate map register set. Subfunction 03 | ||
04H | Deallocate alternate map register set. Subfunction 04 | ||
05H | Allocate DMA register set. Subfunction 05 | ||
06H | Enable DMA on alternate map register set. Subfunction 06 | ||
07H | Disable DMA on alternale map register set. Subfunction 07 | ||
08H | Deallocate DMA register set. Subfunction 08 | ||
5CH | Prepare Expended Memory Manager for warm boot | ||
5DH | 00 | Enable EMM operating system functions. Subfunction 00 | |
01H | Disable EMM operating system functions. Subfunction 01 | ||
02H | Release access key. Subfunction 02 |
Раньше неукоснительно соблюдался принцип обратной совместимости - программа должна работать с любой новой версией ОС или библиотек. К сожалению это правило сегодня не работает.
При написании программ прерывания нужно следить за тем, чтобы системные переменные при ее работе не модифицировались. Это правило касается и всех регистров общего назначения. К сожалению, даже это самоочевидное правило не всегда выполняется.
Например, прерывание INT 21H AH=09H, используемое для отображения строки символов на экране, в некоторых реализациях не сохраняет содержимое сегментного регистра DS, и перед очередным обращением его значние надо восстановить.
Пример программы с использованием программных прерываний и восстановлением содержимого регистра DS представлен ниже.
cr EQU 0DH lf EQU 9AH inpu DB "Tipe a key you want: ",'$'; $code DB "The code of the key: ",'$'; $stry DB cr,lf, 3 DUP (?),"$"; ; code string ;................................. mov AL,cr mov AH,2 int 21 LEA DX,inpu MOV AH,9H INT 21H ;.................................. mov ax, SEG $code ; if DS does not already point to data segment mov ds, ax ; LEA DX,inpu MOV AH,9H INT 21H ; type a key, you want mov ax, SEG $code ; if DS does not already point to data segment mov ds, ax ; MOV DX,offset $code MOV AH,9H INT 21H LEA DX,$stry ; Typing out the result MOV AH,9H INT 21H
Более 20 лет назад я написал на ассемблере интерпретатор для языка FORTH. Оттранслированная версия работает сегодня только под ОС Windows-XP. Когда я писал программу, этой ОС еще не существовало. Оттранслировать программу под более поздние версии ОС не получилось (изменился набор команд процессора, сам ассемблер и т.д.). Это указывает на важность сохранения старых версий транслятора для ассемблера.
Здесь уместно задать вопрос, а зачем вообще нужен ассемблер? Раньше на ассемблере писались драйверы внешних устройств (Смотри Сетевые драйверы и Winsock (для UNIX, Windows-95, -NT, -98 и -XP)). Теперь даже такие программы пишутся на Си. Другой причиной применения ассемблеров было быстродействие. Теперь и это не аргумент, не случайно на первое место по популярности вышел Python. Главным параметром оптимизации стало время с момента постановки задачи до ее окончательного практического решения. Ассемблер остается незаменим, когда нужно, например, програмно изменить в реальном масштабе времени конфигурацию или какие-то параметры ОС. Но такие задачи встречаются не часто.
Одной из таких программ была система блокировки несанкционированного запуска программ. Смотри "Алгоритм предотвращения несанкционированного копирования текстов, программ и мультимедиа-данных".
Previous: 10.9.1 Зарегистрированные номера портов
UP:
10.9 Набор AT-команд модемов |