Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.12.2017, 21:06   #1
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию Не работают прерывания в PM

Пытаюсь настроить прерывания в защищённом режиме, перенастроил PIC(включил таймер и клавиатуру)
PC уходит в reboot после как разрешаю прерывания в Protected mode с помощью команды sti.


В чем может быть проблема?

boot.asm
Код:
use16
jmp _start
_start:
cli
    mov ax, cs
    mov ds, ax 
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
sti           

    mov ax, 03h
    int 10h
jmp time_metka



time_metka:
    mov ax, ds
    shl eax, 4
    lea dx, [ds:NULL_DESC]
    add eax, edx
    mov [ds:GDT_adrr], eax
    mov dx, 39
    mov [ds:GDT_limit], dx


    mov ax, ds
    shl eax, 4
    lea edx, [ds:IDT]
    add eax, edx
    mov [ds:IDTR_ADDRESS], eax
    mov dx, 32
    mov [ds:IDTR_LIMIT], dx
    jmp idtr_recording
;eax - адрес процедуры обработки прерывания
;ebx - запись в таблице дескрипторов
add_idtr_record:
    push eax
    shr eax, 16
    mov [ds:ebx], ax
    pop eax
    mov [ds:(ebx+6)],ax
    ret

idtr_recording:
    ;sys_call
    lea eax, [cs:syscall_int]
    lea ebx, [ds:SYS]
    call add_idtr_record

    lea eax, [cs:global_catch_int]
    lea ebx, [ds:GP]
    call add_idtr_record

    lea eax, [cs:sys_timer_int]
    lea ebx, [ds:TIMER]
    call add_idtr_record

    lea eax, [cs:keyboard_int]
    lea ebx, [ds:KBRD]
    call add_idtr_record


    cli 
    mov al,8Fh;
    out 70h,al
    in al,71h

    mov dx, 0FFFFh
    mov bx, 2820h
    call redirect_IRQ  
    jmp next

    include 'PIC_prog.asm'

next:
   

    call OpenA20Gate       
    lgdt [GDTR]             
    lidt [idtr_d]
    call EnablePMode        


OpenA20Gate:
    in al, 0x92         
    or al, 2            
    out 0x92, al
    ret


EnablePMode:
    xor  eax, eax
   ; mov  ax, cs
   ; shl  eax, 4
    add  eax, ProtectedMode

    mov [cs:JMainPM], eax

    mov eax, cr0
    or eax, 1
    mov cr0, eax

          ; бинарный код для jmp fword 08h:PM_StartUp32
         DB 066h
         DB 0EAh
JMainPM: DD 0                 
         DW 08h
    
    ;  предел(2)-
NULL_DESC:
    db 0, 0, 0, 0, 0, 0, 0, 0
CODE_DESC:
    db 0xFF, 0xFF, 00h, 00h, 00h, 0x9A, 0xCF, 0 
DATA_DESC:
    db 0xFF, 0xFF, 00h, 00h, 00h, 0x92, 0xCF, 0     
VIDEO_SEG:
    db 0FFh ,0FFh, 00h, 80h, 0Bh, 92h,  040h,  0

GDTR:
    GDT_limit dw 0
    GDT_adrr dd  0


IDT:
        dd 0,0 ;0 
SYS     dw 0 ,08h, 1000111000000000b, 0 ; 1
        dd 0,0 ; 2
        dd 0,0 ; 3
        dd 0,0 ; 4
        dd 0,0 ; 5
        dd 0,0 ; 6
        dd 0,0 ; 7
        dd 0,0 ; 8
        dd 0,0 ; 9
        dd 0,0 ; 10
        dd 0,0 ; 11
        dd 0,0 ; 12
GP      dw 0, 08h, 1000111000000000b, 0   ; 13  #GP
        dd 0,0 ; 14
        dd 0,0 ; 15
        dd 0,0 ; 16
        dd 0,0 ; 17
        dd 0,0 ; 18
        dd 0,0 ; 19
        dd 0,0 ; 20
        dd 0,0 ; 21
        dd 0,0 ; 22
        dd 0,0 ; 23
        dd 0,0 ; 24
        dd 0,0 ; 25
        dd 0,0 ; 26
        dd 0,0 ; 27
        dd 0,0 ; 28
        dd 0,0 ; 29
        dd 0,0 ; 30
        dd 0,0 ; 31
TIMER   dw 0, 08h, 1000111000000000b, 0   ; IRQ 0 - ñèñòåìíûé òàéìåð
KBRD    dw 0, 08h, 1000111000000000b, 0   ; IRQ 1 - êëàâèàòóðà
idtr_d:
    IDTR_LIMIT      dw 0
    IDTR_ADDRESS    dd 0



use32
org $+20000h
gp2 db  'Protected mode',0
GP_text db 'General protection fault',0
KB_tb   db 'Keyboard press',0
TM_text db 'Timer text',0


ProtectedMode:
    mov     ax, DATA_DESC - NULL_DESC
    mov     ds, ax 
    mov     es, ax
    mov     fs, ax
    mov     ax, VIDEO_SEG - NULL_DESC
    mov     gs, ax

    lea ebx, [gp2]
    mov di, 0
    xor esi, esi
    in   al, 70h
    and  al, 7Fh
    out  70h, al
    sti
    
    call _puts_1
    
halt:    
    jmp halt

_puts_1:
    mov ah, 1bh
    xor edx, edx
_puts:
    mov  al, [ebx]
    inc ebx
    cmp al, 0
    je _puts_end
    mov  [gs:edi], ax
    add edi, 2
    jmp _puts
_puts_end:
    ret


syscall_int:
    lea ebx, [TM_text]
    mov edi, 0
    call _puts_1
    jmp int_EOI

global_catch_int:
    lea ebx, [GP_text]
    mov edi, 0
    call _puts_1
    jmp int_EOI
keyboard_int:
    lea ebx, [KB_tb]
    mov edi, 0
    call _puts_1
    jmp int_EOI
sys_timer_int:
    lea ebx, [TM_text]
    mov edi, 0
    call _puts_1
    jmp int_EOI
int_EOI:
    push ax
    mov al, 20h
    out 020h, al
    out 0a0h, al
    pop ax
    iretd
PIC_prog.asm
Код:
use16
redirect_IRQ:
     mov    ecx, 1bh
    rdmsr
    or    eax, 1000b
    wrmsr
 
    mov ax,02011h
    out 20h,al ; 00010001b ICW1 ,будет ICW4

    mov al,ah
    out 21h,al ; 20h ICW2 - номер обработчика прерывания
  
    mov al,4   
    out 21h,al ; 00001000b ICW3 - номер контролера подключения ведомого

    mov al,1
    out 21h,al ; 00000001b ICW4 

    in  al, 21h
    mov al,0FCh
    out 21h,al


    ;второй контроллер
    ;прерывания 8-15 получают номера 28H-2FH
    mov ah,28h
    mov al,11h
    out 0A0h,al

    mov al,ah
    out 0a1h,al

    mov al,4
    out 0a1h,al

    mov al,1
    out 0a1h,al

    mov al,0FFh
    out 0a1h,al

    ; APIC On
    rdmsr
    and    eax, not 1000b
    wrmsr
  ret
Nikolay2015 вне форума Ответить с цитированием
Старый 10.12.2017, 23:17   #2
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

С этой проблемой пока разобрался. Но теперь выскакивает GP, а потом проблема с памятью и qemu завершает работу и пишет значения регистров.

Цитата:
qemu: fatal: Trying to execute code outside RAM or ROM at 0x00000000f1007675

EAX=00029261 EBX=00020989 ECX=0000001b EDX=057b0e80
ESI=00000e79 EDI=ffffffff EBP=19de0000 ESP=00029259
EIP=f1007675 EFL=00000c82 [DOS----] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =2000 00020000 0000ffff 00009300 DPL=0 DS16 [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0018 000b8000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 0002012d 00000020
IDT= 00020159 000000ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00029261 CCD=000292c4 CCO=ADDB
EFER=0000000000000000
FCW=037f FSW=2004 [ST=4] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=c000000000000000 ffff
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000 000 XMM01=00000000000000000000000000000 000
XMM02=00000000000000000000000000000 000 XMM03=00000000000000000000000000000 000
XMM04=00000000000000000000000000000 000 XMM05=00000000000000000000000000000 000
XMM06=00000000000000000000000000000 000 XMM07=00000000000000000000000000000 000
Аварийный останов (сделан дамп памяти)
И как я понял этой ошибки не возникает если сделать меньше данных в защищённом режиме, или посокращать код в реальном режиме. То просто вылетает GP. Иногда если очень много данных, примерно 500 байт, то #GP обработчик неккоректно выводит строку.

С чем это может быть связанно?
Nikolay2015 вне форума Ответить с цитированием
Старый 11.12.2017, 00:03   #3
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от Nikolay2015 Посмотреть сообщение
С чем это может быть связанно?
имхо что-то со-стеком у тебя глюки - SS зашкаливает...
вот значения сегментных регистров из твоего лога:
Код:
 ES =0010  00000000  ffffffff  00cf9300  DPL=0 DS   [-WA]
 CS =0008  00000000  ffffffff  00cf9a00  DPL=0 CS32 [-R-]
 SS =2000  00020000  0000ffff  00009300  DPL=0 DS16 [-WA]
 DS =0010  00000000  ffffffff  00cf9300  DPL=0 DS   [-WA]
 FS =0010  00000000  ffffffff  00cf9300  DPL=0 DS   [-WA]
 GS =0018  000b8000  ffffffff  00cf9300  DPL=0 DS   [-WA]
а вот так они выглядят, если отладчиком потрассировать ядерный код из-под винды.
здесь указаны результаты трейса обоих типов: и кода ядра, и кода юзера.
это мои недавние эксперименты (к твоему коду отношения не имеют):
Код:
         |    Kernel (RPL=0)   ||     User (RPL=3)    | 
Регистры |    селектор (bin)   ||    селектор (bin)   | Регистры
---------|---------------------||---------------------|---------
 CS=08h  - 0000000000001.0.00  ||  0000000000011.0.11 -  CS=1Bh 
 DS=10h  - 0000000000010.0.00  ||  0000000000100.0.11 -  DS=23h
 SS=18h  - 0000000000011.0.00  ||  0000000000101.0.11 -  SS=2Bh
 ES=20h  - 0000000000100.0.00  ||  0000000000110.0.11 -  ES=33h
 FS=28h  - 0000000000101.0.00  ||  0000000000111.0.11 -  FS=3Bh
 GS=30h  - 0000000000110.0.00  ||  0000000001000.0.11 -  GS=43h
заслуживают внимания здесь только CS\DS\SS, остальные могут плясать в разные стороны.
эти три (как показали мои опыты) - постоянны.
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 11.12.2017, 00:20   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

А зачем отдельный селектор для видеопамяти?
waleri вне форума Ответить с цитированием
Старый 11.12.2017, 00:32   #5
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

Цитата:
Сообщение от R71MT Посмотреть сообщение
имхо что-то со-стеком у тебя глюки - SS зашкаливает...
вот значения сегментных регистров из твоего лога:
Да как бы не зашкаливает, я для ss селектор описывал 18h, убирал (оставлял адрес из реального режима) разницы ноль. Только если селектор стека определен, то в reboot уходит. Но перед reboot #GP успевает поймать исключение.
Nikolay2015 вне форума Ответить с цитированием
Старый 11.12.2017, 00:43   #6
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
А зачем отдельный селектор для видеопамяти?
А почему бы и нет
Nikolay2015 вне форума Ответить с цитированием
Старый 11.12.2017, 00:47   #7
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

Разобрался регистр esp переполнялся и выходил за пределы селектора стэка. Т.к. GP кладёт в стек 4 байта кода ошибки.(При #GP, забирал значение из стека) А вот теперь вопрос, что за ошибка может быть?

Последний раз редактировалось Nikolay2015; 11.12.2017 в 01:00.
Nikolay2015 вне форума Ответить с цитированием
Старый 11.12.2017, 01:21   #8
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

Цитата:
Сообщение от Nikolay2015 Посмотреть сообщение
Разобрался регистр esp переполнялся и выходил за пределы селектора стэка. Т.к. GP кладёт в стек 4 байта кода ошибки.(При #GP, забирал значение из стека) А вот теперь вопрос, что за ошибка может быть?
Прошёлся отладчиком висит на кодe jmp $ долго прыгает, но потом через (неизвестное) количество тактов выпадает #GP
Nikolay2015 вне форума Ответить с цитированием
Старый 11.12.2017, 03:18   #9
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

Один момент. При исключении #GP код ошибки равен 0102h, что это значит не знаю.

Такого селектора у меня нет, да и нигде я его не загружал.

Откуда такой код ошибки?

И при чём #GP срабатывает всегда, то есть не 1 раз , а повторяется. Через некоторое количество тактов которое я не могу узнать, даже через отладчик, т.к. даже в отладчике я не дошёл до обработчика #GP

Пробовал:
Разрешаю NMI
sti

1) jmp $
2) hlt
3) halt:
nop
jmp halt

Последний раз редактировалось Nikolay2015; 11.12.2017 в 05:03.
Nikolay2015 вне форума Ответить с цитированием
Старый 11.12.2017, 08:53   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от Nikolay2015 Посмотреть сообщение
А почему бы и нет
Например потому что все инструкции обращения к видеопамяти будут на один байт длиннее.
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с циклом. Компилируется нормально,кнопки Один,Два,Три,Четыре и Пять работают хорошо,но кнопки 6 и 7 не работают. Bananiys24 Общие вопросы по Java, Java SE, Kotlin 1 16.06.2017 17:01
Как в МК работают аппаратные прерывания? седьмой Микроконтроллеры, робототехника, схемотехника, 3D принтеры 13 05.05.2017 06:39
Не работают прерывания xotonic Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 4 24.10.2014 21:18
прерывания lilek Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 14.12.2010 20:44
Делфи и ассемблер. Не работают прерывания типа Int Я_и Общие вопросы Delphi 8 11.12.2010 13:13