Заклинание кода: Заин

Дата публикации 22 сен 2003

Заклинание кода: Заин — Архив WASM.RU

У буквы "заин" долгая и богатая история. Многие поколения магов пытались определить, в чем заключается ее сокровенный смысл. Некоторые утвеждали, что она несет врагам смерть и страдания от разящего клинка, иные указывали на ее форму и говорили, что этот разящий клинок применим далеко не всегда и не везде, а только в некоторых, хотя и весьма ответственных операциях.

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

Однако мы еще не рассмотрели две важные темы, а именно - префиксы и использование 16-ти битных инструкций в 32-х битном коде.

Предположим, что нам нужно составить заклинание для следующего фрагмента кода:

Код (Text):
  1.  
  2. xor eax, eax
  3. mov ecx, 1000
  4. repne scasd

Данный код выполняет очень простую операцию - он ищет в массиве двойных слов (чей адрес был предварительно загружен в EDI) элемент, который равен нулю. Сделать заклинания для первых двух строчек вышеприведенного кода не представляет особого труда - в прошлых главах мы делали это много раз. Однако третья может поставить неопытного заклинателя в тупик, так как у инструкции SCASD есть префикс REPNE.

SCASD сравнивает EAX со значением, содержащемся в ячейке памяти, адрес которого находится в EDI, после чего увеличивает содержимое последнего на 4 (размер двойного слова). Эта инструкция удобна, если применять префиксы повторения строковой операции. REPNE - один из таких префиксов. Прибавление его к инструкции SCASD заставляет последнюю выполняться до тех пор, пока операция сравнения не даст положительный результат.

Но как же задать префикс на уровне заклинаний? Очень просто - каждому префиксу соотвествует непосредственное однобайтовое значение, которые помещается непосредственно перед инструкцией. Префиксу REPNE соответствует F2, а опкодом SCASD является AF. Таким образом нужное нам заклинание будет выглять так:

Код (Text):
  1.  
  2. db 0F2h, 0AFh ; repne scasd

Теперь давайте представим другую ситуацию. Например, необходимо составить заклинание для инструкции 'INC AX'. Обратимся к Книге Двойных Слов. В описании инструкции INC нас интересуют следующие строки:

Код (Text):
  1.  
  2. 40+ rw INC r16 Increment word register by 1
  3. 40+ rd INC r32 Increment doubleword register by 1

Как вы можете видеть, и 'INC AX' и 'INC EAX' соответствует один опкод. Какой же вариант выберет процессор? Это зависит от того, в каком режиме работает программа. Если в 32-х битном, то встретив опкод 40h процессор выполнит инструкцию 'INC EAX'. Если в 16-ти битном, то 'INC AX'. А чтобы выполнить 'INC AX' в 32-х битном режиме, нужно использовать специальный префикс 66h, который как и все префиксы помещается непосредственно перед инструкцией. Таким образом, заклинание для 'INC AX' в 32-х битном коде будет выглядеть так:

Код (Text):
  1.  
  2. db 66h, 40h

Тот же префикс в 16-ти битном коде выполняет обратную работу - заставляет процессор выполнить данную инструкцию как 32-х битную.

У читателя может возникнуть закономерный вопрос: какие еще бывают префиксы, кроме префикса повторения строковой операции и префикса переопределения размера операнда (именно так интеловские гномы назвали рассмотренный нами выше префикс)? Далее следует список не рассмотренных нами в данной главе префиксов:

  • F0h - LOCK (обеспечивает эксклюзивное использование памяти в мультипроцессорной среде)
  • F3h - REP/REPE/REPZ (используется только со строковыми инструкциями)
  • 2Eh/36h/3Eh/26h/26h/64h/65h - префиксы переопределения сегмента (CS, SS, DS, ES, FS и GS соответственно)
  • 2Eh - переход выполняется (только с инструкциями Jcc)
  • 3Eh - переход не выполяется (только с инструкциями Jcc)

О последних двух префиксах нужно сказать особо. Они появились в самых последних процессорах, разработанных интеловскими гномами - Pentium 4 и Xeon. Они помогают помочь процессору решить, будет ли (скорее всего) выполнен переход или нет. Это важно для того, какой код будет кэшироваться.

Вот и все для этой главы. Она получилась небольшой, но, возможно, это и к лучшему. Магия кода заключается не в объемных томах, а в правильно работающих заклинаниях. © Aquila / WASM.RU


0 1.331
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532