Похоже, вы спрашиваете об эмуляции x86, а не о виртуализации. Поскольку современное оборудование x86 поддерживает виртуализацию, при которой ЦП изначально запускает гостевой код и перехватывает только гипервизор для некоторых привилегированных инструкций это то, что обычно означает термин «виртуализация».
Отложенная оценка флага типична. Вместо фактического вычисления всех флагов просто сохраните операнды из последней инструкции, устанавливающей флаги. Затем, если что-то действительно читает флаги, выясните, какими должны быть значения флагов.
Это означает, что на самом деле вам не нужно вычислять PF и AF каждый раз, когда они записываются (почти каждая инструкция), только каждый раз, когда они читаются (в основном только PUSHF или прерывания, едва ли какой-либо код когда-либо считывает PF (за исключением ветвей FP). где это означает NaN)). Вычисление PF после каждой целочисленной инструкции в чистом C является дорогостоящим, поскольку требует подсчета всплывающих окон для младших 8 бит результатов. (И я думаю, что компиляторы C, как правило, не могут распознать этот шаблон и сами используют setp
, не говоря уже о pushf
или lahf
для хранения нескольких флагов, если компилируют эмулятор x86 для запуска на хосте x86. Иногда они распознают подсчет населения. шаблоны и выдают popcnt
инструкции, однако, при нацеливании на хост-процессоры, которые имеют эту функцию (например, -march=nehalem
)).
BOCHS использует этот метод и подробно описывает реализацию в разделе "Отложенные флаги" этого короткого файла PDF: Как работает Bochs изнутри, 2-е издание. Они сохраняют результат, чтобы получить ZF, SF и PF, а также перенос из двух старших битов для CF и OF и из бита 3 для AF. Благодаря этому им никогда не нужно повторять инструкцию для вычисления результатов ее флага.
Есть дополнительные сложности из-за того, что некоторые инструкции не записывают все флаги (т. е. частичное обновление флагов) и, предположительно, из-за таких инструкций, как BSF, которые устанавливают ZF на основе входных, а не выходных данных.
Дополнительная литература:
В этом документе на emulators.com содержится много подробностей о том, как эффективно сохранять достаточное количество состояния восстановить флаги. Он имеет «Флаги ленивой арифметики 2.1 для эмуляции ЦП».
Одним из авторов является Darek Mihocka (долгое время пишет эмуляторы, сейчас, по-видимому, работает в Intel). Он написал много интересного о том, как ускорить работу не-JIT-эмуляторов, и о производительности ЦП в целом, большая часть из которых размещена на его сайте http://www.emulators.com/. Например. эта статья о том, как избежать неправильного предсказания перехода в цикле интерпретатора эмулятора, который отправляет функции, реализующие каждый код операции довольно интересен. Дарек также является соавтором статьи о внутреннем устройстве BOCHS, на которую я ссылался ранее.
Также может быть актуален поиск в Google для оценки отложенного флага: https://silviocesare.wordpress.com/2009/03/08/lazy-eflags-evaluation-and-other-emulator-optimisations/
В последний раз, когда возникла эмуляция x86-подобных флагов, обсуждение в комментариях в моем ответе с ленивыми флагами было кое-что интересное: например. @Raymond Chen предложил эту ссылку на документ Mihocka & Troeger, а @amdn указал, что динамический перевод JIT может обеспечить более быструю эмуляцию, чем интерпретация.
person
Peter Cordes
schedule
27.10.2016
vm_flags = output_flags | (vm_flags & unmodified_flags_mask)
. - person zneak   schedule 27.10.2016