Хм. Написал следующее, файл boot.asm: Code (Text): ; ******************************************************************************* ; Имя: boot ; Описание: Загрузочный сектор ; Автор: Дубровкин Сергей ; Начало: 21.10.2010 - 17:54 ; Завершение: ??.??.???? - ??:?? ; ******************************************************************************* use16 org 0x7C00 ; ******************************************************************************* ; К О Д ; ******************************************************************************* boot__Code16: mov AX,CS mov DS,AX mov ES,AX mov FS,AX mov GS,AX mov AX,boot__Stack16 mov SS,AX mov AX,boot__StackStart16 mov SP,AX call Boot__SaveScreen call Boot__InitScreen mov BL,00000000b call Boot__ClearScreen mov SI,boot__TextTitle mov BL,00001111b mov DH,2 mov DL,32 call Boot__DrawText mov SI,boot__TextDescription mov BL,00001111b mov DH,3 mov DL,27 call Boot__DrawText mov SI,boot__TextKey1 mov BL,00001111b mov DH,10 mov DL,26 call Boot__DrawText mov SI,boot__TextKey2 mov BL,00001111b mov DH,12 mov DL,28 call Boot__DrawText mov SI,boot__TextAutors mov BL,00001111b mov DH,22 mov DL,20 call Boot__DrawText mov SI,boot__TextYear mov BL,00001111b mov DH,23 mov DL,36 call Boot__DrawText call Boot__KeyDown cmp AL,0x00 jz Boot__LabelEnd jmp Boot__LabelContinue Boot__LabelEnd: call Boot__LoadScreen int 0x18 Boot__LabelContinue: mov DH,0x00 mov DL,0x00 call Boot__SetCursorPos mov BL,00010000b call Boot__ClearScreen mov AX,CS mov ES,AX mov AH,0x02 ; Функция mov AL,0x02 ; Количество секторов mov CH,00000000b ; Номер цилиндра mov CL,00000010b ; Номер сектора mov DH,0x00 ; Номер головки mov DL,0x00 ; Номер дисковода mov BX,boot__End int 0x13 jmp boot__End ; ******************************************************************************* ; П Р О Ц Е Д У Р Ы ; ******************************************************************************* ; ------------------------------------------------------------------------------{ ; Название: BootKeyDown() ; Описание: Нажатие клавиши ; Вход: Нет ; Выход: AL - код ; ------------------------------------------------------------------------------- Boot__KeyDown: Boot__KeyDownRepeat: mov AH,0x00 int 0x16 cmp AH,0x01 jz Boot__KeyDownEscape cmp AH,0x1C jz Boot__KeyDownEnter jmp Boot__KeyDownRepeat Boot__KeyDownEscape: mov AL,0x00 jmp Boot__KeyDownEnd Boot__KeyDownEnter: mov AL,0x01 Boot__KeyDownEnd: ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootSaveScreen() ; Описание: Сохранение видео-режима ; Вход: Нет ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__SaveScreen: mov AH,0x0F int 0x10 mov [boot__ScreenMode],AL mov [boot__Symbols],AH mov [boot__PageNumber],BH ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootLoadScreen() ; Описание: Загрузка видео-режима ; Вход: Нет ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__LoadScreen: mov AH,0x00 mov AL,[boot__ScreenMode] int 0x10 mov AL,[boot__PageNumber] call Boot__SetScreenPage ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootInitScreen() ; Описание: Инициализация видео-режима ; Вход: Нет ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__InitScreen: mov AH,0x00 mov AL,0x03 int 0x10 ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootClearScreen() ; Описание: Очистка экрана ; Вход: BL - цвет ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__ClearScreen: mov AH,0x09 mov AL,' ' mov BH,0x00 mov CX,2000 int 0x10 ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootSetScreenPage() ; Описание: Установка страницы ; Вход: AL - номер страница ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__SetScreenPage: mov AH,0x05 int 0x10 ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootSetCursorPos() ; Описание: Установка положения курсора ; Вход: DH - номер строки ; DL - номер столбца ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__SetCursorPos: mov AH,0x02 mov BH,0x00 int 0x10 ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootDrawText() ; Описание: Вывод текста ; Вход: BL - атрибуты текста ; DH - номер строки ; DL - номер столбца ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__DrawText: mov CX,1 Boot__DrawTextLoop: call Boot__SetCursorPos mov AH,0x09 mov BH,0x00 lodsb cmp AL,0x00 jz Boot__DrawTextExit int 0x10 inc DL jmp Boot__DrawTextLoop Boot__DrawTextExit: ret ; ------------------------------------------------------------------------------} ; ******************************************************************************* ; Д А Н Н Ы Е ; ******************************************************************************* boot__Data16: boot__ScreenMode db 0x00 boot__Symbols db 0x00 boot__PageNumber db 0x00 boot__TextTitle db "Hello in BOS!",0x00 boot__TextDescription db "(Basic Operation System)",0x00 boot__TextKey1 db "Press 'Enter' for continue.",0x00 boot__TextKey2 db "Press 'Escape' for exit.",0x00 boot__TextAutors db "Dubrovkin Sergei & Konstantin Dement'ev",0x00 boot__TextYear db "(2010)",0x00 ; ******************************************************************************* ; С Т Е К ; ******************************************************************************* boot__Stack16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 boot__StackStart16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; ******************************************************************************* ; Д О П О Л Н И Т Е Л Ь Н О ; ******************************************************************************* ; Заполнение до 510 байт rb 510-($-$$) ; Метка загрузочного сектора db 0x55,0xAA boot__End: include "translation_pmode.asm" ; Дубровкин Сергей © 2010 А вот файл translation_pmode.asm: Code (Text): ; Имя: translation_pmode ; Описание: Перевод процессора в защищённый режим ; Автор: Дубровкин Сергей ; Начало: 23.10.2010 - 11:48 ; Завершение: ??.??.???? - ??:?? ; ******************************************************************************* use16 ; ******************************************************************************* ; К О Д ; ******************************************************************************* translation_pmode__Code16: cli in AL,0x92 or AL,2 out 0x92,AL lgdt [translation_pmode__GDTR] mov EAX,CR0 or AL,1 mov CR0,EAX jmp 0000000000001000b:translation_pmode__Code32 ; Index(13), TI(1), RPL(2) translation_pmode__Code32: sti hlt ; ******************************************************************************* ; Д А Н Н Ы Е ; ******************************************************************************* translation_pmode__Data16: translation_pmode__GDTR: dw 8*5-1 dq translation_pmode__gdt translation_pmode__gdt: translation_pmode__descriptor0: db 00000000b ; Base Address(8) db 00000000b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 0000000000000000b ; Segment Limit(16) translation_pmode__descriptor1: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 10011000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) translation_pmode__descriptor2: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 10010010b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) translation_pmode__descriptor3: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 11111000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) translation_pmode__descriptor4: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 11110010b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) translation_pmode__Data32: ; ******************************************************************************* ; С Т Е К ; ******************************************************************************* translation_pmode__Stack16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__StackStart16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__Stack32: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__StackStart32: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 rb (1024*1024*1)-1-($-$$) db 0x00 И что-то я не так написал. При нажатии на кнопку Enter у меня должен осуществляться переход в защищённый режим, а вместе этого у меня компьютер как-будто сбрасывается. Что я не так сделал?
Наверное, потому что после перехода в PM прерывания разрешили, а таблицу прерываний не настроили? Не?
KIV Вот у меня так: Code (Text): translation_pmode__descriptor1: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 10011000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) А как надо, так что ли: Code (Text): translation_pmode__descriptor1: dw 1111111111111111b ; Segment Limit(16) dw 0000000000000000b ; Base Address(16) db 00000000b ; Base Address(8) db 10011000b ; P(1), DPL(2), S(1), Type(4) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; Base Address(8) Или у меня просто в каждом поле биты были задом наперёд?
И сегменты вроде бы правильно настроил: Code (Text): mov AX,0000000000010000b mov DS,AX mov ES,AX mov FS,AX mov GS,AX mov SS,AX mov EAX,translation_pmode__StackStart32 mov ESP,EAX
KIV Спасибо большое! Теперь всё работает: Code (Text): ; Имя: translation_pmode ; Описание: Перевод процессора в защищённый режим ; Автор: Дубровкин Сергей ; Начало: 23.10.2010 - 11:48 ; Завершение: ??.??.???? - ??:?? ; ******************************************************************************* use16 ; ******************************************************************************* ; К О Д ; ******************************************************************************* translation_pmode__Code16: cli in AL,0x92 or AL,2 out 0x92,AL lgdt [translation_pmode__GDTR] mov EAX,CR0 or AL,1 mov CR0,EAX jmp 0000000000001000b:translation_pmode__Code32 ; Index(13), TI(1), RPL(2) translation_pmode__Code32: use32 mov AX,0000000000010000b mov DS,AX mov ES,AX mov FS,AX mov GS,AX mov SS,AX mov EAX,translation_pmode__StackStart32 mov ESP,EAX hlt ; ******************************************************************************* ; Д А Н Н Ы Е ; ******************************************************************************* translation_pmode__Data16: translation_pmode__GDTR: dw 8*3-1 dq translation_pmode__gdt translation_pmode__gdt: translation_pmode__descriptor0: ;db 00000000b ; Base Address(8) ;db 00000000b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ;db 00000000b ; P(1), DPL(2), S(1), Type(4) ;db 00000000b ; Base Address(8) ;dw 0000000000000000b ; Base Address(16) ;dw 0000000000000000b ; Segment Limit(16) dw 0000000000000000b ; Segment Limit(16) dw 0000000000000000b ; Base Address(16) db 00000000b ; Base Address(8) db 00000000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; Base Address(8) translation_pmode__descriptor1: ;db 00000000b ; Base Address(8) ;db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ;db 10011000b ; P(1), DPL(2), S(1), Type(4) ;db 00000000b ; Base Address(8) ;dw 0000000000000000b ; Base Address(16) ;dw 1111111111111111b ; Segment Limit(16) dw 1111111111111111b ; Segment Limit(16) dw 0000000000000000b ; Base Address(16) db 00000000b ; Base Address(8) db 10011000b ; P(1), DPL(2), S(1), Type(4) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; Base Address(8) translation_pmode__descriptor2: ;db 00000000b ; Base Address(8) ;db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ;db 10010010b ; P(1), DPL(2), S(1), Type(4) ;db 00000000b ; Base Address(8) ;dw 0000000000000000b ; Base Address(16) ;dw 1111111111111111b ; Segment Limit(16) dw 1111111111111111b ; Segment Limit(16) dw 0000000000000000b ; Base Address(16) db 00000000b ; Base Address(8) db 10010010b ; P(1), DPL(2), S(1), Type(4) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; Base Address(8) ;translation_pmode__descriptor3: ; db 00000000b ; Base Address(8) ; db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ; db 11111000b ; P(1), DPL(2), S(1), Type(4) ; db 00000000b ; Base Address(8) ; dw 0000000000000000b ; Base Address(16) ; dw 1111111111111111b ; Segment Limit(16) ;translation_pmode__descriptor4: ; db 00000000b ; Base Address(8) ; db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ; db 11110010b ; P(1), DPL(2), S(1), Type(4) ; db 00000000b ; Base Address(8) ; dw 0000000000000000b ; Base Address(16) ; dw 1111111111111111b ; Segment Limit(16) translation_pmode__Data32: ; ******************************************************************************* ; С Т Е К ; ******************************************************************************* translation_pmode__Stack16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__StackStart16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__Stack32: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__StackStart32: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 rb (1024*1024*1)-1-($-$$) db 0x00
s3dworld, читайте "Микропроцессоры Intel: 8086/8088, 80186/80188, 80286, 80386, 80486, Pentium, Pentium Pro Processor, Pentium 4. Архитектура, программирование и интерфейсы" Барри Брэя, параллельно c этим изучая английский. После английского читайте Intel Manuals. Если до мануалов прочтете и поймете Брэя, то разберетесь с мануалами малой кровью. В любом случае, продолжать сыпать элементарными вопросами, несмотря на неоднократные советы-предупреждения от опытных и умных людей и не имея за плечами не то что базы, а даже минимума -- значит зарекомендовать себя как человека недалекого.
Всем доброго утра! Моя задача: разобраться в работе процессора и написать операционную систему для длинного режима (L-Mode) работы процессора. Но прежде чем переходить к длинному режиму (L-Mode), следует разобраться в защищённом режиме (P-Mode) и в естественное в режиме реальных адресов (R-Mode). С режимом реальных адресов (R-Mode) я разобрался. Теперь меня мучают вопросы, связанные с оперативной памятью (ОЗУ) и со страничной организацией памяти. Пока не рассматриваю длинный режим (L-Mode) работы процессора, так как не разобрался ещё в защищённом режиме (P-Mode) - то есть пока у меня адресная память имеет предел в 4 ГБ. Так вот, под все эти 4 ГБ под оперативную память (ОЗУ) отводится только определённая часть адресов (эта часть большая, по сравнению с другими). Слышал я что через функции BIOS можно определить какие диапазоны адресов доступны для оперативной памяти (ОЗУ). Но вот что меня мучает: если через BIOS мы можем определить, то это только в режиме реальных адресов (R-Mode) или в режиме совместимости (V-Mode). А как же определить диапазон адресов для оперативной памяти (ОЗУ) на 4 ГБ адресном пространстве? А на 16777216 ТБ адресном пространстве? И как вообще дело обстоит со страничной адресацией, ведь тут же нужно учитывать адреса, отведённые под оперативную память (ОЗУ)? Ведь глупо просто взять и заполнить все странички (одна страничка будет у меня на 4 МБ) в одноуровневой таблице из 1024 элементов, описывающих всё адресное пространство? А то ведь тогда страничка будет обращаться не к оперативной памяти (ОЗУ), а к памяти какого-нибудь устройства. Так ведь? Что я хочу понять, так это алгоритм как делать. Нужно странички описывать только лишь на адреса, отведённые для оперативной памяти (ОЗУ). Так ведь? Это я имею в виду для программ пользователя. А для программ операционной системы (ОС) можно составить странички для видеопамяти и прочих устройств. Всё так? И потом странички прикладных программ (программ пользователя) выгружать и подгружать. А странички с программами операционной системы (ОС) и памяти устройств - постоянно держать в памяти. Это тут мои доводы, вариантов кучу. Хочу услышать Ваше мнение.
s3dworld На осдевовской вике я в своё время написал, как определять диапазоны памяти. Всё необходимое там сказано. А тем способом, что делаете Вы (и подавляющая часть других осеписателей) невозможно: там очень много различных нюансов, сложностей и т.п., так что написать её с наскока, без тщательного предварительного проектирования, не сможет даже высококвалифицированный программист, собаку съевший на системном программировании (максимум, что он сможет сделать без проекта, -- это выдать систему типа MS DOS или нечто подобное -- работающее, но примитивное).
SII Не эта ли статья? http://ru.osdev.wikia.com/wiki/Определение_объёма_памяти Вот я начал составлять таблицу прерываний: Code (Text): translation_pmode__Data32: translation_pmode__IDTR: dw 8*18-1 dq translation_pmode__idt translation_pmode__idt: translation_pmode__vector0: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector1: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector2: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector3: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector4: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector5: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector6: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector7: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector8: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector9: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector10: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector11: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector12: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector13: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector14: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector15: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector16: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) translation_pmode__vector17: dw 0000000000000000b ; Смещение(16) dw 1000111100000000b ; P(1), DPL(2), 0(1), D(1), 111(3), 000(3), NULL(5) dw 0000000000001000b ; Селектор сегмента(16): Index(13), TI(1), RPL(2) dw 0000000000000000b ; Смещение(16) Это получается что в GDT я могу для каждого прерывания отдельный дескриптор описать (через смещение на нужную процедуру обращаться), могу несколько прерываний в один дескриптор объединить и могу все в один. Да?
Это всё ладно, разберусь. Вот меня мучает страничная адресация памяти. Физический адрес формируется из 32 битного значения линейного значения: 10 бит указывают на каталог таблиц + 10 бит указывают на каталог страниц + 12 бит указывают на смещение (максимальное 4 КБ). Всё это показано на рисунке: Но как обращаться к странице, где хранить это 32-битное значение? Нужен дли для этого сегментный регистр (правда он же 16-битный). Вот это я не понимаю. Или же достаточно загрузить значение в регистр общего назначения и потом его использовать: Code (Text): ; 1-ая таблица, 3-яя страница, 0-ое смещение mov EAX,00000000010000000011000000000000b ; Таблица(10), Страница(10), Смещение(12) mov [EAX],0xFFFFFFFF Но ведь при адресации обязательно используется сегментный регистр по умолчанию (если нет переопределения сегментного регистра). Вот я и не понимаю где и как нужно обращаться к определённой страничке. Всё это было описано для 4 КБ страничек. А я хочу использовать странички по 4 МБ, то есть таблица будет одноуровневой. И как тогда идёт обращение к страничке? Пускай те же 32 бита. Из них 10 бит используется для определения индекса странички из таблицы, но остальные 22 для чего? Смещение в 4 МБ можно описать через 22 бита. Неужели всё так просто? Но всё же, сегменты, странички. Вот я и запутался. Где указывать какую страничку я хочу выбрать? Есть у меня предположение, что в в сегментном регистре указать тупо дескриптор данных на всё адресное пространство (чтобы от процессора отвязаться), а уже в регистре общего назначения (он же на 32 бита) указывать данные именно для таблицы.
Давно я эти режимы изучал. Вроде так. Вы в GDTR загружаете адрес глобальной таблицы описателей, а в LDTR адрес адрес локальной таблицы дескрипторов, в CR3 - адрес каталога страниц. Когда используете адрес например SS:ESP , то проц сам определяет по сегментному регистру какой по счёту описатель в какой таблице использовать, затем извлекает из описателя базу и складывает её со смещением ESP, получается 32-битное значение. s3dworld Но как обращаться к странице, где хранить это 32-битное значение? Это как раз то 32-битное значение про которое вы спрашиваете. Нигде вроде оно не хранится, этот виртуальный адрес как вы видите - временно полученный результат. Затем используя заданный в CR3 каталог страниц, проц преобразует этот виртуальный адрес в физический.
Хорошо, пускай всё так, будет выбираться страница из 32-битного смещения. А вот как дело обстоит с заполнением таблицы прерываний IDT. В качестве её элементов выступают дескрипторы прерываний, ловушек и задач. Они имеют указатель на сегмент (хорошо, таким образом я могу всё слить на один единственный сегмент кода во всю адресную память), и задают 32-битное смещение. Именно это 32-битное смещение и будет определять страницу и смещение в ней?
s3dworld Нет не это 32-битное смещение. Когда вы вызовете прерывание, по номеру будет найден соответствующий дескриптор1 в IDT. В этом дескрипторе1 будет информация Селектор:Cмещение - для соответствующего обработчика прерывания. Затем проц полезет в GDT или LDT(в зависимости от селектора), чтоб найти дескриптор2 соответствующий селектору. База взятая из дескриптора2 сложится со смещением - этот виртуальный адрес и будет определять страницу и смещение в ней. Вот настолько сложен реальный мир.
Nafanya Но если база дескриптора, на который указывает сегментный регистр (селектор дескриптора), равна 0x00000000, тогда будет так, как я и описал - 32-битный регистр и будет определять страничку и смещение в ней. Правильно?