Русская Википедия:Дизассемблер длин

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Шаблон:Значимость Дизассемблер длин — транслятор, преобразующий машинный код в его длину; аналог дизассемблера, но вычисляющий только размер команды процессора. Обычно применяется с машинным кодом архитектур, допускающих значительную разницу в длине инструкций, обычно из класса CISC. Например, в x86 и x86_64 (Intel и AMD) команда занимает от 1 до 15 байтов[1]. При этом в распространенных RISC архитектурах команда занимает либо всегда 4 байта или допускается использование 2 и 4 байтных команд.

Дизассемблер длин рассматривает машинный код процессора только для оценки, сколько байт занимает текущая команда и когда начнется следующая.

Аналогичный «аппарат» существует в процессоре, производя предвыборку команд из памяти и осуществляя конвейеризацию выполняемых команд[2][1]. Первая стадия декодера инструкций в процессорах с внутренним параллелизмом определяет длины инструкций, чтобы найти начало следующих команд[3][4]. В случае успешного определения длин возможна передача на декодирование сразу нескольких инструкций в такт. В ряде реализаций информация о длинах команд может сохраняться в кэше инструкций. Наблюдая за аппаратным декодером длин исследователям удалось найти ранее недокументированные пространства инструкций в некоторых процессорах[5][6].

Программный Дизассемблер длин необходим для:

  • декодирования инструкций дизассемблером;
  • рекомпиляции прологов функций;
  • быстрого анализа команд программы;

Рекомпиляции прологов функций необходима при перехвате вызовов функций и широко используется в Windows (на всех 32х разрядных процессорах совместимых с i80386).

Для перехвата вызовов к функции подменяются её первые 5 байт на команду «jmp f_ptr_my_func», но для сохранения работоспособности функции необходимо где-то сохранить первые 5 байт оригинальной функции, для этого анализируется размер присутствующих там команд и их назначение.

Нередко приходится сохранять более 5 байт, так как нельзя переносить часть команды (а команды x86 имеют различный формат и размер). Чтобы перенесенные команды сохраняли работоспособность, их рекомпилируют, заменяя на эквивалентные, и завершают командой безусловного перехода на оригинальную функцию (на продолжение кодов). Такой метод перехвата (с подменой пролога функции) называется перехватом методом слайсинга. Это самый эффективный метод перехвата, требующий хорошего знания ассемблера x86.

Примеры дизассемблеров длин можно найти в книге Юань Фэна «Программирование графики для Windows» (дизассемблер длин, представленный там, имеет две ошибки в описании команд x86). Также дизассемблер длин можно найти на сайте wasm.ru

Из-за возможного использования множества префиксов, некоторые сочетания которых могут быть запрещены или игнорироваться, а другие могут изменять длины инструкций, существует ряд широко распространенных ошибок в определении длин для редких сочетаний. Иногда аппаратные реализации разных компаний реализуют такие случаи по-разному[7][8].

См. также

Примечания

Шаблон:Примечания

Ссылки

  1. 1,0 1,1 https://www.agner.org/optimize/blog/read.php?i=25 Шаблон:Wayback «The length of an instruction can be anywhere from one to fifteen bytes. If we want to decode several instructions simultaneously, then we have a serious problem. We have to know the length of the first instruction before we know where the second instruction begins.»
  2. United States Patent 8930678
  3. Шаблон:Книга
  4. PC Mag 21 Feb 1995 page 196 «Pentium Alternatives» Шаблон:Wayback «In NexGen’s Nx586, prefetch circuitry determines instruction length and performs alignment of the x86 instructions»
  5. Шаблон:Cite web
  6. Шаблон:Cite web
  7. Шаблон:Cite web
  8. Шаблон:Cite web