Привет, обьясните почему не получается нормально выйти из РМ, файл прикрепил, виснет и не пойму почему?
А вот почти такой же код, комп ребутиться после выхода из РМ в дос. Кто то скажет почему? .386p stk segment STACK dw 100h dup (0) size_stk = $-stk stk ends data segment use16 ;0писание GDT ;слово 3 (старшее): ;биты 15–8: биты 31–24 базы ;бит 7: бит гранулярности (0—лимит в байтах, 1—лимит в 4-килобайтных единицах) (G) ;бит 6: бит разрядности (0/1—16-битный/32-битный сегмент) (D) ;бит 5: 0 (X) ;бит 4: зарезервировано для операционной системы (U) ;биты 3–0: биты 19–16 лимита ;слово 2: ;бит 15: бит присутствия сегмента (P) ;биты 14–13: уровень привилегий дескриптора (DPL) ;бит 12: тип дескриптора (0—системный, 1—обычный) (S) ;биты 11–9: тип сегмента (TYPE) ;бит 8: бит обращения (А) ;биты 7–0: биты 23–16 базы ;слово 1: биты 15–0 базы ;слово 0 (младшее): биты 15–0 лимита ;пустой дескриптор zero_descr db 8 dup (0) ; дескрипторы для инициализации ; дескриптор кода №8 code_descr dw 0 ; предел 15-0 dw 0 ; базовый адрес 15-0 db 0 ; базовый адрес 23-16 ;pDPLsTypeA db 10011010b ; права доступа AR db 0 ; предел 19-16 и GDXU db 0 ; базовый адрес 31-24 ;дескриптор данных №16 data_descr dw 0 ; предел 15-0 dw 0 ; базовый адрес 15-0 db 0 ; базовый адрес 23-16 ;pDPLsTypeA db 10010010b ; права доступа AR db 0 ; предел 19-16 и GDXU db 0 ; базовый адрес 31-24 ;дескриптор стека №24 stk_descr dw 0 ; предел 15-0 dw 0 ; базовый адрес 15-0 db 0 ; базовый адрес 23-16 ;pDPLsTypeA db 10010010b ; права доступа AR db 0 ; предел 19-16 и GDXU db 0 ; базовый адрес 31-24 ;дескриптор текстового видео буфера №32 video_descr dw 0 ; предел 15-0 dw 0 ; базовый адрес 15-0 db 0 ; базовый адрес 23-16 ;pDPLsTypeA db 10010010b ; права доступа AR db 0 ; предел 19-16 и GDXU db 0 ; базовый адрес 31-24 size_gdt = $-zero_descr ; pазмер в GDT байтах ; операнды команды lgdt lgdt_size dw size_gdt-1 ; размер GDT lgdt_adr dd ? ; и её физический адрес data ends code segment use16 assume cs:code, ss:stk start: mov ax, data mov ds, ax ; данные ; вычислим физ. адр. сегмента кода xor eax, eax mov ax, code shl eax, 4 ; теперь в eax физический адрес сегмента кода mov word ptr ds:code_descr+2, ax ; передадим биты 15-0 базового адреса в дескриптор shr eax, 16 mov byte ptr ds:code_descr+4, al ; биты 23-16 базового адреса ; загрузим значение лимита сегмента и GDXU mov eax, 0FFFFh mov word ptr ds:code_descr, ax ; передадим биты 15-0 предела сегмента shr eax, 16 or al, 00000000b ; установим биты GDXU=0 mov byte ptr ds:code_descr+6, al ; передадим биты 23-16 предела и GDXU ; вычислим физ. адр. сегмента данных xor eax, eax mov ax, data shl eax, 4 ; теперь в eax физический адрес сегмента mov word ptr ds:data_descr+2, ax ; передадим биты 15-0 базового адреса в дескриптор shr eax, 16 mov byte ptr ds:data_descr+4, al ; биты 23-16 базового адреса ; загрузим значение лимита сегмента и GDXU mov eax, 0FFFFh mov word ptr ds:data_descr, ax ; передадим биты 15-0 предела сегмента shr eax, 16 or al, 00000000b ; биты GDXU=0 mov byte ptr ds:data_descr+6, al ; передадим биты 23-16 предела и GDXU ; вычислим физ. адр. сегмента стека xor eax, eax mov ax, stk shl eax, 4 ; теперь в eax физический адрес сегмента mov word ptr ds:stk_descr+2, ax ; передадим биты 15-0 базового адреса в дескриптор shr eax, 16 mov byte ptr ds:stk_descr+4, al ; биты 23-16 базового адреса ; загрузим значение лимита сегмента и GDXU mov eax, size_stk-1 ; в eax размер (минус единица) mov word ptr ds:stk_descr, ax ; передадим биты 15-0 предела сегмента shr eax, 16 or al, 00000000b ; биты GDXU=0 mov byte ptr ds:stk_descr+6, al ; передадим биты 23-16 предела и GDXU ; настроим дескриптор для текстового видеобуфера mov eax, 0B8000h ; 0B8000h физ. адр. текстового видеобуфера mov word ptr ds:video_descr+2, ax ; передадим биты 15-0 базового адреса в дескриптор shr eax, 16 mov byte ptr ds:video_descr+4, al ; биты 23-16 базового адреса ; загрузим значение лимита сегмента и GDXU mov eax, 160*25-1 ; 25 строк по 160 символов, в eax размер (минус единица) mov word ptr ds:video_descr, ax ; передадим биты 15-0 предела сегмента shr eax, 16 or al, 00000000b ; биты GDXU=0 mov byte ptr ds:video_descr+6, al ; передадим биты 23-16 предела и GDXU ; вычисляется физ. адрес GDT xor eax, eax mov ax, data ; GDT находится в сегменте data shl eax, 4 ; физический адрес сегмента add ax, offset zero_descr ; физический адрес GDT mov dword ptr ds:lgdt_adr , eax ; сохр. физ. адреса GDT для команды lgdt lgdt fword ptr ds:lgdt_size ; загрузка GDTR ; отключить прерывания cli ; аппаратные in al,70h ; NMI or al,80h out 70h,al ; включаем защищённый режим mov eax, cr0 or eax, 1 mov cr0, eax ; PM=ON db 0EAh ; оп код команды far jmp dw offset PM_ON ; ip dw 8 ; cs=code PM_ON: ; загружаем селекторы дескрипторов в регистры mov ax, 16 ; селектор данных mov ds, ax ; ds=data mov ax, 24 ; селектор стека mov ss, ax ; ss=stk mov ax, 32 ; селектор видео страницы mov es, ax ; es=video mov word ptr es:[320], 0202h ; вывести смайлик ; выключаем защищённый режим ; PM = OFF mov eax,cr0 and al,0FEh mov cr0,eax ; db 0EAh dw $+4 dw code mov ax, cs mov ds, ax mov es, ax mov ax, stk mov bx, size_stk mov ss,ax mov sp,bx ; разрешить прерывания in al,70h ; NMI and al,07FH out 70h,al sti ; аппаратные mov ah, 9 lea dx, mes int 21h mov ah, 4Ch int 21h mes db "hi$" code ends end start
Привет всем! Значит так, ошибка найдена. Проблема была в том что, после выключения сейф мода, лимит некоторых сегментных регистров был не 0FFFFh. Всё работает отлично когда лимит 0FFFFh. Удачи всем! %)