Здравствуйте! Сначала осуществляю переход в защищенный режим, потом настраиваю IDT. При совершении любых неправомерных действий в защищенном режиме вызывается 15е прерывание. Проверял заведомо неправильным кодом: Код (Text): _asm { mov ax, 0 mov ss, ax } Насколько я понимаю должно вызываться #SS (12е) Проверено на VMWare и на реальном компе. Помогите пожалуйста разобраться.
Возможно, причина "непонятного" вызова int 15 в том, что ты не перенес IRQ вектора - тогда вектора IRQ0-15 (выставленные по дефолту биосовским загрузчиком) перекрывается с векторами исключений Intel. при загрузке выставляется база IRQ0 = 8, тогда IRQ1 = 9, IRQ2 = A, ..., IRQ7 = F. Вот у тебя как раз и генерится IRQ7 - скорее всего там сетевая карта какая-нибудь. Или еще какие девайсы. Нужно перенести IRQ на вектора > 0x20, создать для них корректные обработчики, делать EOI и все такое. Например так: Код (Text): IRQ0_Handler: ; timer interrupt pusha ... inc [gTickCount] ... popa jmp CommonEoiHelper IRQ1_Handler: ; keyboard interrupt ; .. save registers, read-in the byte from PS/2 controller, process scan-code, etc .. .... jmp CommonEoiHelper ; Common routine that has to be called at the end of IRQ dispatch. CommonEoiHelper: push ax mov al, 20h out 020h, al out 0a0h, al pop ax iretd Это в простейшем случае когда мы работаем в режиме эмуляции 8259A. Современные ОС должны использовать "продвинутые" Local APIC для назначения прерываниям конкретных номеров векторов, I/O APIC для маршрутизации прерываний к конкретному процессору. В любом случае, оставлять биосовский дефолт не выйдет. Кстати говоря, ничего не будет сгенерировано. Селектор будет проверен только когда будет выполняться команда, обращающаяся через этот сегментный регистр (в данном случае ss). То есть mov ax, 0 / mov ss, ax / push ax сгенерирует исключение не на "mov ss,ax", а на "push ax" - при фактическом обращении. А уж какое исключение (SS,GP,PF) - зависит от того, какой селектор ты записал, есть ли соответствующая ему запись в GDT и какие там права и какое значение ESP и тп..
Прерывания перенес следующим кодом (у вас на форуме брал): Код (Text): _asm { mov bx,07870h mov dx,0000h mov al,11h out 0a0h,al out 20h,al mov al,bh out 0a1h,al mov al,bl out 21h,al mov al,02 out 0a1h,al mov al,04 out 21h,al mov al,01 out 0a1h,al out 21h,al mov al,dh out 0a1h,al mov al,dl out 21h,al } Я думал, что загружая нулевой селектор всегда исключение буде... Не важно, еще таски неправильно переключал и т. д. - все-равно 15е
2great. mov ax,0 mov ss,ax вызовет эксепшн независимо от обращения к памяти. загрузка селектора в ss обрабатывается по другому нежели остальные сегментные рег-ры. хотя есть метод записать в ss (впрочем как и в cs) нулевой дескриптор, sysexit а помощь
2sorron Ты где-то в хэндлерах упоролся. По идее инт15 невалидный эксепшн, соответственно проц его сам вызвать не может. Код инициализации PIC корректный, значит где-то лагаешь в хэндлере. Код в студию
medstrax1 Верно, регистр Ss просто загрузкой туда нуля нельзя обнулять(посредством iret тоже): При обработке Sysexit проверок нет.
Вы какой именно хендлер имеете ввиду? Если 15го, то он-то работает нормально: Код (Text): __declspec(naked) void gp() { // prolog _asm { push ebp mov ebp, esp sub esp, __LOCAL_SIZE } { sys_con->print("exception"); for(;;); } // epilog _asm { mov esp, ebp pop ebp iretd } } На остальных стоит заглушка, которая выводит другое сообщение и тоже входит в бесконечный цикл. Но выводит именно exception, потому как intr_table->set_int(15, (void*)gp);
Раз при mov ax,0 mov ss,ax у тебя происходит вызов инт15, то очевидно либо косяк в хэндлере инт12, либо в IDT
Дурацкая ошибка вышла. Раньше обращался только к полям структур, которые были в стеке, в блоках _asm. И почему-то пришло в голову, что так же можно обращаться и полям объектов. Ошибку спровоцировало: Код (Text): _asm { mov ebx, inter_table Как оказалось, этот код заносит в ebx смещение поля inter_table относительно начала объекта. Правильно будет так: Код (Text): _asm { mov ebx, this lea [ebx+inter_table]