Разборка инструкции 'faddl' - PullRequest
4 голосов
/ 15 ноября 2011

В моей работе по написанию кода дизассемблера для 32-битного Linux на платформе x86 я столкнулся с проблемой.Я увидел следующую последовательность кодов операций, когда разбирал простой исполняемый файл ELF-32, используя objdump:

dc 82 04 08 0d 00     faddl  0xd0804(%edx)

Но когда я смотрю на руководство Intel , я не вижукод операции, соответствующий этому.Инструкция fadd начинается с 0xDC, но затем требуется операнд m64fp, который является «операндом памяти в памяти».

Теперь, означает ли это, что операнд является 64-битным адресом?(что означает, что инструкция fadd является 64-битной инструкцией, но не имеет префикса байта REX), или это просто 32-битный адрес, который указывает на четырехзначное (64-битное) слово?

Я что-то упустил здесь тривиально или мое понимание кодирования инструкций x86 неверно?

Ответы [ 2 ]

5 голосов
/ 15 ноября 2011

Давайте разберемся с этим.

> dc 82 04 08 0d 00     faddl  0xd0804(%edx)
  |  |  \____ ____/
  |  |       V
  |  |       |
  |  |       +---------> 32-bit displacement
  |  +-----------------> ModRM byte
  +--------------------> Opcode

Если подробно рассмотреть документы, dc действительно для m64real аргумента с плавающей запятой в качестве источника.Он добавит этот 64-битный аргумент в регистр с плавающей запятой ST(0).

Однако, это секунда байт 82, который решает, откуда поступит это 64-битное значение.Это преобразуется в двоичный байт ModRM:

+---+---+---+---+---+---+---+---+
| 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
+---+---+---+---+---+---+---+---+
|  MOD  |  REG/OPCD |    R/M    |

Если вы посмотрите на таблицу 2.2 в вашем связанном документе (для 32-битных режимов адресации), вы увидите, что это преобразуется в disp32[EDX].

Другими словами, он принимает следующие 32 бита (четыре байта), добавляет их в регистр edx и использует этот адрес для извлечения 64-битного значения из памяти.

2 голосов
/ 15 ноября 2011

«Операнд четырех слов в памяти» означает, что значение занимает 64 бита в ОЗУ.Размер адреса будет зависеть от того, компилируется ли он как 32- или 64-битный процесс, а не от того, насколько велики операнды.Вот полная разбивка разборки.

  • Первый байт, DC - это код операции.В сочетании с тем фактом, что следующий байт не находится между C0 и C7 и содержит 0 в поле регистра (биты 3-5), это указывает на инструкцию fadd с 64-битным операндом памяти.Интересно, что l в конце кода операции будет означать 32-битный операнд.Это должно быть faddq.

  • Второй байт содержит 3 поля.

    • Биты 6-7 указывают режим последнего поля.
    • Биты 3-5 - это поле регистра.Поскольку операнд регистра не требуется для этой инструкции, они используются как часть кода операции.
    • Биты 0-2 - это поле R / M.Может содержать регистр или указывать операнд памяти.Комбинированный режим 10 и R / M 010 указывают, что операнд является операндом памяти с 32-битным адресом относительно регистра edx.
  • последние 4 байта являются относительным смещением операнда в младшем порядке (сначала младший байт).

...