Assembler - язык неограниченных возможностей


Пример программы


Теперь воспользуемся интерфейсом DPMI для переключения в защищенный режим и вывода строки на экран. Этот пример будет работать только в системах, предоставляющих DPMI для запускаемых в них DOS-программ, например в Windows 95.

; dpmiex.asm ; Выполняет переключение в защищенный режим средствами DPMI .386 ; 32-битный защищенный режим появился в 80386 ; 16-битный сегмент - в нем выполняется подготовка и переход в защищенный режим RM_seg segment byte public use16 assume cs:RM_seg, ds:PM_seg, ss:RM_stack

; точка входа программы RM_entry: ; проверить наличие DPMI mov ax,1687h ; номер 1678h int 2Fh ; прерывание мультиплексора, test ax,ax ; если АХ не ноль, jnz DPMI_error ; произошла ошибка (DPMI отсутствует), test bl,1 ; если не поддерживается 32-битный режим, jz DPMI_error ; нам тоже нечего делать

; подготовить базовые адреса для будущих дескрипторов mov eax,PM_seg mov ds,ax ; DS - сегментный адрес PM_seg shl eax,4 ; EAX - линейный адрес начала сегмента PM_seg mov dword ptr PM_seg_addr,eax or dword ptr GDT_flatCS+2,eax ; дескриптор для CS or dword ptr GDT_flatDS+2,eax ; дескриптор для DS

; сохранить адрес процедуры переключения DPMI mov word ptr DPMI_ModeSwitch,di mov word ptr DPMI_ModeSwitch+2,es

; ES должен указывать на область данных для переключения режимов, ; у нас она будет совпадать с началом будущего 32-битного стека add eax,offset DPMI_data ; добавить к EAX смещение shr eax,4 ; и превратить в сегментный адрес inc ax mov es,ax

; перейти в защищенный режим mov ах, 1 ; АХ = 1 - мы будем 32 приложением ifdef _WASM_ db 67h ; поправка для wasm endif call dword ptr DPMI_ModeSwitch jc DPMI_error ; если переключения не произошло - выйти

; теперь мы находимся в защищенном режиме, но лимиты всех сегментов ; установлены на 64 Кб, а разрядности сегментов - на 16 бит. ; Нам надо подготовить два ; 32-битных селектора с лимитом 4 Гб - один для кода и один для данных push ds pop es ; ES вообще был сегментом PSP с лимитом 100h mov edi,offset GDT ; EDI - адрес таблицы GDT ; цикл по всем дескрипторам в нашей GDT, mov edx,1 ; которых всего два (0, 1) sel_loop: xor ах,ах ; функция DPMI 00 mov cx,1 int 31h ; создать локальный дескриптор mov word ptr selectors[edx*2],ax ; сохранить селектор mov bx,ax ; в таблицу selectors mov ax,000Ch ; функция DPMI OCh int 31h ; установить селектор add di,8 ; EDI - следующий дескриптор dec dx jns sel_loop




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