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/