TL; DR
Сохраняйте это простым: один шаг и декодируйте только инструкции ветвления и используйте EIP - last EIP
, если только последняя инструкция не была ветвью (в этом случае используйте декодирование, чтобы найти длину).
Если неизвестная инструкция найдена, отступите и не указывайте ее размер.
Невозможно декодировать поток инструкций x86 в обратном направлении, потому что кодировка x86 не является симметричной (рост адреса w.r.t.), чтобы увидеть это mov eax, 90909090h
или подобное.
Таким образом, вам нужно разбирать каждую инструкцию по мере того, как вы проходите через программу (это все равно нужно отладчику) и записывать ее размер.
Команды передачи управления значительно меньше, чем общее количество команд, поэтому вы можете декодировать только это и использовать трюк EIP - EIP'
(где EIP'
- EIP последней инструкции) в противном случае.
Процессоры Intel поддерживают запись последней ветви, но для этого требуется поддержка ОС, и вам все равно придется пост-обработку данных, это кажется слишком обременительным.
Аналогичный аргумент можно привести для технологии Intel Processor Trace.
Я не могу вспомнить ни одного события для счетчиков производительности (при условии, что вы можете их использовать), которое привело бы к количеству байтов инструкции.
На самом деле в бэкэнде понятие «инструкция» было сведено к последовательности операций (возможно, с небольшим, чтобы сказать, что код операции является последним в инструкции), а интерфейс в основном отделен от архитектурного значения eip
(работает почти всегда с умозрительным значением eip
), поэтому перед бэкэндом может быть несколько инструкций.
Я полагаю, что каждый uOP, вероятно, имеет поле для записи, как обновлять eip
при выходе на пенсию, но не размер инструкции в байтах.
Точно так же во внешнем интерфейсе только на этапе предварительного декодирования записывается длина инструкции в байтах, после чего я думаю, что она отбрасывается (я не могу думать о каком-либо ее использовании).
Инструкции в кеше команд L1 еще не декодированы, поэтому даже если бы был способ проверить их содержимое и метаданные , там ничего бы не было.
Обычный способ сделать это - выполнить трассировку: пошагово выполнить программу, разобрать инструкцию в eip
(см. Ниже), записать ее размер, возобновить программу, повторить до состояния остановки.
Это дает вам список адресов и размеров инструкций.
Если вы находите инструкцию, которую вы не можете декодировать, вы либо не записываете ее размер, либо пытаетесь оценить ее с помощью некоторой эвристики (ее длина должна быть меньше 16 В, и вы теоретически можете интегрировать данные с количеством из PMC, например 1034 *).
Возможно определить размер инструкции во время выполнения, но это совершенно неосуществимо в этом контексте .