Доброго времени суток Недавно начал разбираться с protected mode и столкнулся с проблемой: код, приведенный ниже (небольшая модификация из статьи тов. Great'а о прерываниях в PM) не работает на реальной машине (после загрузки идет перезагрузка, и все по новой), причем под Bochs запускается отлично. Если же убрать 2 строки с очисткой экрана (mov ax, 0x3, int 0x10), все работает.. Подскажите, из-за чего это происходит? Code (Text): org 0x7c00 use16 startsect: jmp rm_entry ;Kernel's descriptor table GDT: dd 0x00000000, 0x00000000 ;Zeroed descriptor db 0xff, 0xff, 0x00, 0x00, 0x00, 10011010b, 11001111b, 0x00 ;Kernel code segment db 0xff, 0xff, 0x00, 0x00, 0x00, 10010010b, 11001111b, 0x00 ;Kernel data segment gdtsize equ $-GDT gdtlimit dw gdtsize-1 gdtbase dd GDT ;Kernel's interrupt descriptor table rm_entry: mov ax, cs mov ss, ax mov dx, ax mov es, ax mov sp, startsect mov bp, sp mov ax,3 int 10h ;Loading the rest of sectors mov ax, 0x0000 mov es, ax mov bx, continue_rmode mov ax, 0x0210 ;read 10h sectors mov cx, 0x0002 ;start from zero track, 2nd sector mov dx, 0x0000 ;0 head, 0 drive int 0x13 jnc continue_rmode endsect: rb 510-(endsect-startsect) db 0x55, 0xAA continue_rmode: in al, 0x92 or al, 2 out 0x92, al cli in al, 0x70 or al, 0x80 out 0x70, al ;NMI denial lgdt fword [gdtlimit] mov eax, cr0 or eax, 1 mov cr0, eax jmp 1000b:pm_entry use32 pm_entry: jmp $ P.S. Возможно проблема со стеком, который затирает таблицу GDT? Я пробовал переместить две строки с очисткой перед инициализацией сегментных регистров (как в статье и было), но результат тот же
Стек не может затирать GDT, он растет вниз. Насчет примера из моей статьи: я, кажется, что-то менял, чтобы код заработал на реальной машине. Уж не помню сейчас что. Трезвым беглым взглядом на твой (мой?) код ошибок явных не нашел.. Могу лишь посоветовать настроить IDT и ловить код исключения (перезагрузка идет из-за того, что по определенной причине, которую и надо установить, происходит исключение, таблицы прерываний нет -> генерируется double fault -> его обработчика тоже нет - возникает тройной отказ, процессор уходит в shutdown, дальше чипсет видит, что дело плохо и перезагружает систему).
быть может, ? у тебя ds неверно инициализирован походу дела -> lgdt fword ptr ds:[gdtlimit] загружает совсем не ту таблицу, которая у тебя -> переход в защищенный режим ничем хорошим не закончится. опечатка, я так понимаю, но весьма суровая)
Да, она и была проблемой. Спасибо за подробное объяснение P.S. код из статьи работает на реальной машине