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


Обработка прерываний и исключений - часть 2


.386р RM_seg segment para public "CODE" use16 assume cs:RM_seg,ds:PM_seg,ss:stack_seg start: ; очистить экран mov ax,3 int 10h ; подготовить сегментные регистры push PM_seg pop ds ; проверить, не находимся ли мы уже в РМ mov еах,cr0 test al,1 jz no_V86 ; сообщить и выйти mov dx,so v86_msg err_exit: mov ah,9 int 21h mov ah,4Ch int 21h ; может быть, это Windows 95 делает вид, что РЕ = О? no_V86: mov ax,1600h int 2Fh test al,al jz no_windows ; сообщить и выйти mov dx,so win_msg jmp short err_exit ; итак, мы точно находимся в реальном режиме no_windows: ; вычислить базы для всех используемых дескрипторов сегментов xor еах,еах mov ax,RM_seg shl eax,4 mov word ptr GDT_16bitCS+2,ax ; базой 16bitCS будет RM_seg shr eax,16 mov byte ptr GDT_16bitCS+4,al mov ax,PM_seg shl eax,4 mov word ptr GDT_32bitCS+2,ax ; базой всех 32bit* будет mov word ptr GDT_32bitSS+2,ax ; PM_seg mov word ptr GDT_32bitDS+2,ax shr eax,16 mov byte ptr GDT_32bitCS+4,al mov byte ptr GDT_32bitSS+4,al mov byte ptr GDT_32bitDS+4,al ; вычислить линейный адрес GDT xor еах,еах mov ax,PM_seg shl eax,4 push eax add eax,offset GDT mov dword ptr gdtr+2,eax ; загрузить GDT lgdt fword ptr gdtr ; вычислить линейный адрес IDT pop eax add eax,offset IDT mov dword ptr idtr+2,eax ; загрузить IDT lidt fword ptr idtr ; если мы собираемся работать с 32-битной памятью, стоит открыть А20 in al,92h or al,2 out 92h,al ; отключить прерывания, cli ; включая NMI, in al,70h or al,80h out 70h,al ; перейти в РМ mov еах,cr0 or al,1 mov cr0,eax ; загрузить SEL_32bitCS в CS db 66h db 0EAh dd offset PM_entry dw SEL_32bitCS RM_return: ; перейти в RM mov eax,cr0 and al,0FEh mov cr0,eax ; сбросить очередь и загрузить CS реальным числом db 0EAh dw $+4 dw RM_seg ; установить регистры для работы в реальном режиме mov ax,PM_seg mov ds,ax mov es,ax mov ax,stack_seg mov bx,stack_l mov ss,ax mov sp,bx ; загрузить IDTR для реального режима mov ax,PM_seg mov ds,ax lidt fword ptr idtr_real ; разрешить NMI in al,70h and al,07FH out 70h,al ; разрешить прерывания sti ; и выйти mov ah,4Ch int 21h RM_seg ends




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