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


Пример программы - часть 2


; загрузить селектор сегмента кода в CS при помощи команды RETF push dword ptr Sel_flatCS ; селектор для CS ifdef _WASM_ db 066h endif push offset PM_entry ; EIP db 066h ; префикс размера операнда retf ; выполнить переход в 32-битный сегмент

; сюда передается управление, если произошла ошибка при инициализации DPMI ; (обычно, если DPMI просто нет) DPMI_error: push cs pop ds mov dx,offset nodpmi_msg mov ah,9h ; вывод строки на экран int 21h mov ah,4Ch ; конец ЕХЕ-программы int 21h nodpmi_msg db "Ошибка DPMI$" RM_seg ends

; сегмент PM_seg содержит код, данные и стек для защищенного режима PM_seg segment byte public use32 assume cs:PM_seg,ds:PM_seg,ss:PM_seg ; таблица дескрипторов GDT label byte ; дескриптор для CS GDT_flatCS db 0FFh,0FFh,0h,0h,0h,0FAh,0CFh,0h ; дескриптор для DS GDT_flatDS db 0FFh,0FFh,0h,0h,0h,0F2h,0CFh,0h

; точка входа в 32-битный режим - загружен только CS PM_entry: mov ax,word ptr Sel_flatDS ; селектор для данных mov ds,ax ; в DS mov es,ax ; в ES mov ss,ax ; и в SS mov esp,offset PM_stack_bottom ; и установить стек ; отсюда начинается текст собственно программы, ; программа работает в модели памяти flat с ненулевой базой, ; база CS, DS, ES и SS совпадает и равна линейному адресу начала PM_seg ; все лимиты - 4 Гб mov ах,0300h ; функция DPMI 0300h mov bx,0021h ; прерывание DOS 21h xor есх,есх ; стек не копировать mov edi,offset v86_regs ; ES:EDI - адрес v86_regs int 31h ; вызвать прерывание

mov ah,4Ch ; Это единственный способ int 21h ; правильно завершить DPMI-программу

hello_msg db "Hello world из 32-битного защищенного режима!$"

v86_regs: ; значения регистров для функции DPMI ОЗООп dd 0,0,0,0,0 ; EDI, ESI, EBP, 0, ЕВХ v_86_edx dd offset hello_msg ; EDX dd 0 ; ЕСХ v86_eax dd 0900h ; EAX (AH = 09h, вывод строки на экран) dw 0,0 ; FLAGS, ES v86_ds dw PM_seg ; DS dw 0,0,0,0,0,0 ; FS, GS, 0, 0, SP, SS

; различные временные переменные, нужные для переключения режимов DPMI_ModeSwitch dd ? ; точка входа DPMI PM_seg_addr dd ? ; линейный адрес сегмента PM_seg




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