Ребята, всем привет, может я не по теме, но думаю тут много профессионалов, прошу подсказать - настраиваю таймер, на большую частоту:
; Повышение частоты таймера
xor ax, ax
mov al, 00110110b ; канал 0, режим 3, вид операции 3, счёт двоичный
out 43h, al
;!!!!!!!!!!!!!!!!!
mov ax, 02 ; значение фиксатора 2
;!!!!!!!!!!!!!!!!!
out 40h, al
mov al, ah
out 40h, al
Если ЗНАЧЕНИЕ ФИКСАТОРА где то примерно 100, то всё работает . Как только ставлю маленькое значение, так сразу получаю нарушение общей защиты. Обьясните мне пожалуйста этот момент
Креплю код, в котором происходитит такое "чудо", и ещё, у меня там вывод ошибочного селектора вроде не правильно выводится, подскажите а то уже голова кругом %)
быстрое возбухание таймера = GP13
-
- Attachments
-
-
rabbit.rar (13.43 KiB)
- мой подопытный кролик ;)
Downloaded 589 times
-
Хе-хе, к нам уже с васма идут
По теме: рекомендую вместо tasm/masm использовать fasm. В fasm'е iret означает то, что он и должен означать, а в tasm и masm в 32-битном режиме нужно писать iretd
По теме: рекомендую вместо tasm/masm использовать fasm. В fasm'е iret означает то, что он и должен означать, а в tasm и masm в 32-битном режиме нужно писать iretd
Ушёл к умным, знающим и культурным людям.
diamond, спасибо за совет, но, во первых, он не по теме, во вторых, как ты пипой не крути, ирет получишь ты, пофиг iret или iretd, у меня бит D во всег дескрипторах означает 32-й режим, когда iret, то это значит что он работает с 32-ми данными тчк.
То что в коде моём ошибок куча, то такое. А вот почему выбивает искл13, при быстро возбуждающемся таймере????????????
То что в коде моём ошибок куча, то такое. А вот почему выбивает искл13, при быстро возбуждающемся таймере????????????
Фактически в исходнике написан iretw - при компиляции добавляется префикс изменения разрядности операнда 66h. Поскольку iretw считает, что ситуация 16-битная, то, с её точки зрения, стек выглядит так:
dw old_ip
dw old_cs
dw old_flags
А на самом деле там
dd old_eip
dd MOVZX(old_cs)
dd old_eflags
Следовательно, она пытается вернуться к селектору HIWORD(old_eip) = 0, что, естественно, приводит к #GP.
dw old_ip
dw old_cs
dw old_flags
А на самом деле там
dd old_eip
dd MOVZX(old_cs)
dd old_eflags
Следовательно, она пытается вернуться к селектору HIWORD(old_eip) = 0, что, естественно, приводит к #GP.
diamond, там с самого начала написано - сегмент кода, 32 разрядный, seg_code32 segment use32. код команды iret = CF, у тебя что фасм ставит префикс??? Нафиг префикс??? Чё ты придумал??? Не в этом ошибка Спасибо за твою внимательность и за желание помочь
Нет, не фасм - он такое не скомпилит. masm (которым я компилил 1.asm) действительно в use32-сегментах ставит префикс перед iret. Но в 1.exe действительно iret идёт без всяких префиксов, так что этот вариант отпадает.
А тестировалось случайно не под Bochs? Почему такое происходит под Bochs, я могу объяснить, а под qemu и VMWare 1.exe работает...
А тестировалось случайно не под Bochs? Почему такое происходит под Bochs, я могу объяснить, а под qemu и VMWare 1.exe работает...
Проверил на реальной машине - Bochs оказался прав... #GP с кодом ошибки, указывающим на индекс 0x27 в IDT. Иными словами, происходит IRQ7, а поскольку для него обработчика в IDT нет, то процессор выкручивается как может.
Теперь почему это происходит.
http://lib.e-hard.ru/book/1/page/118.html
1) Запрещаются прерывания. (Кстати, переключение графического режима лучше бы делать в самом начале, потому что 0-я функция int 10h вполне может их временно разрешать...)
2) При перепрограммировании таймера ему указывается режим 3 - генерация прямоугольных импульсов. Что в переводе на русский означает: когда счётчик доходит до нуля, микросхема попеременно посылает высокий уровень сигнала и низкий уровень сигнала.
3) Таймер начинает эти импульсы подавать в большом количестве. Контроллер прерываний запоминает, что кто-то подал сигнал.
4) Но процессору не до них. Прерывания запрещены, причём довольно долгое время (переключение в PM быстро не делается).
5) И вот процессор разрешает прерывания. Контроллер прерываний заявляет процессору "прерывание пришло!" Процессор отвечает: "ну-ну... что за прерывание-то?" Контроллер смотрит на устройства... и видит, что везде уровень сигнала низкий (ибо микросхема таймера уже успела всё сбросить, а остальные даже и не рыпались). Контроллер:"(про себя) Опа! Интересно, что это было? Ладно, надо что-то ответить, процессор ждёт... (процессору) получай: IRQ7, вектор 27h"
6) Процессор (про себя): "странный какой-то вектор... чё там в IDT? ах, нули? Я отказываюсь работать в таких условиях! Вот вам! #GP(27h*8 + 3)!"
Теперь почему это происходит.
http://lib.e-hard.ru/book/1/page/118.html
Хроника событий:В любом случае сигнал запроса аппаратного прерывания IRQx должен удерживаться генерирующей его схемой, по крайней мере, до цикла подтверждения прерывания процессором — именно в этот момент PIC определяет самый приоритетный незамаскированный запрос и по нему формирует вектор. Если к этому моменту запрос окажется снятым, источник прерывания корректно идентифицирован не будет, и контроллер сообщит ложный вектор прерывания (spurious interrupt), соответствующий его входу с максимальным номером (IRQ7 для первого контроллера и IRQ15 для второго). Обычно периферийные устройства строят так, что сигнал запроса сбрасывается при обращении программы обслуживания прерывания к соответствующим регистрам адаптера, так что ложных прерываний возникать не должно.
1) Запрещаются прерывания. (Кстати, переключение графического режима лучше бы делать в самом начале, потому что 0-я функция int 10h вполне может их временно разрешать...)
2) При перепрограммировании таймера ему указывается режим 3 - генерация прямоугольных импульсов. Что в переводе на русский означает: когда счётчик доходит до нуля, микросхема попеременно посылает высокий уровень сигнала и низкий уровень сигнала.
3) Таймер начинает эти импульсы подавать в большом количестве. Контроллер прерываний запоминает, что кто-то подал сигнал.
4) Но процессору не до них. Прерывания запрещены, причём довольно долгое время (переключение в PM быстро не делается).
5) И вот процессор разрешает прерывания. Контроллер прерываний заявляет процессору "прерывание пришло!" Процессор отвечает: "ну-ну... что за прерывание-то?" Контроллер смотрит на устройства... и видит, что везде уровень сигнала низкий (ибо микросхема таймера уже успела всё сбросить, а остальные даже и не рыпались). Контроллер:"(про себя) Опа! Интересно, что это было? Ладно, надо что-то ответить, процессор ждёт... (процессору) получай: IRQ7, вектор 27h"
6) Процессор (про себя): "странный какой-то вектор... чё там в IDT? ах, нули? Я отказываюсь работать в таких условиях! Вот вам! #GP(27h*8 + 3)!"
Ушёл к умным, знающим и культурным людям.
Спасибо за инфу, буду думать! Тестировал на мсдосе . Сразу возникает вопрос - если так, так это получается, если, подключить устройство, очень быстрое, например, которое будет подавать сигналы с частотой в 10 Мгц, то фиг можно будет их быстро обработать? Получается их можно обработать с частотой таймера?
10 миллионов прерываний в секунду?! Зачем столько?если, подключить устройство, очень быстрое, например, которое будет подавать сигналы с частотой в 10 Мгц, то фиг можно будет их быстро обработать?
Для передачи данных совершенно необязательно генерировать прерывание после каждого байта. Практически все устройства общаются пакетами: есть новый пакет - генерируем IRQ, а обработчик разбирается, что произошло, сколько байт в пакете и т.п.
Если
а) процессор очень быстрый,
б) обработчик соответствующего устройству прерывания очень быстрый,
в) прерывания никогда не запрещаются надолго,
то обработка даже прерываний, приходящих с очень высокой частотой, возможна. Но если хотя бы одно из требований не выполнено (а это так практически наверняка), то некоторые сигналы будут неизбежно теряться. Насколько это фатально - зависит от устройства. Микросхема таймера в режиме 3 может успеть сбросить сигнал, и тогда одно прерывание будет потеряно, а вместо него поступит IRQ7 (между прочим, обычное IRQ, его тоже можно обрабатывать). В случае, когда устройство держит высокий уровень, просто при этом потеряется одно прерывание.
diamond, а ведь не может быть IRQ7, оно у меня запрещено, при настройке кПр-й:
mov al, 11111100b ; OCW1, 0 - разрешено прерывание, 1 - запрещено
out 21h, al
mov al, 11111111b ; OCW1, маска
out 0A1h, al
окроме таймера и клавиатуры прерываний больше нет тчк
Есть такой, кто скажет правду???
mov al, 11111100b ; OCW1, 0 - разрешено прерывание, 1 - запрещено
out 21h, al
mov al, 11111111b ; OCW1, маска
out 0A1h, al
окроме таймера и клавиатуры прерываний больше нет тчк
Есть такой, кто скажет правду???
Diamond
Бесполезно пытаться объяснять человеку, который не желает тратить время на тщательное изучение документации...
0136
Так что читайте, дорогой осеписатель, документацию, и читайте внимательно.
Бесполезно пытаться объяснять человеку, который не желает тратить время на тщательное изучение документации...
0136
Для особых интеллектуалов повторяю цитату, приведённую Диамондом:diamond, а ведь не может быть IRQ7, оно у меня запрещено, при настройке кПр-й
А теперь, на всякий случай, ещё и своими словами: если контроллер прерываний получает от процессора сигнал, по которому он должен сообщить процессору вектор, и в этот момент обнаруживается, что никаких активных запросов прерываний от устройств уже нет (запросы были сброшены до того, как были обработаны), контроллер всегда сообщает вектор с наибольшим номером. И никакое маскирование от этого не спасает, потому что маскирование блокирует входящие линии IRQ, а не внутренние схемы контроллера прерываний.В любом случае сигнал запроса аппаратного прерывания IRQx должен удерживаться генерирующей его схемой, по крайней мере, до цикла подтверждения прерывания процессором — именно в этот момент PIC определяет самый приоритетный незамаскированный запрос и по нему формирует вектор. Если к этому моменту запрос окажется снятым, источник прерывания корректно идентифицирован не будет, и контроллер сообщит ложный вектор прерывания (spurious interrupt), соответствующий его входу с максимальным номером (IRQ7 для первого контроллера и IRQ15 для второго)
Так что читайте, дорогой осеписатель, документацию, и читайте внимательно.
привет, точно, сделал IRQ7, и оно возникает %). И нафиг такое железо глючное в комп поставили? Ладно, всем спасибо.
Претензии -- к дегенератам из Интела, которые придумали самые уродские в мире 8-, 16- и 32-разрядные процессоры. Пальму первенства в 64-разрядном сегменте у них отобрали идиоты из АМД.0136 wrote:привет, точно, сделал IRQ7, и оно возникает %). И нафиг такое железо глючное в комп поставили? Ладно, всем спасибо.
Кстати, от знания того, что возникает IRQ7, проблема не исчезает: надо делать так, чтоб оно не возникало, а значит -- корректно программировать и таймер, и контроллер прерываний, и обработчик прерывания от таймера (и, вероятно, не только от него), чтобы прерывания всегда обрабатывались вовремя.
Никаких глюков там нет. Контроллер хранит все запросы на прерывания пока его не перепрограммируют, так что сначала надо замаскировать прерывания в контроллере. Кстати современные чипсеты в случае ошибки генерируют только IRQ7.
Наши быдлокодеры используют Cyrix?SII wrote:Претензии -- к дегенератам из Интела, которые придумали самые уродские в мире 8-, 16- и 32-разрядные процессоры
Who is online
Users browsing this forum: No registered users and 2 guests