Консультация № 69096
30.12.2006, 01:56
0.00 руб.
0 1 1
Здравствуйте уважаемые эксперты. Помогите написать небольшую программу переводящую процессор из реального режима в защищенный. Привожу код, программа загружается со второго сектора флоппи, непосредственно из биоса и загружает ее программа неходящааяся на первом секторе, и комп перегружается.
Вопросов несколько - при переходе в защищенный режим после команд
mov EAX,cr0;
or eax,1;
mov cr0,eax;
объясните как процессор переходит на следующую команду, ведь если он уже работает в защищенном режиме значит он обращается к памяти через gdt_null, так как cs = 0, что и вызывает ошибку. По моему тоже самое должно происходить при переходе в реальный режим, только без ошибки. Просто вычитал этот код в одной книге и стало интересно. Подскажите что вообще не правильно сделал и как правильно перевести проц в защищенный режим?

Приложение:
code: section .text global startbits 16org 7c00hstart: jmp real_startreal_data: STRUC dscrlimit: RESW 1base_1: RESW 1base_m: RESB 1attr_1: RESB 1attr_2: RESB 1base_h: RESB 1 ENDSTRUC;###############################################################gdt_null: ISTRUC dscrAT limit, DW 0AT base_1, DW 0AT base_m, DB 0AT attr_1, DB 0AT attr_2, DB 0AT base_h, DB 0 IENDgdt_code: ISTRUC dscr ;cs = 1000bAT limit, DW 0xFFFFAT base_1, DW 0 AT base_m, DB 0AT attr_1, DB 0x98AT attr_2, DB 0x8FAT base_h, DB 0 IENDgdt_data: ISTRUC dscr ;ds = 10000bAT limit, DW 0xFFFFAT base_1, DW 0 AT base_m, DB 0AT attr_1, DB 0x92AT attr_2, DB 0x8FAT base_h, DB 0 IENDgdt_video: ISTRUC dscr ;fs = 11000bAT limit, DW 4095AT base_1, DW 0x8000AT base_m, DB 0x0BAT attr_1, DB 0x92AT attr_2, DB 0AT base_h, DB 00 IENDgdt_stack: ISTRUC dscr ;ss = 100000bAT limit, DW 0xFFFFAT base_1, DW 0AT base_m, DB 0AT attr_1, DB 0x92AT attr_2, DB 0x8FAT base_h, DB 0 IENDgdtaddr DD 0x0007C003gdtlim DW 39enddata EQU $ - real_datareal_start: lgdt [gdtaddr] cli mov EAX,CR0 or EAX,1 mov CR0,EAXDB 0xEADW continueDW 1000bcontinue EQU $ mov AX,10000b mov DS,AX mov AX,100000b mov SS,AX mov AX,11000b mov FS,AX mov BX,2000 mov AX,0x9F0F mov [FS:BX],AX ;вывод символа mov WORD [gdt_code+limit],0xFFFF mov WORD [gdt_data+limit],0xFFFF mov WORD [gdt_stack+limit],0xFFFF mov WORD [gdt_video+limit],0xFFFF mov AX,10000b mov DS,AX mov AX,11000b mov FS,AXDB 0xEADW goDW 1000bgo EQU $ mov EAX,CR0 and EAX,0xFFFFFFFE mov CR0,EAX stiend_p EQU $ - real_startreal_mode: mov AH,02 mov AL,01 mov BX,7C00h mov CH,0 mov CL,01 mov DH,0 mov DL,80h int 0x13 jmp 0:0x7c00

Обсуждение

Неизвестный
30.12.2006, 02:45
общий
это ответ
Здравствуйте, RIV!

Очень резонный вопрос Ж:-)
Все дело в так называемых теневых регистрах(shadow register). Дело в том что при каждом обращении к памяти, процессор не вычисляет все значения через gdt или ldt как можно было бы подумать(представьте себе накладные расходы такого варианта). Вычисления происходят только при изменения значения сегментных регистров(cs, ds, ss....), а вычесленная информация заностится в теневые регистры.
В них хранится база, лимит и права доступа.

Так что когда вы меняете cr0, то вычисление адреса по прежнему происходит из теневых регистров пока вы не изменяете сегментный регистр.

Отсюда можно сделать два вывода:
1. Вычисление через адреса в реальном режиме все равно проиходит через эти теневые регистры, просто база, лимиты и права соответствуют тому, чему мы привыкли в реальном режиме.

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

Дополнительную информацию можно найти в поисковых системах интернет по запросу "теневые регистры защищенный режим"
Форма ответа