Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Защищенный режим

4.2K
07 мая 2004 года
UnseriousSam
15 / / 26.10.2003
Ошибка в программе следующая: при выходе из задачи по команде iret вызывается исключение общей защиты (при выполнении самой команды iret).
Так вот, не могу найти ошибку. Когда такое может происходить?
Программа из учебника Рудакова и Финогенова №70_1.
Команду, вызывающую исключение, пометил символами =>, чтоб было легче найти :)

.586P

;Структура для описания дескрипторов сегментов
descr struc
lim dw 0 ;Граница сегмента (биты 0...15)
base_l dw 0 ;База сегмента (биты 0...15)
base_m db 0 ;База сегмента (биты 16...23)
attr_1 db 0 ;Байт атрибутов 1
attr_2 db 0 ;Граница (биты 16...19) и атрибуты 2
base_h db 0 ;База (биты 24...31)
descr ends

;Структура для описания шлюза ловушек
trap struc
offs_l dw 0 ;Смещение обработчика (биты 0...15)
sel dw 16 ;Селектор сегмента команд
cntr db 0 ;Не используется
dtype db 8Fh ;Тип шлюза - ловушка 80386 и выше
offs_h dw 0 ;Смещение обработчика (биты 16...31)
trap ends

;Сегмент данных
data segment use16

;Таблица глобальных дескрипторов GDT
gdt_null descr <0, 0, 0, 0, 0, 0>
gdt_data descr <data_size-1, 0, 0, 92h, 0, 0>
gdt_code descr <code_size-1, 0, 0, 98h, 0, 0>
gdt_stack descr <599, 0h, 0, 92h, 0, 0>
gdt_screen descr <3999, 8000h, 0Bh, 92h, 0, 0>
gdt_text1 descr <text1_size-1, 0, 0, 9Ah, 0, 0>
gdt_text2 descr <text2_size-1, 0, 0, 9Ah, 0, 0>
gdt_tss0 descr <103, 0, 0, 89h, 0, 0>
gdt_tss1 descr <103, 0, 0, 89h, 0, 0>
gdt_tss2 descr <103, 0, 0, 89h, 0, 0>

;Размер GDT
gdt_size=$-gdt_null

;Начало таблицы дескрипторов исключений
idt label word

;Таблица дескрипторов исключений
trap 10 dup (<dummy>)
trap <exc10>
trap <exc11>
trap <exc12>
trap <exc13>
trap 18 dup (<dummy>)

;Размер таблицы дескрипторов исключений
idt_size=$-idt

;Псевдодескриптор для команды lgdt
pdescr df 0

;Шаблон диагностической строки
string db '**** ****-**** ****-**** ****'

;Длина строки
len=$-string

;TSS нулевой задачи
tss0 dw 52 dup (0)

;TSS первой задачи
tss1 dw 52 dup (0)

;TSS второй задачи
tss2 dw 52 dup (0)

task1_offs dw 0
task1_sel dw 64
task2_offs dw 0
task2_sel dw 72

;Размер сегмента данных
data_size=$-data

data ends

;Сегмент кода
text segment use16
assume cs:text, ds:data

;Подпрограмма преобразования слова
;При вызове преобразумое число в ax, ds:si = адрес поля для результата
wrd_asc proc

pusha
mov bx, 0F000h
mov dl, 12
mov cx, 4
cccc:
push cx
push ax
and ax, bx
mov cl, dl
shr ax, cl
call bin_asc
mov byte ptr [si], al
inc si
pop ax
shr bx, 4
sub dl, 4
pop cx
loop cccc
popa
ret

wrd_asc endp

;Подпрограмма преобразования 16-ричной цифры
;Преобразуемая четверка битов в младшей половине al, результат в al
bin_asc proc

cmp al, 9
ja lettr
add al, 30h
jmp ok
lettr:
add al, 37h
ok:
ret

bin_asc endp

;Обработчик исключения 10
exc10 proc

mov ax, 8
mov ds, ax
pop eax
pop eax
mov si, offset string+5
call wrd_asc
mov ax, 10
jmp home

exc10 endp

;Обработчик исключения 11
exc11 proc

mov ax, 8
mov ds, ax
pop eax
pop eax
mov si, offset string+5
call wrd_asc
mov ax, 11
jmp home

exc11 endp

;Обработчик исключения 12
exc12 proc

mov ax, 8
mov ds, ax
pop eax
pop eax
mov si, offset string+5
call wrd_asc
mov ax, 12
jmp home

exc12 endp

;Обработчик исключения 13
exc13 proc

mov ax, 8
mov ds, ax
pop eax
pop eax
mov si, offset string+5
call wrd_asc
mov ax, 13
jmp home

exc13 endp

;Обработчик остальных исключений
dummy proc

mov ax, 8
mov ds, ax
mov ax, 5555h
jmp home

dummy endp

;Главная функция
main proc

;Загружаем в ds сегментный адрес сегмента данных
xor eax, eax
mov ax, data
mov ds, ax

;Вычислим и загрузим в GDT линейный адрес сегмента данных
shl eax, 4
mov ebp, eax
mov bx, offset gdt_data
mov [bx].base_l, ax
shr eax, 16
mov [bx].base_m, al

;Вычислим и загрузим в GDT линейный адрес сегмента команд text
xor eax, eax
mov ax, cs
shl eax, 4
mov bx, offset gdt_code
mov [bx].base_l, ax
shr eax, 16
mov [bx].base_m, al

;Вычислим и загрузим в GDT линейный адрес сегмента команд text1
xor eax, eax
mov ax, text1
shl eax, 4
mov bx, offset gdt_text1
mov [bx].base_l, ax
shr eax, 16
mov [bx].base_m, al

;Вычислим и загрузим в GDT линейный адрес сегмента команд text2
xor eax, eax
mov ax, text2
shl eax, 4
mov bx, offset gdt_text2
mov [bx].base_l, ax
shr eax, 16
mov [bx].base_m, al

;Вычислим и загрузим в GDT линейный адрес сегмента стека
xor eax, eax
mov ax, ss
shl eax, 4
mov bx, offset gdt_stack
mov [bx].base_l, ax
shr eax, 16
mov [bx].base_m, al

;Вычислим и загрузим в GDT линейный адрес TSS0
mov eax, ebp
add ax, offset tss0
mov bx, offset gdt_tss0
mov [bx].base_l, ax
shr eax, 16
mov [bx].base_m, al

;Вычислим и загрузим в GDT линейный адрес TSS1
mov eax, ebp
add ax, offset tss1
mov bx, offset gdt_tss1
mov [bx].base_l, ax
shr eax, 16
mov [bx].base_m, al

;Вычислим и загрузим в GDT линейный адрес TSS2
mov eax, ebp
add ax, offset tss2
mov bx, offset gdt_tss2
mov [bx].base_l, ax
shr eax, 16
mov [bx].base_m, al

;Подготовим псевдодескриптор и загрузим регистр GDTR
mov dword ptr pdescr+2, ebp
mov word ptr pdescr, gdt_size-1
lgdt pdescr

cli

;Инициализируем TSS1
mov tss1+4Ch, 40
mov tss1+20h, offset task1
mov tss1+50h, 24
mov tss1+38h, 200
mov tss1+54h, 40
mov tss1+48h, 32

;Инициализируем TSS2
mov tss2+4Ch, 48
mov tss2+20h, offset task2
mov tss2+50h, 24
mov tss2+38h, 400
mov tss2+54h, 48
mov tss2+48h, 32

;Загрузим IDTR
mov word ptr pdescr, idt_size-1
xor eax, eax
mov ax, offset idt
add eax, ebp
mov dword ptr pdescr+2, eax
lidt pdescr

;Переходим в защищенный режим
mov eax, CR0
or eax, 1
mov CR0, eax

;Теперь процессор работает в защищенном режиме

;Загружаем в cs:ip селектор:смещение точки continue
db 0EAh
dw offset continue
dw 16

continue:

;Делаем адресуемыми данные
mov ax, 8
mov ds, ax

;Делаем адресуемыми стек
mov ax, 24
mov ss, ax

;Инициализируем es
mov ax, 32
mov es, ax

;Загрузим регистр задачи TR селектором TSS главной задачи
mov ax, 56
ltr ax

;Выполним переключение задач
call dword ptr task1_offs
call dword ptr task2_offs

mov ax, 0FFFFh
home:
mov si, offset string
call wrd_asc

;Выведем на экран диагностическую строку
mov si, offset string
mov cx, len
mov ah, 74h
mov di, 1280
scrn1:
lodsb
stosw
loop scrn1

cli

;Вернемся в реальный режим
mov gdt_data.lim, 0FFFFh
mov gdt_code.lim, 0FFFFh
mov gdt_stack.lim, 0FFFFh
mov gdt_screen.lim, 0FFFFh
push ds
pop ds
push ss
pop ss
push es
pop es

db 0EAh
dw offset go
dw 16

;Переключим режим процессора
go:
mov eax, CR0
and eax, 0FFFFFFFEh
mov CR0, eax

db 0EAh
dw offset return
dw text

;Теперь процессор работает в реальном режиме

return:

;Восстановим вычислительную среду реального режима
mov ax, data
mov ds, ax
mov ax, stk
mov ss, ax
mov sp, 600

;Восстановим состояние регистра IDTR реального режима
mov ax, 3FFh
mov word ptr pdescr, ax
mov eax, 0
mov dword ptr pdescr+2, eax
lidt pdescr

sti

;Работаем в реальном режиме

mov ah, 4Ch
int 21h

main endp

;Размер сегмента команд
code_size=$-text

text ends

;Сегмент стека
stk segment stack use16
db 600 dup ('^')
stk ends

;Сегмент команд задачи 1
text1 segment use16
assume cs:text1

task1 proc

mov ah, 1Eh
mov si, offset msg1
mov di, 1600
mov cx, 20
c1:
lodsb
stosw
loop c1
=> iret

msg1 db 'Task1 is working....'

task1 endp

;Размер сегмента задачи 1
text1_size=$-task1

text1 ends

;Сегмент команд задачи 2
text2 segment use16
assume cs:text2

task2 proc

mov ah, 1Eh
mov si, offset msg2
mov di, 1630
mov cx, 20
c2:
lodsb
stosw
loop c2
iret

msg2 db 'Task2 is working....'

task2 endp

;Размер сегмента задачи 1
text2_size=$-task2

text2 ends

end main
вавр
4.2K
07 мая 2004 года
UnseriousSam
15 / / 26.10.2003
Вобщем тестил я прогу на Microsoft Virtual PC (см. выше)... После прогона на настоящем железе выскакивает исключение недопустимого TSS на команде, следующей после команды call. Т.е задача возвращает управление, но на следующей команде выскакивает исключение...
Вобщем по-прежнему нужна помощь, а то уже спать хоцца :)
1.8K
10 мая 2004 года
MishaSt
170 / / 11.08.2003
О да! Помню я эту прогу, тоже долга мучался, а потом что-то сделал и заработало вроде...
1.8K
10 мая 2004 года
MishaSt
170 / / 11.08.2003
Пробовал db 66h вставлять перед iret?
4.2K
11 мая 2004 года
UnseriousSam
15 / / 26.10.2003
Да, это я пробовал. Все равно не помогло :(
Если что еще вспомнишь, пиши....уже несколько дней убил.
7.0K
11 мая 2004 года
supertg
7 / / 05.05.2004
Попробуй перед IRET сбросить бит "B" в дескрипторе TSS, на который возвращаешься IRET-ом.
А также посмотри что у тебя в регистре флагов (если не используешь вложенные задачи)
4.2K
11 мая 2004 года
UnseriousSam
15 / / 26.10.2003
В документации написано, что по команде iret переключаться можно только на занятую задачу. Так что бит B должен быть установлен.
1.8K
12 мая 2004 года
Sanya DLR
123 / / 03.03.2004
Цитата:
Originally posted by UnseriousSam
В документации написано, что по команде iret переключаться можно только на занятую задачу. Так что бит B должен быть установлен.


А почему собственно IRET ?
Вроде команда CALL не засовывала в стек флаги, а только селектор и смещение. А IRET пытается снять со стека и регистр флагов тоже.
Может надо использовать простой ret far (код 0CBh) ? Он флагов не снимает.

7.0K
12 мая 2004 года
supertg
7 / / 05.05.2004
Цитата:
Originally posted by UnseriousSam
В документации написано, что по команде iret переключаться можно только на занятую задачу. Так что бит B должен быть установлен.


А ты попробуй.
Знаешь сколько я видел опечаток в документации - видимо не видимо.
Например в одних книгах свободнай TSS путают с шлюзом задачи - 1001 и 0101

4.2K
12 мая 2004 года
UnseriousSam
15 / / 26.10.2003
В защищенном режиме команда iret работает совсем по-другому....при переключении задач.
1.8K
13 мая 2004 года
MishaSt
170 / / 11.08.2003
Цитата:
Originally posted by supertg

А ты попробуй.
Знаешь сколько я видел опечаток в документации - видимо не видимо.
Например в одних книгах свободнай TSS путают с шлюзом задачи - 1001 и 0101


Дык, когда переключаешься на задачу, то задача помечается как занятая, и поэтому и возращаться только на занятую можно, и здесь нет никаких опечаток, а проблемма, как было заявлено, в следующей команде после iret, т.е в переключении на 2-ую задачу.
А вот в чём проблемма хм....

4.2K
13 мая 2004 года
UnseriousSam
15 / / 26.10.2003
Цитата:
Originally posted by MishaSt

Дык, когда переключаешься на задачу, то задача помечается как занятая, и поэтому и возращаться только на занятую можно, и здесь нет никаких опечаток, а проблемма, как было заявлено, в следующей команде после iret, т.е в переключении на 2-ую задачу.
А вот в чём проблемма хм....



Нет, проблема в команде iret. Исключение вылетает в первой задаче именно на команде iret!

1.8K
13 мая 2004 года
Sanya DLR
123 / / 03.03.2004
При переключении проверяются все селекторы: SS, CS, DS, ES, FS и GS !!!
При переключении на TSS1 FS и GS = 0 и переключается без ошибок (видимо проверяется только выход за пределы GDT).
А при возврате в TSS0 ??? А там значение селекторов были сохранены в TSS при выполнении CALL. А откуда они были сохранены ??? Из регистров!!! А как они попали в регистры ??? GS и FS ты явно не загружаешь, значит там значения забитые операционной системой при загрузке программы. А что могла туда засунуть операционная система ??? @$#%$#@ !!!
Вобщем я просто загрузил FS и GS до первого CALL'а и стало работать.
4.2K
13 мая 2004 года
UnseriousSam
15 / / 26.10.2003
Цитата:
Originally posted by Sanya DLR
При переключении проверяются все селекторы: SS, CS, DS, ES, FS и GS !!!
При переключении на TSS1 FS и GS = 0 и переключается без ошибок (видимо проверяется только выход за пределы GDT).
А при возврате в TSS0 ??? А там значение селекторов были сохранены в TSS при выполнении CALL. А откуда они были сохранены ??? Из регистров!!! А как они попали в регистры ??? GS и FS ты явно не загружаешь, значит там значения забитые операционной системой при загрузке программы. А что могла туда засунуть операционная система ??? @$#%$#@ !!!
Вобщем я просто загрузил FS и GS до первого CALL'а и стало работать.



Не мог бы ты выслать мне всю твою работающую программу на [email]Sega_444@freemail.ru[/email]. У меня даже после этого не хочет работать. Может быть ты еще чего правил? И ты запускал на эмуляторе или на настоящем железе?

4.2K
13 мая 2004 года
UnseriousSam
15 / / 26.10.2003
Цитата:
Originally posted by Sanya DLR
При переключении проверяются все селекторы: SS, CS, DS, ES, FS и GS !!!
При переключении на TSS1 FS и GS = 0 и переключается без ошибок (видимо проверяется только выход за пределы GDT).
А при возврате в TSS0 ??? А там значение селекторов были сохранены в TSS при выполнении CALL. А откуда они были сохранены ??? Из регистров!!! А как они попали в регистры ??? GS и FS ты явно не загружаешь, значит там значения забитые операционной системой при загрузке программы. А что могла туда засунуть операционная система ??? @$#%$#@ !!!
Вобщем я просто загрузил FS и GS до первого CALL'а и стало работать.



Вобщем я запустил на чистом железе, заработало :) Наконец-то :)) ОСОБАЯ благодарность Sanya DLR :) При запуске на Microsoft Virtual PC опять выскакивает #GP на команде iret при выходе из первой задачи!!! Вобщем, в итоге, два бага: сегментные регистры и MICROSOFT Virtual PC :)) Люди, может посоветуете нормальный эмулятор :))

1.8K
13 мая 2004 года
MishaSt
170 / / 11.08.2003
Bochs, VmWare
4.2K
13 мая 2004 года
UnseriousSam
15 / / 26.10.2003
Цитата:
Originally posted by MishaSt
Bochs, VmWare



Bochs консольный - неинтересно :) Вобщем на WMWare все заработало.

1.8K
13 мая 2004 года
Sanya DLR
123 / / 03.03.2004
continue:

;Делаем адресуемыми данные
mov ax, 8
mov ds, ax

;Делаем адресуемыми стек
mov ax, 24
mov ss, ax

;Инициализируем es
mov ax, 32
mov es, ax
mov fs,ax
mov gs,ax

на реальном pentium2
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог