IDT, 8059 - в чём ошибка? %)

Тема в разделе "WASM.ASSEMBLER", создана пользователем 0136, 8 дек 2007.

  1. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Всем привет!
    Пишу ось, с целью познания мира ;)
    Настроил контролёр прерываний на векторы 20h и 28h
    Сформировал IDT ,влепил все дескрипторы такими db 0h, 0h, 08h, 0h, 0h, 10001110b, 0h, 0h, настраиваю смещения обработчиков в них. И когда в коде настройки контролёра разрешено прерывание
    mov al, 11111101b ; OCW1
    out 21h, al
    (пробую с клавиатурой или с таймером) то при старте перегружается комп :)
    Кто скажет в чём, где, какая ошибка, как сделать что бы работало? С шести вечера колупаюсь, комп раз 20 перегружался! %)
    Благодарю за внимание :)
    Код прикрепил.
     
  2. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    0136

    Ну, во-первых, есть ошибка в вычислении адреса GDT перед переключением в защищённый режим:

    Код (Text):
    1.     xor eax, eax            ; вычисляется физ. адрес GDT    
    2.     mov ax, seg_gdt     ; (4000h)
    3.     shl eax, 4      
    4.     add ax, offset ds:Zero_descriptor   ; прибавляется к физ.адрeсу смещение в сег. данных
    5.     mov LA_GDT, eax     ; сохр. физ. адреса GDT
    Физический адрес -- это 4 байта (реально до 20 бит), поэтому и используется регистр EAX. Но почему выполняем 16-разрядное сложение, а не 32-разрядное?

    Ну а во-вторых, что, собственно, и вызывает глюк: судя по коду в IDT, обработчики всех прерываний имеют точку входа 8:0, что соответствует нулевому физическому адресу памяти. Ну а Ваша программа явно на ходится не там. Более того, обработчиков прерываний в ней я вовсе не обнаружил (хотя в полвторого ночи внимательно смотреть откровенно не хочется).
     
  3. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    ; Реальный режим
    xor eax, eax ; EAX=0
    mov ax, seg_gdt ; AX=сегмент таблицы
    shl eax, 4 ; EAX=физический адрес сегмента
    add ax, offset ds:Zero_descriptor ; +16разрядное смещение

    mov LA_GDT, eax ; сохр. физ. адреса GDT
    Выделен ведь отдельный сегмент под GDT, нулевой дескриптор стоит по адресу seg_gdt:0000. Можно вообще не добавлять смещение.


    Вот что с IDT:
    ; Это всё ещё реальный режим.
    xor eax, eax
    mov ax, seg_idt ; настроим IDT
    mov ds, ax

    shl eax, 4 ; вычислим физ. адрес IDT
    add ax, offset Gate_descriptor0
    mov LA_IDT, eax ; сохранение полного физ. адреса IDT

    ; настройка смещений шлюзов
    xor eax, eax
    mov eax, seg_cs32
    shr eax, 4
    mov edx, eax

    add eax, offset int_0
    mov word ptr ds:Gate_descriptor0, ax
    shr eax, 16
    mov word ptr ds:Gate_descriptor0+6, ax

    SII, ошибка в чём то другом. Спасибо тебе ;)
     
  4. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    0136
    От того, что смещение равно нулю, факт ошибки никуда не исчезает. Она лишь не приводит к неправильному результату, но не более того. Так что аккуратней будьте с адресной арифметикой.

    Тоже некорректное сложение. Вы думаете, что не может возникнуть переноса из 15-го разряда, который в таком случае будет потерян, и в результате в EAX получится неверный адрес? Возможно, в конкретном случае переноса действительно возникнуть не может, но такое сложение -- ошибочное. Грамотно написанная программа не "закладывается" на размещение своих кишок в памяти, за исключением совсем уж особых случаев (типа загрузчика, который грузится BIOSом в строго определённую область).

    Ну а дальнейший код вообще мутный какой-то...
     
  5. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    SII, не в этом дело. Но всё же спасибо за корректуру.
     
  6. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Прошу извинения, нашёл ошибку, перепутал некоторые команды в процесе инициализации IDT. Просьба админу - закройте тему.
    Всем спасибо :)