OSDev http://osdev.su/ |
|
Страницы http://osdev.su/viewtopic.php?f=6&t=1072 |
Страница 2 из 2 |
Автор: | pavia [ 03 апр 2015, 21:33 ] |
Заголовок сообщения: | Re: Страницы |
stlw писал(а): pavia писал(а): Наконец-то закончил дебажить. Судя по всему в борще invlpg не работает. Пришлось заменить на передёргивание cr3 Слишком серьезное заявление. Без invlpg ни один современный OS не поднимется. Скорее всего что-то ты не так делаешь. Станислав Я прекрасно знаю что современные ОС работают на invlpg. Поэтому и не понимаю как это возможно. Но я специально ставил invlpg перед обнулением памяти, но это не помогало. У меня есть код, который вызывается при изменении страницы. Код: procedure INVLPG(_addr:TAddrVirtual); begin asm INVLPG [_addr] end; end; Как только заменил на Код: procedure INVLPG(_addr:TAddrVirtual); begin asm MOV EAX, CR3 MOV CR3, EAX end; end; Всё заработало. |
Автор: | stlw [ 03 апр 2015, 22:34 ] |
Заголовок сообщения: | Re: Страницы |
Проверь как следует что видно на месте твоего INVLPG в дебаггере Bochs. Я точно не знаю как правильно пишется inline asm на ... это Pascal? Самая распространенная ошибка, что вместо invalpg ADDR гедериться invlpg *ADDR, то есть в качестве адреса берется значение по адресу ADDR. |
Автор: | Himik [ 03 апр 2015, 22:40 ] |
Заголовок сообщения: | Re: Страницы |
Если в INVLPG [_addr] скобки означают косвенную адресацию, то работать не будет, т.к. будет адресоваться сама переменная _addr. Делай MOV EAX,[_addr]; INVLPG EAX |
Автор: | pavia [ 04 апр 2015, 00:03 ] |
Заголовок сообщения: | Re: Страницы |
Похоже что опкод неверно генерируется. Прописал руками вроде нормально. Но надо будет тест написать. Код: procedure INVLPG(_addr:TAddrVirtual); begin asm mov EAX,[_addr] DB 0Fh, 01h, 038h;//INVLPG [EAX] end; end; Код: procedure INVLPG(const _addr); begin asm INVLPG [_addr] end; end; Наверно второй вариант будет работать тоже только мне первый больше по душе. Там проверка типов есть. |
Автор: | Himik [ 04 апр 2015, 00:22 ] |
Заголовок сообщения: | Re: Страницы |
Если возможно, то в объявлении _addr используй атрибут register, тогда INVLPG [_addr] сработает. Надо ещё смотреть ассемблерный или дизассемблерный код скомпилированного файла, чтобы видеть конечный результат. |
Автор: | dragon [ 04 апр 2015, 17:07 ] |
Заголовок сообщения: | Re: Страницы |
Предполагаю что референсная реализация будет выглядеть как нибудь так (хотя и не уверен: негде проверить, да я и не знаю что за инструкция invlpg): Код: procedure InvLPG(const Addr: pointer); asm invlpg Addr; end; Полезно было бы иметь такую, чтобы можно было быстро вставить в свой проект. В паскале (delphi7) по умолчанию первые 3 параметра передаются через регистры, а отдельно указать кто пойдёт через регистр - нельзя. |
Автор: | Freeman [ 04 апр 2015, 18:11 ] |
Заголовок сообщения: | Re: Страницы |
dragon писал(а): Предполагаю что референсная реализация будет выглядеть как нибудь так Да, именно так. Набросал два варианта (Delphi 6): Код: procedure InvLPG(Page: Pointer); asm INVLPG [Page] end; procedure ConstInvLPG(const Page); asm INVLPG [Page] end; Без квадратных скобок у [Page] Delphi не компилит, ругается на несовместимость команды и операндов. DCU32Int выдает одинаковые опкоды для обоих вариантов: Код: procedure InvLPG (Page: System.Pointer); begin // -- Line #308 -- 0: ..8 [0F 01 38 | INVLPG WORD PTR [EAX] // -- Line #309 -- 3: Γ |C3 | RET NEAR end; procedure ConstInvLPG (var Page: void); begin // -- Line #313 -- 0: ..8 [0F 01 38 | INVLPG WORD PTR [EAX] // -- Line #314 -- 3: Γ |C3 | RET NEAR end; Коды совпадают с теми, что выдает FASM. В Delphi, стало быть, всё реализовано верно. Ну и DCU32Int хороший инструмент, советую. |
Автор: | kailot2 [ 07 май 2015, 19:54 ] |
Заголовок сообщения: | Re: Страницы |
Тоже долго мучался с invlpg, Си и борщом. В итоге пришел к этому. Если еще актуально. Код: asm volatile (
"movl addr,%eax\n\t" "invlpg (%eax)\n\t" ); |
Страница 2 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |