За многими кодами операций следует байт ModR / M, который разделен на 3 части: верхние два бита - «Mod», следующие три - «Reg», а нижние три - «R / M».
Комбинация частей "Mod" и "R / M" определяет регистр и режим адресации; часть «Reg» может указывать другой регистр или, в некоторых случаях, может указывать дополнительное расширение кода операции.
В этом случае байт ModR / M выглядит следующим образом:
0 0 1 1 0 0 0 0
\_/ \___/ \___/
Mod Reg R/M
Модифицированные биты 00
и R / M биты 000
означают режим адресации [EAX]
(в 32-битном режиме).
Остальные биты Reg являются 6
в десятичном виде. Отсюда MODRM_EAX_06
.
Чтобы полностью понять, что происходит в вашем примере, вам нужно знать, что делает макрос vmx_ptrld
. Предполагая, что это действительно то, что найдено @sixlettervariables, vmx_ptrld
производит байты 0F C7
.
0F
- это первый байт двухбайтового кода операции. Во многих случаях следующий байт завершит код операции; но C7
указывает, что дополнительные биты должны быть считаны из поля Reg байта ModR / M, чтобы определить, какой это код операции. Таким образом, окончательный код операции - 0F
, за которым следует C7
, за которым следует 6
из поля Reg байта ModR / M, записанного как 0F C7 /6
в руководствах Intel (который можно найти здесь ).
0F C7 /6
- это VMPTRLD
, поэтому реальный смысл вашей рутины:
mov eax,8
add eax,ebp
vmptrld [eax]
ret
Предположительно, это было написано так для старых ассемблеров, которые не понимают (относительно недавних) инструкций VMX.