Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Защищённый режим, первые шаги 
V
    Опции темы
JAPH
Дата 4.2.2007, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: нет
Всего: 23



Привожу программку, которая умудряется перевести процессор в защищённый режим, вывести на экран энное количество восклицательных знаков, перевестись обратно в реальный режим и корректно передать управление обратно DOSу.
Код

        .486p        ;Тестируется на Pentium MMX. Компилятор TASM
sseg    segment stack    ;Сегмент стэка, используемый и в реальном (RM), и в защищённом (PM) режимах
        db      0400h dup (?)
sseg    ends
dseg    segment        ;Сегмент, содержащий GDT и IDT
; GDT
gdts    db      8 dup (0)    ;Нулевой дескриптор
    ;Дескриптор сегмента кода, в котором будет осуществляться выход из PM
        db      0FFh, 0FFh, 0, 0, 0, 10011010b, 00000000b, 0 ;cseg
    ;Дескриптор сегмента кода, используемого в PM
        db      0FFh, 0FFh, 0, 0, 0, 10011010b, 11001111b, 0 ;codes for cs
    ;Дескриптор сегмента видеопамяти. К лимиту не придираться
        db      0FFh, 0FFh, 0, 80h, 0Bh, 10010010b, 01000000b, 0 ;B800
    ;Дескриптор сегмента стэка с точки зрения PM
        db      00h, 0FCh, 0, 0, 0, 10010110b, 01000000b, 0 ;sseg for pm
    ;Дескриптор сегмента стэка с точки зрения RM
        db      0FFh, 0FFh, 0, 0, 0, 10010010b, 01000000b, 0 ;sseg for rm
    ;Дескриптор стартового TSS
        db      067h, 0, 0, 0, 0, 10001001b, 00000000b, 0 ;stss
gdtlim  dw      0037h
gdtad   dd      0
idts    dw      20h dup (small offset here, 10h, 1000111000000000b, 0)    ;Все прерывания - на выход из PM
idtlim  dw      00FFh
idtad   dd      0
stss    db      68h dup (0)
dseg    ends
codes   segment use32
        assume  cs:codes, ds:dseg
got:    mov     byte ptr fs:[0], '2'    ;Это - отладочное. Кое-как показывает работу программы
        mov     ecx, 05000000h
@1:     dec     ecx
        jnz     @1
        mov     ax, 20h        ;Инициализация стэка
        mov     ss, ax
        xor     esp, esp
        push    ax        ;И проверка его работоспособности
        pop     ax
        mov     byte ptr fs:[0], '3'
        mov     ecx, 05000000h
@4:     dec     ecx
        jnz     @4
        mov     ax, 30h        ;Инициализация единственного TSS
        ltr     ax
       ;sti             Очень хотелось бы
        mov     ax, 18h        ;Вывод, с которого всё начиналось :)
        mov     es, ax
        mov     ecx, 20
        mov     eax, 07200721h
        xor     edi, edi
        cld
    rep stosd
        mov     ecx, 05000000h
@3:     dec     ecx
        jnz     @3
here:  ;cli             Выход из PM
        mov     ax, 28h        ;Регистру SS нужно дать предел 0FFFFh
        mov     ss, ax
        db      0EAh
        dd      offset back
        dw      8
codes   ends
cseg    segment use16
        assume  cs:cseg, ds:dseg
start:  xor     eax, eax    ;Настройка GDT
        mov     ax, 0B800h
        mov     fs, ax
        mov     ax, dseg    ;Вычисление адреса GDT
        mov     ds, ax
        shl     eax, 4
        mov     gdtad, eax
        xor     eax, eax    ;Настройка дескриптора 2
        mov     ax, codes
        shl     eax, 4
        mov     word ptr gdts + 12h, ax
        bswap   eax
        mov     byte ptr gdts + 14h, ah
        mov     byte ptr gdts + 17h, al
        xor     eax, eax    ;Вычисление базы дескрипторов 4 и 5
        mov     ax, sseg
        shl     eax, 4
        mov     word ptr gdts + 22h, ax
        mov     word ptr gdts + 2Ah, ax
        bswap   eax
        mov     byte ptr gdts + 24h, ah
        mov     byte ptr gdts + 2Ch, ah
        mov     byte ptr gdts + 27h, al
        mov     byte ptr gdts + 2Fh, al
        xor     eax, eax    ;Настройка дескриптора 6
        mov     ax, dseg
        shl     eax, 4
        add     eax, offset stss
        mov     word ptr gdts + 32h, ax
        bswap   eax
        mov     byte ptr gdts + 34h, ah
        mov     byte ptr gdts + 37h, al
        xor     eax, eax    ;Настройка дескриптора 1
        mov     ax, cseg
        shl     eax, 4
        mov     word ptr gdts + 0Ah, ax
        bswap   eax
        mov     byte ptr gdts + 0Ch, ah
        mov     byte ptr gdts + 0Fh, al
        mov     eax, gdtad    ;Вычисление адреса IDT
        add     eax, offset idts
        mov     idtad, eax
        lgdt    fword ptr gdtlim
        lidt    fword ptr idtlim
        in      al, 92h        ;Открытие линии A20
        or      al, 02h
        out     92h, al
        cli            ;Запрет маскируемых
        in      al, 70h        ;   и немаскируемых прерываний
        or      al, 80h
        out     70h, al
        mov     byte ptr fs:[0], '1'
        mov     ecx, 05000000h
@2:     dec     ecx
        jnz     @2
        mov     eax, cr0    ;Поехали!
        or      al, 1
        mov     cr0, eax
        db      66h
        db      0EAh
        dd      offset got
        dw      10h
;----------------------------------
idtr    dw      03FFh        ;IDTR для RM
        dd      0
back:   mov     byte ptr fs:[0], '4'
        mov     ecx, 05000000h
@5:     dec     ecx
        jnz     @5
        mov     eax, cr0    ;Прилетели
        and     al, 0FEh
        mov     cr0, eax
        db      0EAh
        dw      $ + 4
        dw      cseg
        lidt    fword ptr cs:idtr
        mov     byte ptr fs:[0], '5'
        mov     ecx, 05000000h
@6:     dec     ecx
        jnz     @6
        mov     ax, cs
        mov     ds, ax
        mov     es, ax
        mov     ax, sseg
        mov     ss, ax
        mov     esp, 00000400h
        push    ax        ;Работоспособность стэка в RM
        pop     ax
        mov     byte ptr fs:[0], '6'
        mov     ecx, 05000000h
@7:     dec     ecx
        jnz     @7
        in      al, 92h        ;Закрытие A20
        and     al, 0FDh
        out     92h, al
        in      al, 70h        ;Разрешение прерываний
        and     al, 7Fh
        out     70h, al
        sti
        mov     ax, 4C00h    ;Выход в DOS
        int     21h
cseg    ends
        end     start


Так вот. Хочется раскомментировать строку ;sti, чтоб в PM обрабатывать прерывания таймера и клавиатуры (для начала по векторам 8 и 9). Но все мои попытки как-то это организовать проваливались.
Даже такой безобидный вариант: в IDT заменить 8 и 9 шлюзы прерываний на нечто, указывающее на код (в сегменте codes)
Код

mov  al, 20h
out  20h, al
iret

Так как повела себя прога: не дойдя до вывода восклицательных знаков, прошла шаги 4, 5, 6 (в смысле, показала эти цифры) и перезагрузила комп (вероятно, из-за sti). Что это было? Что сделала iret? iretd тоже не помогла - перезагрузка и всё тут. Как правильно?
Если убрать первые две строки в обработчике, прога отрабатывает и даже передаёт управление DOS, но клавиатура в результате просто игнорируется.

Итак, просьба-вопрос: написать простейший обработчик прерываний 8 и 9 (желательно использовать шлюзы прерываний), так, чтобы: прерывание 8 не выполняло никакой полезной работы - пример пустого обработчика; прерывнаие 9 выводило по адресу dword ptr 000B80A0h (через fs) scan-код клавиши-причины прерывания в hex-виде.
Хочется увидеть полный код.


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
MAKCim
Дата 4.2.2007, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



эх, написал бы, но только на GAS  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
JAPH
Дата 4.2.2007, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: нет
Всего: 23



Напишите, объясните отличия от TASM, может, уловлю и синтаксис, и идеи. smile
А если не уловлю, наверняка найдётся кто-нибудь, способный перевести код на TASM.

Это сообщение отредактировал(а) JAPH - 4.2.2007, 20:17


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
MAKCim
Дата 4.2.2007, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



Код

.code32
.text
head_handler:
    addl    $4, %esp /* код ошибки */
    iret

keyboard_handler:
    iret

timer_handler:
    iret

startup_32:
    movw    $2 << 3, %ax
    movw    %ax, %ds
    movw    %ax, %ss
    movl    $0x90200, %esp    /* стек 512 байт */
/* перепрограммирование primary контроллера на 0x20, slave - на 0x28 */
    movb    $0x15, %al
    outb    %al, $0x20
    outb    %al, $0xa0
    movb    $0x20, %al
    outb    %al, $0x21
    movb    $0x28, %al
    outb    %al, $0xa1
    movb    $0x04, %al
    outb    %al, $0x21
    movb    $0x02, %al
    outb    %al, $0xa1
    movb    $0x0d, %al
    outb    %al, $0x21
    movb    $0x09, %al
    outb    %al, $0xa1
/* отключение всех прерываний кроме IRQ0 и IRQ1 */
        movb   $~0 << 2, %al
        outb    %al, $0x21
        movb   $~0, %al
        outb    %al, $0xa1
    sti
/* дальше любой код */

.code16
.section .boot, "ax", @progbits /* при линковке указываем адрес секции .boot = 0 */
.globl boot
boot:
    ljmp    $0x07C0, $1f  /* дальний jump на метку 1 (с изменением CS на 0x07C0) */
1:
    cli
    lgdt    gdtr
    lidt    idtr
    movl    %cr0, %eax
    orb        $1, %al
    movl    %eax, %cr0   /* переход в protected mode ... */
.code32
    ljmp    $1 << 3, $startup_32 + 0x7C00 /* ... и прыжок на startup_32 (физически находится сразу за .boot) 
           но в памяти по адресу 0x7C00 + startup_32 */
idtr:
    .word BOOT_IDT_SIZE - 1
    .long 0x7C00 + idt
idt:
.rept 32 /* 32 исключения (для всех один обработчик head_handler) */
        .word head_handler + 0x7C00
        .word 0x0008
        .word 0x8F00 /* вместо .word 0x8E00, т. е для исключений - шлюз ловушки */
        .word 0
.endr 
    .word timer_handler + 0x7C00 /* адрес обработчика таймера */
    .word 0x0008 /* селектор сегмента кода (1 << 3) */
    .word 0x8E00 /* DPL = 0, P = 1, type = E */
    .word 0
/* дальше аналогично для клавиатуры... */
    .word keyboard_handler + 0x7C00
    .word 0x0008
    .word 0x8E00
    .word 0
BOOT_IDT_SIZE = . - idt
gdtr:
    .word BOOT_GDT_SIZE - 1
    .long 0x7C00 + gdt
gdt:
    .quad 0x0000000000000000
    .quad 0x00CF98000000FFFF /* сегмент кода */
    .quad 0x00CF92000000FFFF /* сегмент данных */
BOOT_GDT_SIZE = . - gdt


Это сообщение отредактировал(а) MAKCim - 5.2.2007, 11:19


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
JAPH
Дата 5.2.2007, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: нет
Всего: 23



Пытаюсь что-нибудь понять...
Вопросы такие:
1. Можно код обратного перепрограммирования контроллера прерываний? То же самое, только в строках 22-25
Код

mov al, 08h  ;movb $0x08, %al
out 21h, al  ;outb %al, $0x21
mov al, 70h  ;movb $0x70, %al
out 0A1h, al ;outb %al, $0xA1

так? (Задно проверяйте понимание синтаксиса)
2. Почему в строке 19 именно 15h, а не 11h, как у Пирогова?
Что есть остальное? Как контроллер отличает различные ICW/OCW, или они посылаются в определённом порядке, тогда в каком? Может, поясните именно этот пример, описание самих CW у меня есть, но связей между ними - нет.
3. Можно ли обойтись без перепрограммирования, то есть можно ли различить, прерывание 8 вызвано из-за таймера или двойной ошибки? По младшему биту кода ошибки? Хотя прерывание таймера не помещает код ошибки в стэк, не должно, так ведь? Может, пользоваться шлюзом задачи и отслеживать ESP - есть код ошибки или нет?
4. В 17ой строке опечатка?


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
MAKCim
Дата 5.2.2007, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



отвечу с конца  smile 
4.
нет, не опечатка, просто в пределах 1-го мегабайта память в пространстве адресов между
0x500 и 0x9FBFF свободна (нет данных BIOS и пр.), поэтому и отводим под стек 512 байт от 0x90200 до 0x90000
(так как мы используем flat 32-х разрядный сегмент данных с базой 0 и лимитом 0xFFFFFFFF)
3.
Код ошибки помещается в стек только для исключений. Это раз. Во-вторых обработчик исключения вызывается через шлюз ловушки, в то время как обработчики аппаратных прерываний - через шлюзы прерываний (автоматический вызов cli после записи EFLAGS). Я точно не уверен, будет ли #GP, если их подменить (т. е прерывания обрабатывать через шлюз ловушки)
Цитата

Может, пользоваться шлюзом задачи и отслеживать ESP - есть код ошибки или нет?

как вариант, только не шлюзом задачи, а TSS сегментом  smile 
Код

timer_handler:
    push    ebx
    xor    ebx, ebx
    str    bx ; селектор дескриптора TSS
    push    eax
    sgdt    [esp - 6]
    mov    eax, dword ptr [esp - 4] ; базовый адрес GDT
    lea    eax, [eax + ebx * 8] ; находим дескриптор TSS
; вычисляем базу сегмента TSS
    mov    bh, byte ptr [eax + 7]
    mov    bl, byte ptr [eax + 4]
    shl    ebx, 16
    mov    bx, word ptr [eax]
    mov    eax, [ebx + 4] ; находим esp для CPL = 0
; дальше код с учетом, непереключения стека при вызове обработчика исключения
    sub    eax, 18 ; esp - eflags (4 байта) - cs (2 байта) - eip (4 байта) - ebx (см. начало обработчика) (4 байта)  - eax (аналогично 4 байта)
    cmp    eax, esp
    jz    @@L1 ; нет кода ошибки
    ; есть код ошибки => исключение
...
@@L2:
...

(надеюсь, написал правильно, если не забыл tasm)
но как видишь, код будет излишне длинным (т. е сам обработчик будет выполняться через хз сколько команд), что неприемлемо для обработчиков прерываний/исключений
при этом у тебя также должен быть валидный дескриптор TSS в GDT и TSS сегмент
2.
15h = 00010101b
11h = 00010001b
2-ой бит - размер вектора прерывания
если он - 1 => размер 4 байта, иначе - 8 байт
Цитата(JAPH @  5.2.2007,  00:02 Найти цитируемый пост)
Что есть остальное? Как контроллер отличает различные ICW/OCW, или они посылаются в определённом порядке, тогда в каком? Может, поясните именно этот пример, описание самих CW у меня есть, но связей между ними - нет.

да, они посылаются в определенном порядке
ICW1 -> ICW2 -> [ICW3] -> [ICW4]
Код

movb    $0x15, %al /* старшие биты 0x15 - 0001 показывают, что будет запись ICW1 */
    outb    %al, $0x20 /* запись в ICW1 primary */
    outb    %al, $0xa0 /* запись в ICW1 slave */
    movb    $0x20, %al /* IRQ0 - IRQ7 перенаправляются на 0x20 - 0x28 */
    outb    %al, $0x21
    movb    $0x28, %al /* IRQ0 - IRQ7 перенаправляются на 0x28 - 0x28 + 8 */
/* далее идет запись в ICW3-4, значения взяты из справочника */
    outb    %al, $0xa1
    movb    $0x04, %al
    outb    %al, $0x21
    movb    $0x02, %al
    outb    %al, $0xa1
    movb    $0x0d, %al
    outb    %al, $0x21
    movb    $0x09, %al
    outb    %al, $0xa1

Цитата(JAPH @  5.2.2007,  00:02 Найти цитируемый пост)
так? (Задно проверяйте понимание синтаксиса)

ну так, только опять же, зачем так делать?

Это сообщение отредактировал(а) MAKCim - 5.2.2007, 11:22


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
JAPH
Дата 5.2.2007, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: нет
Всего: 23



Ну, как это зачем? Когда прога выйдет из PM, она должна корректно передать управление DOS. А тут по первому прерыванию от таймера INT 20h!

Насчёт #GP при подмене шлюза прерывания на ловушки - судя по тому, что они отличаются друг от друга только разрешением/запретом прерываний во время работы обработчика, не будет.

По поводу стэка - получается, что никто не контролирует, выйдем мы за 512 байт или нет. Вот я и удивился.

По поводу
Цитата(MAKCim @  5.2.2007,  10:55 Найти цитируемый пост)
только не шлюзом задачи, а TSS сегментом

Я читал, что IDT может содержать только шлюзы прерываний, ловушек и задач. А что на самом деле?


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
MAKCim
Дата 5.2.2007, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



Цитата(JAPH @  5.2.2007,  13:12 Найти цитируемый пост)
Ну, как это зачем? Когда прога выйдет из PM, она должна корректно передать управление DOS. А тут по первому прерыванию от таймера INT 20h!

а, ну если в этом смысле, тогда да
Цитата(JAPH @  5.2.2007,  13:12 Найти цитируемый пост)
По поводу стэка - получается, что никто не контролирует, выйдем мы за 512 байт или нет. Вот я и удивился.

ну это же пример, думаю 512 байт вполне достаточно, нет - пожалуйста, делай отдельный дескриптор для стека и пр.
Цитата

Я читал, что IDT может содержать только шлюзы прерываний, ловушек и задач. А что на самом деле? 

так оно и есть
просто если тебе надо узнать, произошло исключение или прерывание, то нужно узнать ESP для CPL = 0, а он находится в TSS текущей задачи



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
JAPH
Дата 5.2.2007, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: нет
Всего: 23



Прицепил перепрограммирование контроллера до и после. Теперь проблема такая: после возврата в DOS набрать что-либо в командной строке не удаётся - клавиатура игнорируется. Причём раскомментирование sti и/или комментирование mov al, 20h | out 20h, al исхода не меняет. Чего я недоглядел?
Код

        .486p
sseg    segment stack
        db      0400h dup (?)
sseg    ends
dseg    segment
gdts    db      8 dup (0)
        db      0FFh, 0FFh, 0, 0, 0, 10011010b, 00000000b, 0 ;cseg
        dw      small codeslim
        db      0, 0, 0, 10011010b, 01001111b, 0 ;codes in pm
        db      0FFh, 0FFh, 0, 80h, 0Bh, 10010010b, 01000000b, 0 ;B800
        db      00h, 0FCh, 0, 0, 0, 10010110b, 01000000b, 0 ;sseg in pm
        db      0FFh, 0FFh, 0, 0, 0, 10010010b, 01000000b, 0 ;sseg in rm
        db      067h, 0, 0, 0, 0, 10001001b, 00000000b, 0 ;stss
gdtlim  dw      0037h
gdtad   dd      0
idts    dw      20h dup (small offset here, 10h, 1000111000000000b, 0)
        dw      small offset timer, 10h, 1000111000000000b, 0
        dw      small offset keyb, 10h, 1000111000000000b, 0
idtlim  dw      010Fh
idtad   dd      0
stss    db      68h dup (0)
dseg    ends
codes   segment use32
        assume  cs:codes, ds:dseg
got:    mov     byte ptr fs:[0], '2'
        mov     ecx, 05000000h
@1:     dec     ecx
        jnz     @1
        mov     ax, 20h
        mov     ss, ax
        xor     esp, esp
        push    ax
        pop     ax
        mov     byte ptr fs:[0], '3'
        mov     ecx, 05000000h
@4:     dec     ecx
        jnz     @4
        mov     ax, 30h
        ltr     ax
        mov     al, 15h
        out     20h, al
        out     0A0h, al
        mov     al, 20h
        out     21h, al
        mov     al, 28h
        out     0A1h, al
        mov     al, 04h
        out     21h, al
        mov     al, 02h
        out     0A1h, al
        mov     al, 0Dh
        out     21h, al
        mov     al, 09h
        out     0A1h, al
        mov     al, 0FCh
        out     21h, al
        mov     al, 0FFh
        out     0A1h, al
       ;sti
        mov     ax, 18h
        mov     es, ax
        mov     ecx, 20
        mov     eax, 07200721h
        xor     edi, edi
        cld
    rep stosd
        mov     ecx, 05000000h
@3:     dec     ecx
        jnz     @3
here:   cli
        mov     ax, 28h
        mov     ss, ax
        db      0EAh
        dd      offset back
        dw      8
timer:  nop
keyb:   mov     al, 20h
        out     20h, al
        iretd
codeslim = $ - 1
codes   ends
cseg    segment use16
        assume  cs:cseg, ds:dseg
start:  xor     eax, eax
        mov     ax, 0B800h
        mov     fs, ax
        mov     ax, dseg
        mov     ds, ax
        shl     eax, 4
        mov     gdtad, eax
        xor     eax, eax
        mov     ax, codes
        shl     eax, 4
        mov     word ptr gdts + 12h, ax
        bswap   eax
        mov     byte ptr gdts + 14h, ah
        mov     byte ptr gdts + 17h, al
        xor     eax, eax
        mov     ax, sseg
        shl     eax, 4
        mov     word ptr gdts + 22h, ax
        mov     word ptr gdts + 2Ah, ax
        bswap   eax
        mov     byte ptr gdts + 24h, ah
        mov     byte ptr gdts + 2Ch, ah
        mov     byte ptr gdts + 27h, al
        mov     byte ptr gdts + 2Fh, al
        xor     eax, eax
        mov     ax, dseg
        shl     eax, 4
        add     eax, offset stss
        mov     word ptr gdts + 32h, ax
        bswap   eax
        mov     byte ptr gdts + 34h, ah
        mov     byte ptr gdts + 37h, al
        xor     eax, eax
        mov     ax, cseg
        shl     eax, 4
        mov     word ptr gdts + 0Ah, ax
        bswap   eax
        mov     byte ptr gdts + 0Ch, ah
        mov     byte ptr gdts + 0Fh, al
        mov     eax, gdtad
        add     eax, offset idts
        mov     idtad, eax
        lgdt    fword ptr gdtlim
        lidt    fword ptr idtlim
        in      al, 92h
        or      al, 02h
        out     92h, al
        cli
        in      al, 70h
        or      al, 80h
        out     70h, al
        mov     byte ptr fs:[0], '1'
        mov     ecx, 05000000h
@2:     dec     ecx
        jnz     @2
        mov     eax, cr0
        or      al, 1
        mov     cr0, eax
        db      66h
        db      0EAh
        dd      offset got
        dw      10h
;----------------------------------
idtr    dw      03FFh
        dd      0
back:   mov     byte ptr fs:[0], '4'
        mov     ecx, 05000000h
@5:     dec     ecx
        jnz     @5
        mov     eax, cr0
        and     al, 0FEh
        mov     cr0, eax
        db      0EAh
        dw      $ + 4
        dw      cseg
        lidt    fword ptr cs:idtr
        mov     byte ptr fs:[0], '5'
        mov     ecx, 05000000h
@6:     dec     ecx
        jnz     @6
        mov     ax, cs
        mov     ds, ax
        mov     es, ax
        mov     ax, sseg
        mov     ss, ax
        mov     esp, 00000400h
        push    ax
        pop     ax
        mov     al, 15h
        out     20h, al
        out     0A0h, al
        mov     al, 08h
        out     21h, al
        mov     al, 70h
        out     0A1h, al
        mov     al, 04h
        out     21h, al
        mov     al, 02h
        out     0A1h, al
        mov     al, 0Dh
        out     21h, al
        mov     al, 09h
        out     0A1h, al
        mov     al, 00h
        out     21h, al
        out     0A1h, al
        mov     byte ptr fs:[0], '6'
        mov     ecx, 05000000h
@7:     dec     ecx
        jnz     @7
        in      al, 92h
        and     al, 0FDh
        out     92h, al
        in      al, 70h
        and     al, 7Fh
        out     70h, al
        sti
        mov     ax, 4C00h
        int     21h
cseglim = $ - 1
cseg    ends
        end     start



--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
MAKCim
Дата 5.2.2007, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



Цитата(JAPH @  5.2.2007,  14:09 Найти цитируемый пост)
Чего я недоглядел?

так ты sti делаешь только перед int 21h, а в here: делаешь cli


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
JAPH
Дата 5.2.2007, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: нет
Всего: 23



А что тут такого? Раскомментировать строку 59? Не поможет. Так как надо?
Почему DOS после отрабатывания программы не воспринимает клавиатуру? Куда делся обработчик INT 09h?
Если убрать перепрограммирование, всё в порядке.

Это сообщение отредактировал(а) JAPH - 5.2.2007, 19:03


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
MAKCim
Дата 5.2.2007, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



Цитата(JAPH @  5.2.2007,  18:59 Найти цитируемый пост)
А что тут такого? Раскомментировать строку 59? Не поможет. Так как надо?

причем тут строка 59
насколько я понял
переход в реальный режим тут
Код

here:   cli
        mov     ax, 28h
        mov     ss, ax
        db      0EAh
        dd      offset back
        dw      8

далее в back (читай комментарии)
Код

back:   mov     byte ptr fs:[0], '4'
        mov     ecx, 05000000h
@5:     dec     ecx
        jnz     @5
        mov     eax, cr0
        and     al, 0FEh
        mov     cr0, eax  ; собственно переход в real-mode
        db      0EAh
        dw      $ + 4
        dw      cseg
        lidt    fword ptr cs:idtr  ; зачем?
        mov     byte ptr fs:[0], '5'
        mov     ecx, 05000000h
@6:     dec     ecx
        jnz     @6
        mov     ax, cs
        mov     ds, ax
        mov     es, ax
        mov     ax, sseg
        mov     ss, ax
        mov     esp, 00000400h
        push    ax
        pop     ax
; тут возврат на 08h и 70h
        mov     al, 15h
        out     20h, al
        out     0A0h, al
        mov     al, 08h
        out     21h, al
        mov     al, 70h
        out     0A1h, al
        mov     al, 04h
        out     21h, al
        mov     al, 02h
        out     0A1h, al
        mov     al, 0Dh
        out     21h, al
        mov     al, 09h
        out     0A1h, al
        mov     al, 00h
        out     21h, al
        out     0A1h, al
        mov     byte ptr fs:[0], '6'
        mov     ecx, 05000000h
@7:     dec     ecx
        jnz     @7
        in      al, 92h
        and     al, 0FDh
        out     92h, al
        in      al, 70h
        and     al, 7Fh
        out     70h, al
        sti ; а вот тут только разрешаем прерывания, пред самым выходом
        mov     ax, 4C00h
        int     21h




--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
JAPH
Дата 5.2.2007, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: нет
Всего: 23



Если оставить только конечное перепрограммирование, та же проблема.

Что касается последнего lidt, он должен загрузить в IDTR его значение в реальном режиме, то есть базу 0 и предел 03FFh. Я так понял, тут то же, что заставляет прописывать в CS и SS нечто с лимитом 0FFFFh для выхода из PM. (Я сначала забыл про это - заработал перезагрузку)

И всё же, чем мешает cli? Это не должно влиять на контроллер. Разрешить прерывания я решаюсь только после закрытия A20 и разрешения маскируемых прерываний. Конечно, можно перенести перепрограммирование поближе к sti, но что это изменит?


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
MAKCim
Дата 5.2.2007, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: нет
Всего: 207



Цитата

Что касается последнего lidt, он должен загрузить в IDTR его значение в реальном режиме, то есть базу 0 и предел 03FFh.

в реальном режиме процессор регистр LDTR вообще не смотрит а обращается напрямую к таблице векторов прерываний по 0000:0000h, такова логика
Цитата

И всё же, чем мешает cli? Это не должно влиять на контроллер

Нет, конечно на контроллер это не влияет
однако, сделав cli, процессор не реагирует на сообщения контроллера о возникновении прерываний => процессор не начинает их обработку

Это сообщение отредактировал(а) MAKCim - 5.2.2007, 20:37


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
JAPH
Дата 5.2.2007, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: нет
Всего: 23



Ну дык перед выходом из программы происходит sti. По идее, ОС уже должна реагировать на прерывания?


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для Windows/DOS"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для Windows/Dos | Следующая тема »


 




[ Время генерации скрипта: 0.0702 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.