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


Переключение задач - часть 2


.386p RM_seg segment para public "CODE" use16 assume cs:RM_seg,ds:PM_seg,ss:stack_seg start: ; подготовить сегментные регистры push PM_seg pop ds ; проверить, не находимся ли мы уже в РМ mov eax,cr0 test al,1 jz no_V86 ; сообщить и выйти mov dx,offset v86_msg err_exit: push cs pop ds mov ah,9 int 21h mov ah,4Ch int 21h

; убедиться, что мы не под Windows no_V86: mov ax,1600h int 2Fh test al,al jz no_windows ; сообщить и выйти mov dx,offset win_msg jmp short err_exit

; сообщения об ошибках при старте v86_msg db "Процессор в режиме V86 - нельзя переключиться в РМ$" win_msg db "Программа запущена под Windows - нельзя перейти в кольцо 0$"

; итак, мы точно находимся в реальном режиме no_windows: ; очистить экран mov ax,3 int 10h ; вычислить базы для всех дескрипторов сегментов данных xor еах,еах mov ax,RM_seg shl eax,4 mov word ptr GDT_16bitCS+2,ax shr eax,16 mov byte ptr GDT_16bitCS+4,al mov ax,PM_seg shl eax,4 mov word ptr GDT_32bitCS+2,ax mov word ptr GDT_32bitSS+2,ax shr eax,16 mov byte ptr GDT_32bitCS+4,al mov byte ptr GDT_32bitSS+4,al ; вычислить линейный адрес GDT xor eax,eax mov ax,PM_seg shl eax,4 push eax add eax,offset GDT mov dword ptr gdtr+2,eax ; загрузить GDT lgdt fword ptr gdtr ; вычислить линейные адреса сегментов TSS наших двух задач pop eax push eax add eax,offset TSS_0 mov word ptr GDT_TSS0+2,ax shr eax,16 mov byte ptr GDT_TSS0+4,al pop eax add eax,offset TSS_1 mov word ptr GDT_TSS1+2,ax shr eax,16 mov byte ptr GDT_TSS1+4,al ; открыть А20 mov al,2 out 92h,al ; запретить прерывания cli ; запретить NMI in al,70h or al,80h out 70h,al ; переключиться в РМ mov eax,cr0 or al,1 mov cr0,eax ; загрузить 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 ; разрешить NMI in al,70h and al,07FH out 70h,al ; разрешить прерывания sti ; завершить программу mov ah,4Ch int 21h RM_seg ends




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