Реальный режим, сбой при замене вектора прерывания

StackOverflow https://stackoverflow.com/questions/842341

Вопрос

Я пытаюсь узнать больше о том, как на самом деле работают системы под всей этой красивой графикой сверху.Итак, в настоящее время я играю с памятью в 512 байт, которую BIOS загружает при запуске, на данный момент, я думаю, не могу назвать это загрузчиком.В любом случае, я заменяю вектор прерывания, но у меня возникают проблемы с ним.После замены interupt 09h (клавиатура) он функционирует корректно, при нажатии клавиши выводится сообщение "Ошибка памяти".Но потом ничего.Каждое последующее нажатие клавиши ничего не дает.Я не знаю, происходит ли сбой в системе или я что-то упускаю из своего обработчика, вот код:

jmp start
times 100 db 0 ; Cleared space for stack

start:
xor ax, ax
mov ax, start
sub ax, 80
mov sp, ax 

mov al, 0x09   ; Interupt number
mov bl, 4
mul bl
mov bx, ax
xor ax, ax
mov es, ax
mov [es:bx], word prints ; My interupt handler
add bx, 2
mov [es:bx], word 0x00

bloader:
    jmp bloader

prints:
    cli
    push ax
    push bx
    push si
    mov si, msg       ; Message to print
    mov bl, 0x07
    mov bh, 0x00
    printnb:
        lodsb     ; Grab byte from message
        cmp al, 0 ; End of message
        je printf
        mov ah, 0x0E
        int 0x10  ; Print byte
        jmp printnb
    printf:
        mov al, 0x20
        out 0x20, al ; Inform interupt controller interupt has been handled
        pop si
        pop bx
        pop ax
        sti
        iret ; Interupt return

msg db "Memory messing",0

times 510 - ($ - $$) db 0
dw 0xAA55
Это было полезно?

Решение

Прошло много времени с тех пор, как я работал над обработкой прерываний клавиатуры, но я думаю, чего вам не хватает, так это фактической обработки аппаратного обеспечения клавиатуры, чтобы оно очистило условие прерывания и было готово сгенерировать другое прерывание.

Что - то вроде:

         in     al, 60h     ; Read input buffer 

может быть, это все, что для этого нужно.

Если у меня будет возможность, я посмотрю, нет ли у меня каких-нибудь старых заметок или кода, завалявшихся еще с тех времен, когда я писал драйверы клавиатуры.

Другие советы

Мое предположение (я никогда не писал обработчик прерываний клавиатуры) заключается в том, что вам также нужно связаться с аппаратным обеспечением клавиатуры, чтобы восстановить нажатие клавиши (иначе клавиатура не будет знать, когда генерировать следующее прерывание).

Я обнаружил еще одну проблему.Если мы установим новый вектор прерывания для ISR с двумя отдельными инструкциями перемещения, то возможно, что между этими двумя инструкциями перемещения произойдет прерывание, а затем он получит адрес из поврежденного вектора с одной частью старого местоположения, а другой частью нового местоположения ISR.Но в этом местоположении нет ISR, нет инструкций для ЗАВЕРШЕНИЯ прерывания, а также нет инструкции iret.

Ибо, чтобы предотвратить такие плохие события, мы должны поместить cli и sti вокруг этих инструкций перемещения для установки нового вектора прерывания.

cli
mov [es:bx], word prints ; My interupt handler
mov [es:bx+2], word 0x00
sti

Дирк

Это всего лишь предположение, но, возможно, проблема в том, что вы вызываете int 10h из обработчика int 9h.Попробуйте выполнить запись в экранную память напрямую (просто увеличьте байт на 0b800h: 0 и установите флажок на верхний левый символ на экране).Если он увеличивается при каждом нажатии клавиши, то вам не следует вызывать int 10h из int 9h.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top