что делает код операции FF350E204000?

У меня 32-битный код операции: FF 35 0E 20 40 00. Кто-нибудь знает хорошую таблицу OpCode, которая дает ответ на этот вопрос? (Я знаю, что могу использовать дизассемблер, но я хотел бы знать, как определить это с помощью таблицы кодов операций). Я нашел эту веб-страницу, но есть 7 различных решений для FF. Я не понимаю.


person Nicolas M.    schedule 04.03.2013    source источник


Ответы (2)


Вы ищете не в том месте. Вам следует поискать это в официальной документации Intel или AMD.

Appendix A Opcode Map из Vol 2B из Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 3A and 3B говорит, что FF это INC/DEC Grp5 1A.

Table A-6 Opcode Extensions for One- and Two-byte Opcodes by Group Number из Vol 2B говорит _9 _ / _ 10_ либо INC, DEC, CALLN, CALLF, JMPN, JMPF, PUSH, в зависимости от битов с 5 по 3 байта ModR/M, следующего за ним. (0x35 >> 3) & 7 = 6 или 110 в двоичном формате. Итак, это PUSH Ev.

Chapter 2 Instruction Format из Vol 2A объясняет, из каких частей состоит инструкция, включая те ModR/M байта, а какие нет.

Appendix A Using Opcode Tables из Vol 2B сообщает вам для E:

Байт ModR / M следует за кодом операции и определяет операнд. Операнд - это регистр общего назначения или адрес памяти. Если это адрес памяти, адрес вычисляется из сегментного регистра и любого из следующих значений: базовый регистр, индексный регистр, коэффициент масштабирования, смещение.

Это также говорит вам для v:

Слово, двойное слово или четверное слово (в 64-битном режиме), в зависимости от атрибута размера операнда.

Итак, вы знаете, что Ev означает регистр или операнд памяти, и поскольку это для 32-битного кода и нет префиксов команд, размер операнда составляет 32 бита. Итак, Ev 32-битный регистр или 32-битная переменная в памяти.

Теперь нужно до конца вычислить оставшиеся байты от ModR / M.

Посмотрите на Figure 2-1. Intel 64 and IA-32 Architectures Instruction Format из Vol 2A. Он сообщает вам, что в ModR/M = 0x35:

Mod = 00 (двоичный)
Reg = 110 (двоичный; мы извлекали эти 3 бита раньше)
R/M = 101 (двоичный)

Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte из Vol 2A говорит вам, что Mod = 00 и R/M = 101 означает disp32, IOW, в инструкции есть операнд памяти, состоящий из 32-битного смещения.

Поле Reg байта ModR/M уже использовалось для выбора одной из семи инструкций, и поэтому это поле не кодирует регистровый операнд.

Итак, ваша инструкция PUSH DWORD [0x0040200E].

И это согласуется с моими выводами дизассемблера.

person Alexey Frunze    schedule 04.03.2013
comment
Таблица A-6 Расширения кодов операций для одно- и двухбайтовых кодов операций по номеру группы находится в томе 2D (номер для заказа: 334569-068), а не в томе 2B. - person ajkhoury; 20.12.2018

Давайте попробуем просмотреть эту последовательность байтов по одному байту за раз.

  1. Первый байт - FF. Если посмотреть на карту кодов операций в Справочнике по набору инструкций Intel, то мы узнаем, что это инструкция INC или DEC вместе с загадочной «Grp 5 - 1A». 1A означает, что «биты 5, 4 и 3 байта ModR / M используются в качестве расширения кода операции». Байт ModR / M - это байт, который кодирует источник и адрес операндов, которые используются для этой инструкции. В этом случае три бита используются для расширения кода операции.
  2. Следующий байт - 35. Это байт ModR / M, который обычно появляется сразу после самого кода операции в инструкциях, которые его используют. 35 (в шестнадцатеричном формате) - это 00110101 в двоичном формате, поэтому биты 5, 4 и 3 равны 110. Глядя на это в таблице расширений кода операции (Таблица A-6), мы видим, что это означает, что это инструкция PUSH d64 Ev. Сноска d64 означает, что «В 64-битном режиме инструкция по умолчанию использует 64-битный размер операнда и не может кодировать 32-битный размер операнда.». Это ожидается для инструкции PUSH. Ev - это символ, который определяет кодировку операнда - что наиболее важно, он указывает, что байт ModR / M следует за самим кодом операции. v, с другой стороны, сигнализирует, что размер операнда зависит от атрибута размера операнда. У нас уже есть байт ModR / M, поэтому давайте его расшифруем (таблица 2-2, предполагая, что этот код работает в 32-битном режиме): эффективный адрес указывается как disp32, что означает, что 32-битное смещение должно следовать за байтом ModR / M. Часть, определяющая регистр, говорит, что следует использовать ESI, но в этом случае это поле используется для расширения кода операции, поэтому оно не используется для обозначения операнда источника регистра.
  3. Следующие четыре байта - это 32-битное смещение. 0E 20 40 00 при декодировании с прямым порядком байтов означает 0x40200e. Это адрес операнда, который будет использоваться для этой инструкции.

Подводя итог, мы получили, что FF 35 0E 20 40 00 равно PUSH DWORD [0x40200e], то есть он будет помещать 32-битное значение, считанное с адреса 0x40200e в стек.

person Daniel Kamil Kozar    schedule 04.03.2013