Обработка прерываний

Тема в разделе "WASM.ASSEMBLER", создана пользователем speck, 12 дек 2004.

  1. speck

    speck New Member

    Публикаций:
    0
    Регистрация:
    12 дек 2004
    Сообщения:
    2
    Пытаюсь установить собственное прерывание int 49, например





    .....



    lidt [idtr]

    mov eax,int49_handler

    mov [idt+49*8],ax

    mov word [idt+49*8+2],0x8

    mov word [idt+49*8+4],0x8E00

    shr eax,16

    mov [idt+49*8+6],ax



    sti

    int 49



    int49_handler:

    mov al,'+'

    mov [0xB8000],al

    iret



    ..комп перезагружается на iret Подскажите пожалуйста, в чем дело?
     
  2. volodya

    volodya wasm.ru

    Публикаций:
    0
    Регистрация:
    22 апр 2003
    Сообщения:
    1.169
    Поиск по форуму рулит...
     
  3. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    может быть ты в 32 битном режиме вызываешь 16битный iret?

    use iretd?
     
  4. Same

    Same New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2003
    Сообщения:
    114
    Narkomanius

    опкод у них одинаков 0CFh - Это завист от режима...

    speck У меня тоже прикол с прерываниями в 16 битном работают как надо а в 32х битном - прерывание выполняется но по IRET не возвращается - а вызывает исключение общей защиты:dntknw: и фиг знает почему
     
  5. stel123

    stel123 New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2004
    Сообщения:
    8
    А у меня, почему-то, прерывание выполняется и по IRET возвращается, но вызывает "Двойную ошибку". В чем может быть проблема и как правильно описывать обработчики эксепшнов?
     
  6. Same

    Same New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2003
    Сообщения:
    114
    2 stel123 Это в каком режиме? в 16 или 32?
     
  7. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    может надо 66 cf ?



    напиши откуда куда идет прерывание?

    16->32



    сегменты стека/кода сколькибитные?
     
  8. nobody

    nobody New Member

    Публикаций:
    0
    Регистрация:
    8 сен 2004
    Сообщения:
    32
    Адрес:
    Afghanistan
    Возможно sti разрешает аппаратные прерывания которые ты не обрабатываешь

    А для вызова своего прерывания программно это не нужно - попробуй убрать
     
  9. Narkomanius

    Narkomanius New Member

    Публикаций:
    0
    Регистрация:
    14 апр 2003
    Сообщения:
    144
    не так уж и важно - в 16 битах ведь работает.

    а вот вылет по #DF указывает на то что было #GP и кто то еше - #PF может?

    скорее всего тут мы имеем дело со не правильнобитнымстеком.

    давай сюда код оброботчика и дескрипторы которые юзаются
     
  10. stel123

    stel123 New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2004
    Сообщения:
    8
    [BITS 16]

    [ORG 0x9000]

    _start:

    cli

    mov ax, cs

    mov ds, ax

    mov ss, ax

    mov sp, _start



    in al,70h

    or al,80h

    out 70h,al





    in al,0x92

    or al,2

    out 0x92,al



    lgdt [GDTR]

    lidt [IDTR]



    mov eax,cr0

    or al,1

    mov cr0,eax



    jmp 0x08:_protected



    [BITS 32]

    _protected:

    mov ax,0x10

    mov ds,ax

    mov ss,ax

    mov es,ax

    mov esp,9000



    call setup_idt

    sti



    int 4 ;Например... Врезультате получаю int 4 + #DF



    p: jmp p





    ;--------------------------------



    setup_idt:

    mov ecx,0

    mov eax,isr00

    call set_int_descriptor

    mov eax,isr01

    call set_trap_descriptor

    mov eax,isr02

    call set_int_descriptor

    mov eax,isr03

    call set_trap_descriptor

    mov eax,isr04

    call set_trap_descriptor

    mov eax,isr05

    call set_int_descriptor



    .....................



    mov eax,isr13

    call set_int_descriptor



    set_idt_descriptor:

    mov [IDT+ecx*8],ax

    mov word [IDT+ecx*8+2],0x8

    mov word [IDT+ecx*8+4],0x8E00

    shr eax,16

    mov [IDT+ecx*8+6],ax

    inc ecx

    ret



    set_int_descriptor:

    mov dx,0x8E00

    call set_idt_descriptor

    ret



    set_trap_descriptor:

    mov dx,0x8F00

    call set_idt_descriptor

    ret



    ;------------------------------------------------



    isr00:

    mov al,'0'

    mov [0xB8000+2],al

    iretd

    isr01:

    mov al,'1'

    mov [0xB8000],al

    iretd

    isr02:

    mov al,'2'

    mov [0xB8000+2],al

    iretd

    isr03:

    mov al,'3'

    mov [0xB8000+2],al

    iretd



    .................



    isr13:

    mov al,'d'

    mov [0xB8000+2],al

    iretd



    ;------------------------------------------------



    GDT:

    dw 0, 0, 0, 0

    db 0xFF,0xFF,0x00,0x00,0x00,10011010b,0xCF,0x00

    db 0xFF,0xFF,0x00,0x00,0x00,10010010b,0xCF,0x00

    GDTR:

    dw 8192

    dd GDT

    IDT:

    resw 256*8

    IDTR:

    dw (256*8)-1

    dd IDT
     
  11. stel123

    stel123 New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2004
    Сообщения:
    8
    Спасибо... уже разобрался... Это таймер вызывает 8 исключение, т.к. я не перенапрравляю его прерывание.. Тогда дайте пожалуйста ссылочку или объясните кратенько прицип работы и програмитрования контроллера прарываний..
     
  12. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    2 stel123, кратенько:



    В AT используются (или эмулируются) два контроллера прерываний (8259A): ведущий обслуживает IRQ0-7 (IRQ2 не используется), ведомый - IRQ8-15. Каждый контроллер использует два однобайтных порта: ведущий - 20h-21h, ведомый - A0h-A1h.



    Для инициализации контроллеров используются т. н. ICW1-4 (initialisation control word). Сначала в порт 20h (A0h) посылается ICW1, затем в порт 21h (A1h) - ICW2-4, последовательно. ICW1-4 для ведущего контроллера - 11h, int0, 4, 1Fh, для ведомого - 11h, int8, 2, 1Bh, где int0 и int8 - номер прерывания (кратный восьми) для IRQ0 (08) и IRQ8 (70h).



    Для управления используются OCW1-3 (из которых нужны только первые два), их можно посылать в любое время и в любом количестве. OCW1 посылается в порт 21h (A1h), остальные - в 20h (A0h).



    OCW1: установленные биты 0-7 избирательно запрещают IRQ0-7 (IRQ8-15). После инициализации контроллера все прерывания разрешены.



    OCW2: 20h - EOI (end of interrupt). Необходимо послать EOI ведущему конроллеру (для IRQ8-15 - еще и ведомому) перед IRET(D), иначе больше прерываний не будет.



    (Вся изложенная информация проверена мной на практике).
     
  13. vdk

    vdk New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2003
    Сообщения:
    18
    stel123

    imho не думаю что дело в таймере, если ты не инициализировал контроллер прерываний

    есть предположение: если ты этот код грузиш с boot sectora дискеты то у тебя просто не помещается в 512b IDTR (хотя непонятно почему в таком случае org 0x9000, а не 0x7c00)
     
  14. Same

    Same New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2003
    Сообщения:
    114
    2 Narkomanius

    может надо 66 cf ?

    Гыгыгы - я такого не где не встречал

    - Этот кусок тебе интересен?



    [​IMG] _787454340__123.txt
     
  15. Same

    Same New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2003
    Сообщения:
    114
    Я забыл при переходе в 32 установить бит разрадности стека В дескрипторах прерываний