Защищенный режим процессоров Intel


Использование функций DPMI


Приведённая ниже программа демонстрирует использование функций интерфейса DPMI, описанного в предыдущей главе. Эта программа может работать только под управлением WINDOWS версий 3.0, 3.1 и только в расширенном режиме на процессорах i80386 или i80486. Такое ограничение связано с тем, что только в расширенном режиме существует понятие виртуальной DOS-машины, и только в этом режиме DOS-программа может воспользоваться сервисом DPMI.

Вы можете также попробовать запустить эту программу под управлением DOS-экстендера, входящего в состав интегрированной системы разработки программ Borland C++ 3.1. Запустите программу DPMIRES.EXE, входящую в состав Borland C++ 3.1, и затем - программу, приведённую ниже. (DOS-экстендеры, входящие в состав Borland C++ 2.0 или 3.0, не вполне совместимы с DPMI, поэтому наш пример с этими системами работать не будет).

Программа начинает свою работу с проверки доступности сервера DPMI, при этом не делается никаких предположений относительно средств, обеспечивающих присутствие DPMI. Это означает, что вы можете проверить работоспособность этой программы в различных средах, предоставляющих интерфейс DPMI, например на виртуальной DOS-машине операционной системы OS/2 версии 2.0.

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

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

Листинг 21. Использование интерфейса DPMI Файл dpmi.c ----------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <dos.h> #include <conio.h> #include <stdarg.h> typedef struct { unsigned long edi, esi, ebp, reserved, ebx, edx, ecx, eax; unsigned flags, es, ds, fs, gs, ip, cs, sp, ss; } RM_INT_CALL; #define MONO_MODE 0x07 #define BW_80_MODE 0x02 #define COLOR_80_MODE 0x03 // Макро для вычисления линейного адреса исходя из // логического адреса реального режима #define ABSADDR(seg, ofs) \ ((((unsigned long) seg) << 4) + ((ofs) & 0xFFFF)) typedef struct { // байт доступа unsigned accessed : 1; unsigned read_write : 1; unsigned conf_exp : 1; unsigned code : 1; unsigned xsystem : 1; unsigned dpl : 2; unsigned present : 1; } ACCESS; typedef struct { // дескриптор unsigned limit; unsigned addr_lo; unsigned char addr_hi; ACCESS access; unsigned reserved; } DESCRIPTOR; // Структура для записи информации о памяти typedef struct { unsigned long avail_block; unsigned long max_page; unsigned long max_locked; unsigned long linadr_space; unsigned long total_unlocked; unsigned long free_pages; unsigned long tot_phys_pages; unsigned long free_linspace; unsigned long size_fp; char reserved[12]; } PMI; void dos_exit(unsigned); void dpmi_init(void); void set_pmode(void); void cdecl pm_printf(const char *, ...); void pm_puts(char *); void pm_putch(int); int rm_int(unsigned, unsigned , RM_INT_CALL far *); int mi_show(void); unsigned get_sel(void); int set_descriptor(unsigned pm_sel, DESCRIPTOR far *desc); void vi_print(unsigned int x, unsigned int y, char *s, char attr); void vi_hello_msg(void); void main() { clrscr(); printf("DOS Protected Mode Interface Demo, © Frolov A.V., 1992\n\r" "--------------------------------------------------------\n\r\n\r"); // Определяем текущий видеорежим и // сегментный адрес видеобуфера video_init(); // Инициализируем защищённый режим dpmi_init(); printf("\n\r\n\r\n\rДля входа в защищённый режим нажмите любую клавишу..."); getch(); // Входим в защищённый режим set_pmode(); // Стираем экран и выводим сообщение, находясь в // защищённом режиме.


- Начало -  - Назад -  - Вперед -