Medstrax слушай, почитай внимательно псевдокод там четко написано, когда может генерироваться #GP по селектору по поводу места, где описаны исключения как ты мог заметить, RETF инструкция не описана отдельно RET и RETF объеденены в одну инструкцию RET и описанные исключения - это все исключения, которые могут генерироваться при выполнении этой обобщенной инструкции RET, т. е исключения при выполнении RETF и RET а уже конкретные действия для RET и RETF описываются псевдокодом для каждой инструкции в отдельности и в псевдокоде для RET четко можно заметить, что #GP по селектору не генерируется это раз во-вторых, даже логически понятно, что в этом случае не может быть никакого #GP по селектору хотя бы потому, что SS никто не трогал все условия (в том числе ссответствие селектора лимиту GDT (или LDT)) проверяются только при его загрузке и если он загружен успешно, то нет смысла опять проверять все условия при работе со стеком, если SS не затрагивается
Разговор ни о чем. Надо просто вставить перед ret - mov ax,8 mov ss,ax Если прав я - тогда прога свалится где то после ret'а Одно фигово, проверить на чем валится - нереально, при такой gdt, в к-рой даже сегмент кода неопределен, мы даже исключение поймать не сможем. А в том, что bochs (или любой другой эмулятор) правильно сэмулирует данную ситуацию я сомневаюсь. Особо тонкие моменты они не эмулируют, сталкивался неоднократно З.Ы. А твои рассуждения насчет логики работы ret - это только твои рассуждения, просто в мане этот момент можно трактовать неоднозначно.
Беру свои слова обратно Сейчас проверил на реальной машине. В GDTR можно грузить что угодно, хоть нули, хоть FFFFh и FFFFFFFFh. До тех пор пока сегментные регистры не меняются или не требуется их повторная загрузка - процу фиолетово, все работает как часы. Так что проблема не в этом rei3er, сори только грубить то зачем?
Гм, я тоже не первый год курю, 15 лет асмом занимаюсь. Однако ж вот, приплыл )). Бывает, блин. Тем не менее проблема так и не решена - почему система валится после lgdt? Естесно, что при такой gdt она свалится рано или поздно в любом случае, после первого же исключения или межсегментной передачи управления. Непонятно - почему сразу?
с точки зрения человека - сразу а вот с точки зрения CPU - где-то после Code (Text): in al, 70h and al, 7Fh out 70h, al ; вот этой инструкции sti ret вроде KonstantinBart про "сразу" написал в контексте того, что если, закомментировать lgdt, то все работает
Я в софт айсе отлаживал только чтобы показать значения всех нужных регистров и дампов памяти перед выполнение lgdt.....а само собой что сайс не позволит мне выполнить эту команду, так как я и его как бы грохаю! Я еще тестировал на чистой WinXP.....и там просто комп перегружался...... А на виртуальной машине - вываливался Fault и перезагрузка или выключение ВМ.
Ну я как понял надо настроить сегмент кода, данных и стека, причем: Селектор, загруженный в SS, должен быть селектором сегмента данных, доступного для чтения/записи. Селектор, загруженный в CS, должен быть селектором сегмента кода. Селектор, загруженный в регистры DS, ES, FS, GS, должен быть либо селектором сегмента данных, либо селектором сегмента кода, доступного для чтения, либо нулевым селектором. Я вот добавил в свой код еще и дескрипторы стека и кода... Теперь прога валится на "mov ss, ax"... Code (Text): .386p .model flat public _GetCr0@0 .stack 100h .data GDT db 0 ;0 descr db 0 db 0 db 0 db 0 db 0 db 0 db 0 db 0FFh ;data descr db 0FFh db 0 db 0 db 0 db 10010010b ;92h db 10001111b ;8Fh db 0 db 0FFh ;stack descr db 0FFh db 0 db 0 db 0 db 10010110b ;96h db 10001111b ;8Fh db 0 db 0FFh ;code descr db 0FFh db 0 db 0 db 0 db 10011010b ;9Ah db 0 db 0 gdtr dw $ - GDT - 1 dd ? .code _GetCr0@0: jmp short _main _main: call disable_interrupts call initialize_gdt call enable_interrupts ret disable_interrupts: cli in al, 70h or al, 80h out 70h, al ret initialize_gdt: mov eax, 0 add eax, offset GDT mov dword ptr gdtr + 2, eax ;lgdt fword ptr gdtr mov ax, 16 ;for stack mov ss, ax mov ax, 24 ;for code mov cs, ax mov ax, 8 ;for data mov ds, ax ret enable_interrupts: in al, 70h and al, 7Fh out 70h, al sti ret end _GetCr0@0
ты же lgdt не выполнил поэтому gdtr содержит адрес GDT Windows, а так как по селектору 16 не обязательно будет находится валидный дескриптор сегмента данных, доступный на чтение, от этого и вылет
rei3er дык валится то на "mov ss, ax". или ты учитывая предыдущие посты автора предполагаешь что метод обнаружения ошибки - это комментирование кода до тех пор пока не заработает?
n0name я на код смотрю зачем гадать? KonstantinBart я только сейчас заметил, что у тебя все дескрипторы 16-ти разрядные, так нужно? и кроме того инструкции Code (Text): mov cs, ax нет
KonstantinBart, Юрьев "Assembler" там все оччень подробно расписано. И потренируся хотя бы на виртуальной машине попрыгать из реала в защищеный и обратно.
В рез-те обсуждения темы появилась интересная мысля. Тот факт, что в GDTR можно загружать что угодно и нормально при этом работать (естесно если при этом не будут возникать исключения и загрузка новых селекторов) - можно использовать для антиотладки. Любые трапы - на I/O, на данные или код - будут рушить систему, если, к примеру, забить в GDTR нули. Естесно, что речь идет о ринг0 и, естесно, наш код должен выполняться при закрытых прерываниях. Может, конечно, изобрел велосипед, но лично я с таким приемом не сталкивался. Еще нужно проверить, можно ли воспользоваться этой фишкой, чтобы обломать трапы на I/O с помощью SMI# Не факт, что при выходе из SMM проц не упадет, если GDTR будет кривым
Ну дык о чем и речь. Если наш код выполняется в обычном режиме, не возникает никаких исключений. Если мы пытаемся его дебажить - система рухнет.
При загрузке селектора из LDT все равно идет косвенное обращение к GDT. По идее тоже должно все падать.