OSDev http://osdev.su/ |
|
как правильно делать прерывания http://osdev.su/viewtopic.php?f=6&t=737 |
Страница 1 из 2 |
Автор: | scuter [ 24 апр 2013, 15:55 ] |
Заголовок сообщения: | как правильно делать прерывания |
пробую сделать прерывания, и как то ничего не выходит с сегментными регистрами, Код: pushad ; сохраняю все регистры mov cx , es shl ecx, 16 mov cx , ss mov bx , ds shl ebx, 16 mov bx , fs mov dx , gs mov ax, 40h mov ES, ax mov SS, ax mov DS, ax mov FS, ax mov GS, ax mov esp, 500h mov ebp, 500h pushad popad ; востанавливаю все регистры mov gs , dx mov fs , bx shr ebx, 16 mov ds , bx mov ss , cx shr ecx, 16 mov es , cx popad возникает какой то глюк с сегментами, програмный код встаёт и всё обламывается. |
Автор: | Yoda [ 25 апр 2013, 10:38 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
Это код реального режима? Зачем так извращаться с сегментными регистрами? Только ради использования команды POPAD? Нет никакого смысла. Лучше использовать непосредственно push/pop с сегментными регистрами, каждая такая команда использует ровно один байт. Будет занимать много меньше места и быстрей выполняться. Этот код где находится? В обработчике прерывания? Не забыл, что в конце обработчика необходимо использовать возврат инструкцией iret, а не ret? |
Автор: | iz56 [ 25 апр 2013, 14:09 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
Вроде нельзя читать из сег. рег. в любой дроугой кроме AX. |
Автор: | Yoda [ 25 апр 2013, 14:52 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
Можно в любой регистр кроме другого сегментного. |
Автор: | SII [ 25 апр 2013, 15:51 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
А если б было нельзя, не прошла бы трансляция. |
Автор: | scuter [ 26 апр 2013, 01:30 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
Yoda писал(а): Это код реального режима? Зачем так извращаться с сегментными регистрами? Только ради использования команды POPAD? Нет никакого смысла. Лучше использовать непосредственно push/pop с сегментными регистрами, каждая такая команда использует ровно один байт. Будет занимать много меньше места и быстрей выполняться. просто команды push/pop то же используют сегментные регистры если бы у меня использовался только один кодовый сегмент и один сегмент данных проблем бы таких не было. кстати Код: push ES push SS push DS push FS push GS это я тоже использовал Yoda писал(а): Этот код где находится? В обработчике прерывания? Не забыл, что в конце обработчика необходимо использовать возврат инструкцией iret, а не ret? да в обработчике прерываний(Int32, Trap32) и в конце стоит iretd. в IDT стоит Int32 Sel:Off=0008:0010171a и Trap32 Sel:Off=0008:0010171a код ещё раз повторю Код: Interrupt_code:
pushad mov cx , es shl ecx, 16 mov cx , ss mov bx , ds shl ebx, 16 mov bx , fs mov dx , gs mov ax, 40h mov ES, ax mov SS, ax mov DS, ax mov FS, ax mov GS, ax mov esp, 500h mov ebp, 500h pushad ; код прерывания popad mov gs , dx mov fs , bx shr ebx, 16 mov ds , bx mov ss , cx shr ecx, 16 mov es , cx popad iret |
Автор: | Yoda [ 26 апр 2013, 12:59 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
scuter писал(а): просто команды push/pop то же используют сегментные регистры если бы у меня использовался только один кодовый сегмент и один сегмент данных проблем бы таких не было. Таких проблем и нет. Достаточно сначала установить стек (сегмент и указатель) и push-ить/pop-ить остальные регистры/сегменты туда. Например, так: Код: mov [cs:SaveSS], ss mov [cs:SaveSP], sp mov ss, NewSS mov sp, NewSP pushad push ds push es push fs push gs mov ax, NewSeg mov ds, ax mov es, ax mov fs, ax mov gs, ax ... pop gs pop fs pop es pop ds popad iret scuter писал(а): в IDT стоит Int32 Sel:Off=0008:0010171a и Trap32 Sel:Off=0008:0010171a Тэкс, я же не просто так спросил, работает ли обработчик в реальном режиме. Из приведённого заключаю, что нифига не в реальном, а в защищённом. В защищённом режиме работа процессора (и прерываний) выглядит совершенно по-другому. Лучше всего взять тьюториал (например, этот) по работе прерываний в защищённом режиме. Причин, по которым у тебя всё может виснуть в защищённом режиме из-за некорректной работы обработчика прерываний - мильён и раскручивать/отлаживать код приходится очень мелкими изменениями. |
Автор: | Himik [ 26 апр 2013, 13:41 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
Если в коде присутствует mov SS, ax, значит ты не настраивал TSS, или не разобрался с его работой. Загрузки SS в обработчике прерывания не должно быть. |
Автор: | phantom-84 [ 26 апр 2013, 14:51 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
Да, обычно ss:esp настраивается автоматически или используется текущий стек. Я во вступительной части обработчиков настраиваю только ds и es, т.к. в режиме ядра при дальнейших вызовах вложенных подпрограмм эти регистры должны ссылаться на сегмент данных ядра. Примерно так: Код: push ds Регистры fs и gs сохраняют/настраивают/восстанавливают вложенные подпрограммы, когда это необходимо.push es push ss ; ds <- KDATA pop ds push ss ; es <- KDATA pop es ... pop es pop ds iret В коде обработчика не увидел команды EOI. |
Автор: | pavia [ 26 апр 2013, 15:09 ] |
Заголовок сообщения: | Re: как правильно делать прерывания |
В 0 кольце стек не перегружается, востальных перезагружается автоматом. Не перезагрузка вызывает трудности при переполнении стека или работе в сегметном режиме. Так что перезагружать или нет решать вам. Лучше сделать как выше перезагрузить через кодовый сегмент. |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |