Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1436 lines
68 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. 86dis.cpp
  5. Abstract:
  6. Used to find out how long (in bytes) an instruction is: X86 only
  7. Notes:
  8. This is largely undocumented since it's based entirely on the original
  9. implementation by Gerd Immeyer.
  10. History:
  11. 10/19/1989 Gerd Immeyer Original version
  12. 01/09/2000 linstev Dumbed down for a shim
  13. --*/
  14. #include "precomp.h"
  15. IMPLEMENT_SHIM_BEGIN(IgnoreException)
  16. #include "ShimHookMacro.h"
  17. #ifdef _X86_
  18. #pragma pack(1)
  19. #define BIT20(b) (b & 0x07)
  20. #define BIT53(b) (b >> 3 & 0x07)
  21. #define BIT76(b) (b >> 6 & 0x03)
  22. #define MRM 0x40
  23. #define COM 0x80
  24. #define END 0xc0
  25. #define SECTAB_OFFSET_1 256
  26. #define SECTAB_OFFSET_2 236
  27. #define SECTAB_OFFSET_3 227
  28. #define SECTAB_OFFSET_4 215
  29. #define SECTAB_OFFSET_5 199
  30. #define SECTAB_OFFSET_UNDEF 260
  31. #define O_DoDB 0
  32. #define O_NoOperands 0
  33. #define O_NoOpAlt5 O_NoOperands+1
  34. #define O_NoOpAlt4 O_NoOpAlt5+2
  35. #define O_NoOpAlt3 O_NoOpAlt4+2
  36. #define O_NoOpAlt1 O_NoOpAlt3+2
  37. #define O_NoOpAlt0 O_NoOpAlt1+2
  38. #define O_NoOpStrSI O_NoOpAlt0+2
  39. #define O_NoOpStrDI O_NoOpStrSI+2
  40. #define O_NoOpStrSIDI O_NoOpStrDI+2
  41. #define O_bModrm_Reg O_NoOpStrSIDI+2
  42. #define O_vModrm_Reg O_bModrm_Reg+3
  43. #define O_Modrm_Reg O_vModrm_Reg+3
  44. #define O_bReg_Modrm O_Modrm_Reg+3
  45. #define O_fReg_Modrm O_bReg_Modrm+3
  46. #define O_Reg_Modrm O_fReg_Modrm+3
  47. #define O_AL_Ib O_Reg_Modrm+3
  48. #define O_AX_Iv O_AL_Ib+2
  49. #define O_sReg2 O_AX_Iv+2
  50. #define O_oReg O_sReg2+1
  51. #define O_DoBound O_oReg+1
  52. #define O_Iv O_DoBound+3
  53. #define O_wModrm_Reg O_Iv+1
  54. #define O_Ib O_wModrm_Reg+3
  55. #define O_Imulb O_Ib+1
  56. #define O_Imul O_Imulb+4
  57. #define O_Rel8 O_Imul+4
  58. #define O_bModrm_Ib O_Rel8+1
  59. #define O_Modrm_Ib O_bModrm_Ib+3
  60. #define O_Modrm_Iv O_Modrm_Ib+3
  61. #define O_Modrm_sReg3 O_Modrm_Iv+3
  62. #define O_sReg3_Modrm O_Modrm_sReg3+3
  63. #define O_Modrm O_sReg3_Modrm+3
  64. #define O_FarPtr O_Modrm+2
  65. #define O_AL_Offs O_FarPtr+1
  66. #define O_Offs_AL O_AL_Offs+2
  67. #define O_AX_Offs O_Offs_AL+2
  68. #define O_Offs_AX O_AX_Offs+2
  69. #define O_oReg_Ib O_Offs_AX+2
  70. #define O_oReg_Iv O_oReg_Ib+2
  71. #define O_Iw O_oReg_Iv+2
  72. #define O_Enter O_Iw+1
  73. #define O_Ubyte_AL O_Enter+2
  74. #define O_Ubyte_AX O_Ubyte_AL+2
  75. #define O_AL_Ubyte O_Ubyte_AX+2
  76. #define O_AX_Ubyte O_AL_Ubyte+2
  77. #define O_DoInAL O_AX_Ubyte+2
  78. #define O_DoInAX O_DoInAL+3
  79. #define O_DoOutAL O_DoInAX+3
  80. #define O_DoOutAX O_DoOutAL+3
  81. #define O_Rel16 O_DoOutAX+3
  82. #define O_ADR_OVERRIDE O_Rel16+1
  83. #define O_OPR_OVERRIDE O_ADR_OVERRIDE+1
  84. #define O_SEG_OVERRIDE O_OPR_OVERRIDE+1
  85. #define O_DoInt3 O_SEG_OVERRIDE+1
  86. #define O_DoInt 117
  87. #define O_OPC0F O_DoInt+1
  88. #define O_GROUP11 O_OPC0F+1
  89. #define O_GROUP13 O_GROUP11+5
  90. #define O_GROUP12 O_GROUP13+5
  91. #define O_GROUP21 O_GROUP12+5
  92. #define O_GROUP22 O_GROUP21+5
  93. #define O_GROUP23 O_GROUP22+5
  94. #define O_GROUP24 O_GROUP23+6
  95. #define O_GROUP25 O_GROUP24+6
  96. #define O_GROUP26 O_GROUP25+6
  97. #define O_GROUP4 O_GROUP26+6
  98. #define O_GROUP6 O_GROUP4+4
  99. #define O_GROUP8 O_GROUP6+4
  100. #define O_GROUP31 O_GROUP8+5
  101. #define O_GROUP32 O_GROUP31+3
  102. #define O_GROUP5 O_GROUP32+3
  103. #define O_GROUP7 O_GROUP5+3
  104. #define O_x87_ESC O_GROUP7+3
  105. #define O_bModrm O_x87_ESC+2
  106. #define O_wModrm O_bModrm+2
  107. #define O_dModrm O_wModrm+2
  108. #define O_fModrm O_dModrm+2
  109. #define O_vModrm O_fModrm+2
  110. #define O_vModrm_Iv O_vModrm+2
  111. #define O_Reg_bModrm O_vModrm_Iv+3
  112. #define O_Reg_wModrm O_Reg_bModrm+3
  113. #define O_Modrm_Reg_Ib O_Reg_wModrm+3
  114. #define O_Modrm_Reg_CL O_Modrm_Reg_Ib+4
  115. #define O_ST_iST O_Modrm_Reg_CL+5
  116. #define O_iST O_ST_iST+2
  117. #define O_iST_ST O_iST+2
  118. #define O_qModrm O_iST_ST+2
  119. #define O_tModrm O_qModrm+2
  120. #define O_DoRep O_tModrm+2
  121. #define O_Modrm_CReg O_DoRep+1
  122. #define O_CReg_Modrm O_Modrm_CReg+3
  123. #define O_AX_oReg O_CReg_Modrm+3
  124. #define O_MmReg_qModrm O_AX_oReg+2
  125. #define O_qModrm_MmReg O_MmReg_qModrm+3
  126. #define O_MmReg_dModrm O_qModrm_MmReg+3
  127. #define O_dModrm_MmReg O_MmReg_dModrm+3
  128. #define O_qModrm_Ib O_dModrm_MmReg+3
  129. #define O_PSHimw O_qModrm_Ib+3
  130. #define O_PSHimd O_PSHimw+5
  131. #define O_PSHimq O_PSHimd+5
  132. #define O_length O_PSHimq+5
  133. typedef unsigned short ActionIndex;
  134. typedef struct Tdistbl
  135. {
  136. ActionIndex opr;
  137. } Tdistbl;
  138. typedef struct _ADDR
  139. {
  140. USHORT type;
  141. USHORT seg;
  142. ULONG off;
  143. union
  144. {
  145. ULONG flat;
  146. ULONGLONG flat64;
  147. };
  148. } ADDR, *PADDR;
  149. typedef struct _DECODEDATA
  150. {
  151. int mod; // mod of mod/rm byte
  152. int rm; // rm of mod/rm byte
  153. int ttt; // return reg value (of mod/rm)
  154. unsigned char *pMem; // current position in instruction
  155. ADDR EAaddr[2]; // offset of effective address
  156. int EAsize[2]; // size of effective address item
  157. BOOL fMovX; // indicates a MOVSX or MOVZX
  158. BOOL fMmRegEa; // Use mm? registers in reg-only EA.
  159. } DECODEDATA;
  160. enum oprtyp { ADDRP, ADR_OVR, ALSTR, ALT, AXSTR, BOREG,
  161. BREG, BRSTR, xBYTE, CHR, CREG, xDWORD,
  162. EDWORD, EGROUPT, FARPTR, GROUP, GROUPT, IB,
  163. IST, IST_ST, IV, IW, LMODRM, MODRM,
  164. NOP, OFFS, OPC0F, OPR_OVR, QWORD, REL16,
  165. REL8, REP, SEG_OVR, SREG2, SREG3, ST_IST,
  166. STROP, xTBYTE, UBYTE, VAR, VOREG, VREG,
  167. xWORD, WREG, WRSTR, MMWREG, MMQWORD
  168. };
  169. unsigned char actiontbl[] = {
  170. /* NoOperands */ NOP+END,
  171. /* NoOpAlt5 */ ALT+END, 5,
  172. /* NoOpAlt4 */ ALT+END, 4,
  173. /* NoOpAlt3 */ ALT+END, 3,
  174. /* NoOpAlt1 */ ALT+END, 1,
  175. /* NoOpAlt0 */ ALT+END, 0,
  176. /* NoOpStrSI */ STROP+END, 1,
  177. /* NoOpStrDI */ STROP+END, 2,
  178. /* NoOpStrSIDI */ STROP+END, 3,
  179. /* bModrm_Reg */ xBYTE+MRM, MODRM+COM, BREG+END,
  180. /* vModrm_Reg */ VAR+MRM, LMODRM+COM, BREG+END,
  181. /* Modrm_Reg */ VAR+MRM, MODRM+COM, VREG+END,
  182. /* bReg_Modrm */ xBYTE+MRM, BREG+COM, MODRM+END,
  183. /* fReg_Modrm */ FARPTR+MRM,VREG+COM, MODRM+END,
  184. /* Reg_Modrm */ VAR+MRM, VREG+COM, MODRM+END,
  185. /* AL_Ib */ ALSTR+COM, IB+END,
  186. /* AX_Iv */ AXSTR+COM, IV+END,
  187. /* sReg2 */ SREG2+END,
  188. /* oReg */ VOREG+END,
  189. /* DoBound */ VAR+MRM, VREG+COM, MODRM+END,
  190. /* Iv */ IV+END,
  191. /* wModrm_Reg */ xWORD+MRM, LMODRM+COM, WREG+END,
  192. /* Ib */ IB+END,
  193. /* Imulb */ VAR+MRM, VREG+COM, MODRM+COM, IB+END,
  194. /* Imul */ VAR+MRM, VREG+COM, MODRM+COM, IV+END,
  195. /* REL8 */ REL8+END,
  196. /* bModrm_Ib */ xBYTE+MRM, LMODRM+COM, IB+END,
  197. /* Modrm_Ib */ VAR+MRM, LMODRM+COM, IB+END,
  198. /* Modrm_Iv */ VAR+MRM, LMODRM+COM, IV+END,
  199. /* Modrm_sReg3 */ xWORD+MRM, MODRM+COM, SREG3+END,
  200. /* sReg3_Modrm */ xWORD+MRM, SREG3+COM, MODRM+END,
  201. /* Modrm */ VAR+MRM, MODRM+END,
  202. /* FarPtr */ ADDRP+END,
  203. /* AL_Offs */ ALSTR+COM, OFFS+END,
  204. /* Offs_AL */ OFFS+COM, ALSTR+END,
  205. /* AX_Offs */ AXSTR+COM, OFFS+END,
  206. /* Offs_AX */ OFFS+COM, AXSTR+END,
  207. /* oReg_Ib */ BOREG+COM, IB+END,
  208. /* oReg_Iv */ VOREG+COM, IV+END,
  209. /* Iw */ IW+END,
  210. /* enter */ IW+COM, IB+END,
  211. /* Ubyte_AL */ UBYTE+COM, ALSTR+END,
  212. /* Ubyte_AX */ UBYTE+COM, AXSTR+END,
  213. /* AL_Ubyte */ ALSTR+COM, UBYTE+END,
  214. /* AX_Ubyte */ AXSTR+COM, UBYTE+END,
  215. /* DoInAL */ ALSTR+COM, WRSTR+END, 2,
  216. /* DoInAX */ AXSTR+COM, WRSTR+END, 2,
  217. /* DoOutAL */ WRSTR+COM, 2, ALSTR+END,
  218. /* DoOutAX */ WRSTR+COM, 2, AXSTR+END,
  219. /* REL16 */ REL16+END,
  220. /* ADR_OVERRIDE*/ ADR_OVR,
  221. /* OPR_OVERRIDE*/ OPR_OVR,
  222. /* SEG_OVERRIDE*/ SEG_OVR,
  223. /* DoInt3 */ CHR+END, '3',
  224. /* DoInt */ UBYTE+END,
  225. /* Opcode0F */ OPC0F,
  226. /* group1_1 */ xBYTE+MRM, GROUP, 0, LMODRM+COM, IB+END,
  227. /* group1_3 */ VAR+MRM, GROUP, 0, LMODRM+COM, IB+END,
  228. /* group1_2 */ VAR+MRM, GROUP, 0, LMODRM+COM, IV+END,
  229. /* group2_1 */ xBYTE+MRM, GROUP, 1, LMODRM+COM, IB+END,
  230. /* group2_2 */ VAR+MRM, GROUP, 1, LMODRM+COM, IB+END,
  231. /* group2_3 */ xBYTE+MRM, GROUP, 1, LMODRM+COM, CHR+END, '1',
  232. /* group2_4 */ VAR+MRM, GROUP, 1, LMODRM+COM, CHR+END, '1',
  233. /* group2_5 */ xBYTE+MRM, GROUP, 1, LMODRM+COM, BRSTR+END, 1,
  234. /* group2_6 */ VAR+MRM, GROUP, 1, LMODRM+COM, BRSTR+END, 1,
  235. /* group4 */ xBYTE+MRM, GROUP, 2, LMODRM+END,
  236. /* group6 */ xWORD+MRM, GROUP, 3, LMODRM+END,
  237. /* group8 */ xWORD+MRM, GROUP, 4, LMODRM+COM, IB+END,
  238. /* group3_1 */ xBYTE+MRM, GROUPT, 20,
  239. /* group3_2 */ VAR+MRM, GROUPT, 21,
  240. /* group5 */ VAR+MRM, GROUPT, 22,
  241. /* group7 */ NOP+MRM, GROUPT, 23,
  242. /* x87_ESC */ NOP+MRM, EGROUPT,
  243. /* bModrm */ xBYTE+MRM, LMODRM+END,
  244. /* wModrm */ xWORD+MRM, LMODRM+END,
  245. /* dModrm */ xDWORD+MRM,LMODRM+END,
  246. /* fModrm */ FARPTR+MRM,LMODRM+END,
  247. /* vModrm */ VAR+MRM, LMODRM+END,
  248. /* vModrm_Iv */ VAR+MRM, LMODRM+COM, IV+END,
  249. /* reg_bModrm */ xBYTE+MRM, VREG+COM, LMODRM+END,
  250. /* reg_wModrm */ xWORD+MRM, VREG+COM, LMODRM+END,
  251. /* Modrm_Reg_Ib*/ VAR+MRM, MODRM+COM, VREG+COM, IB+END,
  252. /* Modrm_Reg_CL*/ VAR+MRM, MODRM+COM, VREG+COM, BRSTR+END, 1,
  253. /* ST_iST */ NOP+MRM, ST_IST+END,
  254. /* iST */ NOP+MRM, IST+END,
  255. /* iST_ST */ NOP+MRM, IST_ST+END,
  256. /* qModrm */ QWORD+MRM, LMODRM+END,
  257. /* tModrm */ xTBYTE+MRM, LMODRM+END,
  258. /* REP */ REP,
  259. /* Modrm_CReg */ EDWORD+MRM,MODRM+COM, CREG+END,
  260. /* CReg_Modrm */ EDWORD+MRM,CREG+COM, MODRM+END,
  261. /* AX_oReg */ AXSTR+COM, VOREG+END,
  262. /* MmReg_qModrm*/ MMQWORD+MRM, MMWREG+COM, LMODRM+END,
  263. /* qModrm_MmReg*/ MMQWORD+MRM, MODRM+COM, MMWREG+END,
  264. /* MmReg_dModrm*/ xDWORD+MRM, MMWREG+COM,LMODRM+END,
  265. /* dModrm_MmReg*/ xDWORD+MRM, MODRM+COM, MMWREG+END,
  266. /* qModrm_Ib */ MMQWORD+MRM, MODRM+COM,IB+END,
  267. /* PSHimw */ MMQWORD+MRM, GROUP, 5, LMODRM+COM, IB+END,
  268. /* PSHimd */ MMQWORD+MRM, GROUP, 6, LMODRM+COM, IB+END,
  269. /* PSHimq */ MMQWORD+MRM, GROUP, 7, LMODRM+COM, IB+END,
  270. };
  271. Tdistbl distbl[] = {
  272. O_bModrm_Reg, /* 00 ADD mem/reg, reg (byte) */
  273. O_Modrm_Reg, /* 01 ADD mem/reg, reg (word) */
  274. O_bReg_Modrm, /* 02 ADD reg, mem/reg (byte) */
  275. O_Reg_Modrm, /* 03 ADD reg, mem/reg (word) */
  276. O_AL_Ib, /* 04 ADD AL, I */
  277. O_AX_Iv, /* 05 ADD AX, I */
  278. O_sReg2, /* 06 PUSH ES */
  279. O_sReg2, /* 07 POP ES */
  280. O_bModrm_Reg, /* 08 OR mem/reg, reg (byte) */
  281. O_Modrm_Reg, /* 09 OR mem/reg, reg (word) */
  282. O_bReg_Modrm, /* 0A OR reg, mem/reg (byte) */
  283. O_Reg_Modrm, /* 0B OR reg, mem/reg (word) */
  284. O_AL_Ib, /* 0C OR AL, I */
  285. O_AX_Iv, /* 0D OR AX, I */
  286. O_sReg2, /* 0E PUSH CS */
  287. O_OPC0F, /* 0F CLTS & protection ctl(286) */
  288. O_bModrm_Reg, /* 10 ADC mem/reg, reg (byte) */
  289. O_Modrm_Reg, /* 11 ADC mem/reg, reg (word) */
  290. O_bReg_Modrm, /* 12 ADC reg, mem/reg (byte) */
  291. O_Reg_Modrm, /* 13 ADC reg, mem/reg (word) */
  292. O_AL_Ib, /* 14 ADC AL, I */
  293. O_AX_Iv, /* 15 ADC AX, I */
  294. O_sReg2, /* 16 PUSH SS */
  295. O_sReg2, /* 17 POP SS */
  296. O_bModrm_Reg, /* 18 SBB mem/reg, reg (byte) */
  297. O_Modrm_Reg, /* 19 SBB mem/reg, reg (word) */
  298. O_bReg_Modrm, /* 1A SBB reg, mem/reg (byte) */
  299. O_Reg_Modrm, /* 1B SBB reg, mem/reg (word) */
  300. O_AL_Ib, /* 1C SBB AL, I */
  301. O_AX_Iv, /* 1D SBB AX, I */
  302. O_sReg2, /* 1E PUSH DS */
  303. O_sReg2, /* 1F POP DS */
  304. O_bModrm_Reg, /* 20 AND mem/reg, reg (byte) */
  305. O_Modrm_Reg, /* 21 AND mem/reg, reg (word) */
  306. O_bReg_Modrm, /* 22 AND reg, mem/reg (byte) */
  307. O_Reg_Modrm, /* 23 AND reg, mem/reg (word) */
  308. O_AL_Ib, /* 24 AND AL, I */
  309. O_AX_Iv, /* 25 AND AX, I */
  310. O_SEG_OVERRIDE, /* 26 SEG ES: */
  311. O_NoOperands, /* 27 DAA */
  312. O_bModrm_Reg, /* 28 SUB mem/reg, reg (byte) */
  313. O_Modrm_Reg, /* 29 SUB mem/reg, reg (word) */
  314. O_bReg_Modrm, /* 2A SUB reg, mem/reg (byte) */
  315. O_Reg_Modrm, /* 2B SUB reg, mem/reg (word) */
  316. O_AL_Ib, /* 2C SUB AL, I */
  317. O_AX_Iv, /* 2D SUB AX, I */
  318. O_SEG_OVERRIDE, /* 2E SEG CS: */
  319. O_NoOperands, /* 2F DAS */
  320. O_bModrm_Reg, /* 30 XOR mem/reg, reg (byte) */
  321. O_Modrm_Reg, /* 31 XOR mem/reg, reg (word) */
  322. O_bReg_Modrm, /* 32 XOR reg, mem/reg (byte) */
  323. O_Reg_Modrm, /* 33 XOR reg, mem/reg (word) */
  324. O_AL_Ib, /* 34 XOR AL, I */
  325. O_AX_Iv, /* 35 XOR AX, I */
  326. O_SEG_OVERRIDE, /* 36 SEG SS: */
  327. O_NoOperands, /* 37 AAA */
  328. O_bModrm_Reg, /* 38 CMP mem/reg, reg (byte) */
  329. O_Modrm_Reg, /* 39 CMP mem/reg, reg (word) */
  330. O_bReg_Modrm, /* 3A CMP reg, mem/reg (byte) */
  331. O_Reg_Modrm, /* 3B CMP reg, mem/reg (word) */
  332. O_AL_Ib, /* 3C CMP AL, I */
  333. O_AX_Iv, /* 3D CMP AX, I */
  334. O_SEG_OVERRIDE, /* 3E SEG DS: */
  335. O_NoOperands, /* 3F AAS */
  336. O_oReg, /* 40 INC AX */
  337. O_oReg, /* 41 INC CX */
  338. O_oReg, /* 42 INC DX */
  339. O_oReg, /* 43 INC BX */
  340. O_oReg, /* 44 INC SP */
  341. O_oReg, /* 45 INC BP */
  342. O_oReg, /* 46 INC SI */
  343. O_oReg, /* 47 INC DI */
  344. O_oReg, /* 48 DEC AX */
  345. O_oReg, /* 49 DEC CX */
  346. O_oReg, /* 4A DEC DX */
  347. O_oReg, /* 4B DEC BX */
  348. O_oReg, /* 4C DEC SP */
  349. O_oReg, /* 4D DEC BP */
  350. O_oReg, /* 4E DEC SI */
  351. O_oReg, /* 4F DEC DI */
  352. O_oReg, /* 50 PUSH AX */
  353. O_oReg, /* 51 PUSH CX */
  354. O_oReg, /* 52 PUSH DX */
  355. O_oReg, /* 53 PUSH BX */
  356. O_oReg, /* 54 PUSH SP */
  357. O_oReg, /* 55 PUSH BP */
  358. O_oReg, /* 56 PUSH SI */
  359. O_oReg, /* 57 PUSH DI */
  360. O_oReg, /* 58 POP AX */
  361. O_oReg, /* 59 POP CX */
  362. O_oReg, /* 5A POP DX */
  363. O_oReg, /* 5B POP BX */
  364. O_oReg, /* 5C POP SP */
  365. O_oReg, /* 5D POP BP */
  366. O_oReg, /* 5E POP SI */
  367. O_oReg, /* 5F POP DI */
  368. O_NoOpAlt5, /* 60 PUSHA (286) / PUSHAD (386) */
  369. O_NoOpAlt4, /* 61 POPA (286) / POPAD (286) */
  370. O_DoBound, /* 62 BOUND reg, Modrm (286) */
  371. O_Modrm_Reg, /* 63 ARPL Modrm, reg (286) */
  372. O_SEG_OVERRIDE, /* 64 */
  373. O_SEG_OVERRIDE, /* 65 */
  374. O_OPR_OVERRIDE, /* 66 */
  375. O_ADR_OVERRIDE, /* 67 */
  376. O_Iv, /* 68 PUSH word (286) */
  377. O_Imul, /* 69 IMUL (286) */
  378. O_Ib, /* 6A PUSH byte (286) */
  379. O_Imulb, /* 6B IMUL (286) */
  380. O_NoOperands, /* 6C INSB (286) */
  381. O_NoOpAlt3, /* 6D INSW (286) / INSD (386) */
  382. O_NoOperands, /* 6E OUTSB (286) */
  383. O_NoOpAlt4, /* 6F OUTSW (286) / OUTSD (386) */
  384. O_Rel8, /* 70 JO */
  385. O_Rel8, /* 71 JNO */
  386. O_Rel8, /* 72 JB or JNAE or JC */
  387. O_Rel8, /* 73 JNB or JAE or JNC */
  388. O_Rel8, /* 74 JE or JZ */
  389. O_Rel8, /* 75 JNE or JNZ */
  390. O_Rel8, /* 76 JBE or JNA */
  391. O_Rel8, /* 77 JNBE or JA */
  392. O_Rel8, /* 78 JS */
  393. O_Rel8, /* 79 JNS */
  394. O_Rel8, /* 7A JP or JPE */
  395. O_Rel8, /* 7B JNP or JPO */
  396. O_Rel8, /* 7C JL or JNGE */
  397. O_Rel8, /* 7D JNL or JGE */
  398. O_Rel8, /* 7E JLE or JNG */
  399. O_Rel8, /* 7F JNLE or JG */
  400. O_GROUP11, /* 80 */
  401. O_GROUP12, /* 81 */
  402. O_DoDB, /* 82 */
  403. O_GROUP13, /* 83 */
  404. O_bModrm_Reg, /* 84 TEST reg, mem/reg (byte) */
  405. O_Modrm_Reg, /* 85 TEST reg, mem/reg (word) */
  406. O_bModrm_Reg, /* 86 XCHG reg, mem/reg (byte) */
  407. O_Modrm_Reg, /* 87 XCHG reg, mem/reg (word) */
  408. O_bModrm_Reg, /* 88 MOV mem/reg, reg (byte) */
  409. O_Modrm_Reg, /* 89 MOV mem/reg, reg (word) */
  410. O_bReg_Modrm, /* 8A MOV reg, mem/reg (byte) */
  411. O_Reg_Modrm, /* 8B MOV reg, mem/reg (word) */
  412. O_Modrm_sReg3, /* 8C MOV mem/reg, segreg */
  413. O_Reg_Modrm, /* 8D LEA reg, mem */
  414. O_sReg3_Modrm, /* 8E MOV segreg, mem/reg */
  415. O_Modrm, /* 8F POP mem/reg */
  416. O_NoOperands, /* 90 NOP */
  417. O_AX_oReg, /* 91 XCHG AX,CX */
  418. O_AX_oReg, /* 92 XCHG AX,DX */
  419. O_AX_oReg, /* 93 XCHG AX,BX */
  420. O_AX_oReg, /* 94 XCHG AX,SP */
  421. O_AX_oReg, /* 95 XCHG AX,BP */
  422. O_AX_oReg, /* 96 XCHG AX,SI */
  423. O_AX_oReg, /* 97 XCHG AX,DI */
  424. O_NoOpAlt0, /* 98 CBW / CWDE (386) */
  425. O_NoOpAlt1, /* 99 CWD / CDQ (386) */
  426. O_FarPtr, /* 9A CALL seg:off */
  427. O_NoOperands, /* 9B WAIT */
  428. O_NoOpAlt5, /* 9C PUSHF / PUSHFD (386) */
  429. O_NoOpAlt4, /* 9D POPF / POPFD (386) */
  430. O_NoOperands, /* 9E SAHF */
  431. O_NoOperands, /* 9F LAHF */
  432. O_AL_Offs, /* A0 MOV AL, mem */
  433. O_AX_Offs, /* A1 MOV AX, mem */
  434. O_Offs_AL, /* A2 MOV mem, AL */
  435. O_Offs_AX, /* A3 MOV mem, AX */
  436. O_NoOpStrSIDI, /* A4 MOVSB */
  437. O_NoOpStrSIDI, /* A5 MOVSW / MOVSD (386) */
  438. O_NoOpStrSIDI, /* A6 CMPSB */
  439. O_NoOpStrSIDI, /* A7 CMPSW / CMPSD (386) */
  440. O_AL_Ib, /* A8 TEST AL, I */
  441. O_AX_Iv, /* A9 TEST AX, I */
  442. O_NoOpStrDI, /* AA STOSB */
  443. O_NoOpStrDI, /* AB STOSW / STOSD (386) */
  444. O_NoOpStrSI, /* AC LODSB */
  445. O_NoOpStrSI, /* AD LODSW / LODSD (386) */
  446. O_NoOpStrDI, /* AE SCASB */
  447. O_NoOpStrDI, /* AF SCASW / SCASD (386) */
  448. O_oReg_Ib, /* B0 MOV AL, I */
  449. O_oReg_Ib, /* B1 MOV CL, I */
  450. O_oReg_Ib, /* B2 MOV DL, I */
  451. O_oReg_Ib, /* B3 MOV BL, I */
  452. O_oReg_Ib, /* B4 MOV AH, I */
  453. O_oReg_Ib, /* B5 MOV CH, I */
  454. O_oReg_Ib, /* B6 MOV DH, I */
  455. O_oReg_Ib, /* B7 MOV BH, I */
  456. O_oReg_Iv, /* B8 MOV AX, I */
  457. O_oReg_Iv, /* B9 MOV CX, I */
  458. O_oReg_Iv, /* BA MOV DX, I */
  459. O_oReg_Iv, /* BB MOV BX, I */
  460. O_oReg_Iv, /* BC MOV SP, I */
  461. O_oReg_Iv, /* BD MOV BP, I */
  462. O_oReg_Iv, /* BE MOV SI, I */
  463. O_oReg_Iv, /* BF MOV DI, I */
  464. O_GROUP21, /* C0 shifts & rotates (286) */
  465. O_GROUP22, /* C1 shifts & rotates (286) */
  466. O_Iw, /* C2 RET Rel16 */
  467. O_NoOperands, /* C3 RET */
  468. O_fReg_Modrm, /* C4 LES reg, mem */
  469. O_fReg_Modrm, /* C5 LDS reg, mem */
  470. O_bModrm_Ib, /* C6 MOV mem/reg, I(byte) */
  471. O_Modrm_Iv, /* C7 MOV mem/reg, I(word) */
  472. O_Enter, /* C8 ENTER (286) */
  473. O_NoOperands, /* C9 LEAVE (286) */
  474. O_Iw, /* CA RETF I(word) */
  475. O_NoOperands, /* CB RETF */
  476. O_DoInt3, /* CC INT 3 */
  477. O_DoInt, /* CD INT */
  478. O_NoOperands, /* CE INTO */
  479. O_NoOpAlt4, /* CF IRET / IRETD (386) */
  480. O_GROUP23, /* D0 shifts & rotates,1 (byte) */
  481. O_GROUP24, /* D1 shifts & rotates,1 (word) */
  482. O_GROUP25, /* D2 shifts & rotates,CL (byte) */
  483. O_GROUP26, /* D3 shifts & rotates,CL (word) */
  484. O_Ib, /* D4 AAM */
  485. O_Ib, /* D5 AAD */
  486. O_DoDB, /* D6 */
  487. O_NoOperands, /* D7 XLAT */
  488. O_x87_ESC, /* D8 ESC */
  489. O_x87_ESC, /* D9 ESC */
  490. O_x87_ESC, /* DA ESC */
  491. O_x87_ESC, /* DB ESC */
  492. O_x87_ESC, /* DC ESC */
  493. O_x87_ESC, /* DD ESC */
  494. O_x87_ESC, /* DE ESC */
  495. O_x87_ESC, /* DF ESC */
  496. O_Rel8, /* E0 LOOPNE or LOOPNZ */
  497. O_Rel8, /* E1 LOOPE or LOOPZ */
  498. O_Rel8, /* E2 LOOP */
  499. O_Rel8, /* E3 JCXZ / JECXZ (386) */
  500. O_AL_Ubyte, /* E4 IN AL, I */
  501. O_AX_Ubyte, /* E5 IN AX, I */
  502. O_Ubyte_AL, /* E6 OUT I, AL */
  503. O_Ubyte_AX, /* E7 OUT I, AX */
  504. O_Rel16, /* E8 CALL Rel16 */
  505. O_Rel16, /* E9 JMP Rel16 */
  506. O_FarPtr, /* EA JMP seg:off */
  507. O_Rel8, /* EB JMP Rel8 */
  508. O_DoInAL, /* EC IN AL, DX */
  509. O_DoInAX, /* ED IN AX, DX */
  510. O_DoOutAL, /* EE OUT DX, AL */
  511. O_DoOutAX, /* EF OUT DX, AX */
  512. O_DoRep, /* F0 LOCK */
  513. O_DoDB, /* F1 */
  514. O_DoRep, /* F2 REPNE or REPNZ */
  515. O_DoRep, /* F3 REP or REPE or REPZ */
  516. O_NoOperands, /* F4 HLT */
  517. O_NoOperands, /* F5 CMC */
  518. O_GROUP31, /* F6 TEST, NOT, NEG, MUL, IMUL, */
  519. O_GROUP32, /* F7 DIv, IDIv F6=Byte F7=Word */
  520. O_NoOperands, /* F8 CLC */
  521. O_NoOperands, /* F9 STC */
  522. O_NoOperands, /* FA CLI */
  523. O_NoOperands, /* FB STI */
  524. O_NoOperands, /* FC CLD */
  525. O_NoOperands, /* FD STD */
  526. O_GROUP4, /* FE INC, DEC mem/reg (byte) */
  527. O_GROUP5, /* FF INC, DEC, CALL, JMP, PUSH */
  528. // secondary opcode table begins. Only "filled" locations are stored
  529. // to compress the secondary table. Hence while disassembling
  530. // opcode needs to be displaced appropriately to account for the.
  531. // The displacements are defined in 86dis.c and need to be reevaluated
  532. // if new opcodes are added here.
  533. O_GROUP6, /* 0 MULTI */
  534. O_GROUP7, /* 1 MULTI */
  535. O_Reg_Modrm, /* 2 LAR */
  536. O_Reg_Modrm, /* 3 LSL */
  537. O_DoDB, /* 4 */
  538. O_NoOperands, /* 5 LOADALL */
  539. O_NoOperands, /* 6 CLTS */
  540. O_GROUP7, /* 7 MULTI */
  541. O_NoOperands, /* 8 INVD */
  542. O_NoOperands, /* 9 WBINVD */
  543. O_DoDB, /* A */
  544. O_NoOperands, /* B UD2 undefined */
  545. O_Modrm_CReg, /* 20 MOV Rd,Cd */
  546. O_Modrm_CReg, /* 21 MOV Rd,Dd */
  547. O_CReg_Modrm, /* 22 MOV Cd,Rd */
  548. O_CReg_Modrm, /* 23 MOV Dd,Rd */
  549. O_Modrm_CReg, /* 24 MOV Rd,Td */
  550. O_DoDB, /* 25 */
  551. O_CReg_Modrm, /* 26 MOV Td,Rd */
  552. O_NoOperands, /* 30 WRMSR */
  553. O_NoOperands, /* 31 RDTSC */
  554. O_NoOperands, /* 32 RDMSR */
  555. O_NoOperands, /* 33 RDPMC */
  556. O_Reg_Modrm, /* 40 CMOVO */
  557. O_Reg_Modrm, /* 41 CMOVNO */
  558. O_Reg_Modrm, /* 42 CMOVB */
  559. O_Reg_Modrm, /* 43 CMOVNB */
  560. O_Reg_Modrm, /* 44 CMOVE */
  561. O_Reg_Modrm, /* 45 CMOVNE */
  562. O_Reg_Modrm, /* 46 CMOVBE */
  563. O_Reg_Modrm, /* 47 CMOVNBE */
  564. O_Reg_Modrm, /* 48 CMOVS */
  565. O_Reg_Modrm, /* 49 CMOVNS */
  566. O_Reg_Modrm, /* 4A CMOVP */
  567. O_Reg_Modrm, /* 4B CMOVNP */
  568. O_Reg_Modrm, /* 4C CMOVL */
  569. O_Reg_Modrm, /* 4D CMOVGE */
  570. O_Reg_Modrm, /* 4E CMOVLE */
  571. O_Reg_Modrm, /* 4F CMOVNLE */
  572. O_MmReg_qModrm, /* 60 PUNPCKLBW */
  573. O_MmReg_qModrm, /* 61 PUNPCKLWD */
  574. O_MmReg_qModrm, /* 62 PUNPCKLDQ */
  575. O_MmReg_qModrm, /* 63 PACKSSWB */
  576. O_MmReg_qModrm, /* 64 PCMPGTB */
  577. O_MmReg_qModrm, /* 65 PCMPGTW */
  578. O_MmReg_qModrm, /* 66 PCMPGTD */
  579. O_MmReg_qModrm, /* 67 PACKUSWB */
  580. O_MmReg_qModrm, /* 68 PUNPCKHBW */
  581. O_MmReg_qModrm, /* 69 PUNPCKHWD */
  582. O_MmReg_qModrm, /* 6A PUNPCKHDQ */
  583. O_MmReg_qModrm, /* 6B PACKSSDW */
  584. O_DoDB, /* 6C */
  585. O_DoDB, /* 6D */
  586. O_MmReg_dModrm, /* 6E MOVD */
  587. O_MmReg_qModrm, /* 6F MOVQ */
  588. O_DoDB, /* 70 */
  589. O_PSHimw, /* 71 PS[LR][AL]W immediate */
  590. O_PSHimd, /* 72 PS[LR][AL]D immediate */
  591. O_PSHimq, /* 73 PS[LR]LQ immediate */
  592. O_MmReg_qModrm, /* 74 PCMPEQB */
  593. O_MmReg_qModrm, /* 75 PCMPEQW */
  594. O_MmReg_qModrm, /* 76 PCMPEQD */
  595. O_NoOperands, /* 77 EMMS */
  596. O_DoDB, /* 78 */
  597. O_DoDB, /* 79 */
  598. O_DoDB, /* 7A */
  599. O_DoDB, /* 7B */
  600. O_DoDB, /* 7C */
  601. O_bModrm, /* 7D SETNL */
  602. O_dModrm_MmReg, /* 7E MOVD */
  603. O_qModrm_MmReg, /* 7F MOVQ */
  604. O_Rel16, /* 80 JO */
  605. O_Rel16, /* 81 JNO */
  606. O_Rel16, /* 82 JB */
  607. O_Rel16, /* 83 JNB */
  608. O_Rel16, /* 84 JE */
  609. O_Rel16, /* 85 JNE */
  610. O_Rel16, /* 86 JBE */
  611. O_Rel16, /* 87 JNBE */
  612. O_Rel16, /* 88 JS */
  613. O_Rel16, /* 89 JNS */
  614. O_Rel16, /* 8A JP */
  615. O_Rel16, /* 8B JNP */
  616. O_Rel16, /* 8C JL */
  617. O_Rel16, /* 8D JNL */
  618. O_Rel16, /* 8E JLE */
  619. O_Rel16, /* 8F JNLE */
  620. O_bModrm, /* 90 SETO */
  621. O_bModrm, /* 91 SETNO */
  622. O_bModrm, /* 92 SETB */
  623. O_bModrm, /* 93 SETNB */
  624. O_bModrm, /* 94 SETE */
  625. O_bModrm, /* 95 SETNE */
  626. O_bModrm, /* 96 SETBE */
  627. O_bModrm, /* 97 SETNBE */
  628. O_bModrm, /* 98 SETS */
  629. O_bModrm, /* 99 SETNS */
  630. O_bModrm, /* 9A SETP */
  631. O_bModrm, /* 9B SETNP */
  632. O_bModrm, /* 9C SETL */
  633. O_bModrm, /* 9D SETGE */
  634. O_bModrm, /* 9E SETLE */
  635. O_bModrm, /* 9F SETNLE */
  636. O_sReg2, /* A0 PUSH FS */
  637. O_sReg2, /* A1 POP FS */
  638. O_NoOperands, /* A2 CPUID */
  639. O_Modrm_Reg, /* A3 BT */
  640. O_Modrm_Reg_Ib, /* A4 SHLD */
  641. O_Modrm_Reg_CL, /* A5 SHLD */
  642. O_DoDB, /* A6 */
  643. O_DoDB, /* A7 */
  644. O_sReg2, /* A8 PUSH GS */
  645. O_sReg2, /* A9 POP GS */
  646. O_NoOperands, /* AA RSM */
  647. O_vModrm_Reg, /* AB BTS */
  648. O_Modrm_Reg_Ib, /* AC SHRD */
  649. O_Modrm_Reg_CL, /* AD SHRD */
  650. O_DoDB, /* AE */
  651. O_Reg_Modrm, /* AF IMUL */
  652. O_bModrm_Reg, /* B0 CMPXCH */
  653. O_Modrm_Reg, /* B1 CMPXCH */
  654. O_fReg_Modrm, /* B2 LSS */
  655. O_Modrm_Reg, /* B3 BTR */
  656. O_fReg_Modrm, /* B4 LFS */
  657. O_fReg_Modrm, /* B5 LGS */
  658. O_Reg_bModrm, /* B6 MOVZX */
  659. O_Reg_wModrm, /* B7 MOVZX */
  660. O_DoDB, /* B8 */
  661. O_DoDB, /* B9 */
  662. O_GROUP8, /* BA MULTI */
  663. O_Modrm_Reg, /* BB BTC */
  664. O_Reg_Modrm, /* BC BSF */
  665. O_Reg_Modrm, /* BD BSR */
  666. O_Reg_bModrm, /* BE MOVSX */
  667. O_Reg_wModrm, /* BF MOVSX */
  668. O_bModrm_Reg, /* C0 XADD */
  669. O_Modrm_Reg, /* C1 XADD */
  670. O_DoDB, /* C2 */
  671. O_DoDB, /* C3 */
  672. O_DoDB, /* C4 */
  673. O_DoDB, /* C5 */
  674. O_DoDB, /* C6 */
  675. O_qModrm, /* C7 CMPXCHG8B */
  676. O_oReg, /* C8 BSWAP */
  677. O_oReg, /* C9 BSWAP */
  678. O_oReg, /* CA BSWAP */
  679. O_oReg, /* CB BSWAP */
  680. O_oReg, /* CC BSWAP */
  681. O_oReg, /* CD BSWAP */
  682. O_oReg, /* CE BSWAP */
  683. O_oReg, /* CF BSWAP */
  684. O_DoDB, /* D0 */
  685. O_MmReg_qModrm, /* D1 PSRLW */
  686. O_MmReg_qModrm, /* D2 PSRLD */
  687. O_MmReg_qModrm, /* D3 PSRLQ */
  688. O_DoDB, /* D4 */
  689. O_MmReg_qModrm, /* D5 PMULLW */
  690. O_DoDB, /* D6 */
  691. O_DoDB, /* D7 */
  692. O_MmReg_qModrm, /* D8 PSUBUSB */
  693. O_MmReg_qModrm, /* D9 PSUBUSW */
  694. O_DoDB, /* DA */
  695. O_MmReg_qModrm, /* DB PAND */
  696. O_MmReg_qModrm, /* DC PADDUSB */
  697. O_MmReg_qModrm, /* DD PADDUSW */
  698. O_DoDB, /* DE */
  699. O_MmReg_qModrm, /* DF PANDN */
  700. O_DoDB, /* E0 */
  701. O_MmReg_qModrm, /* E1 PSRAW */
  702. O_MmReg_qModrm, /* E2 PSRAD */
  703. O_DoDB, /* E3 */
  704. O_DoDB, /* E4 */
  705. O_MmReg_qModrm, /* E5 PMULHW */
  706. O_DoDB, /* E6 */
  707. O_DoDB, /* E7 */
  708. O_MmReg_qModrm, /* E8 PSUBSB */
  709. O_MmReg_qModrm, /* E9 PSUBSW */
  710. O_DoDB, /* EA */
  711. O_MmReg_qModrm, /* EB POR */
  712. O_MmReg_qModrm, /* EC PADDSB */
  713. O_MmReg_qModrm, /* ED PADDSW */
  714. O_DoDB, /* EE */
  715. O_MmReg_qModrm, /* EF PXOR */
  716. O_DoDB, /* F0 */
  717. O_MmReg_qModrm, /* F1 PSLLW */
  718. O_MmReg_qModrm, /* F2 PSLLD */
  719. O_MmReg_qModrm, /* F3 PSLLQ */
  720. O_DoDB, /* F4 */
  721. O_MmReg_qModrm, /* F5 PMADDWD */
  722. O_DoDB, /* F6 */
  723. O_DoDB, /* F7 */
  724. O_MmReg_qModrm, /* F8 PSUBB */
  725. O_MmReg_qModrm, /* F9 PSUBW */
  726. O_MmReg_qModrm, /* FA PSUBD */
  727. O_DoDB, /* FB */
  728. O_MmReg_qModrm, /* FC PADDB */
  729. O_MmReg_qModrm, /* FD PADDW */
  730. O_MmReg_qModrm, /* FE PADDD */
  731. };
  732. Tdistbl groupt[][8] = {
  733. /* 00 00 x87-D8-1 */
  734. { O_dModrm, /* D8-0 FADD */
  735. O_dModrm, /* D8-1 FMUL */
  736. O_dModrm, /* D8-2 FCOM */
  737. O_dModrm, /* D8-3 FCOMP */
  738. O_dModrm, /* D8-4 FSUB */
  739. O_dModrm, /* D8-5 FSUBR */
  740. O_dModrm, /* D8-6 FDIV */
  741. O_dModrm }, /* D8-7 FDIVR */
  742. /* 01 x87-D8-2 */
  743. { O_ST_iST, /* D8-0 FADD */
  744. O_ST_iST, /* D8-1 FMUL */
  745. O_iST, /* D8-2 FCOM */
  746. O_iST, /* D8-3 FCOMP */
  747. O_ST_iST, /* D8-4 FSUB */
  748. O_ST_iST, /* D8-5 FSUBR */
  749. O_ST_iST, /* D8-6 FDIV */
  750. O_ST_iST }, /* D8-7 FDIVR */
  751. /* 02 01 x87-D9-1 */
  752. { O_dModrm, /* D9-0 FLD */
  753. O_DoDB, /* D9-1 */
  754. O_dModrm, /* D9-2 FST */
  755. O_dModrm, /* D9-3 FSTP */
  756. O_Modrm, /* D9-4 FLDENV */
  757. O_Modrm, /* D9-5 FLDCW */
  758. O_Modrm, /* D9-6 FSTENV */
  759. O_Modrm }, /* D9-7 FSTCW */
  760. /* 03 01 x87-D9-2 TTT=0,1,2,3 */
  761. { O_iST, /* D9-0 FLD */
  762. O_iST, /* D9-1 FXCH */
  763. O_NoOperands, /* D9-2 FNOP */
  764. O_iST, /* D9-3 FSTP */
  765. O_DoDB, /* D9-4 */
  766. O_DoDB, /* D9-5 */
  767. O_DoDB, /* D9-6 */
  768. O_DoDB }, /* D9-7 */
  769. /* 04 02 x89-DA-1 */
  770. { O_dModrm, /* DA-0 FIADD */
  771. O_dModrm, /* DA-1 FIMUL */
  772. O_dModrm, /* DA-2 FICOM */
  773. O_dModrm, /* DA-3 FICOMP */
  774. O_dModrm, /* DA-4 FISUB */
  775. O_dModrm, /* DA-5 FISUBR */
  776. O_dModrm, /* DA-6 FIDIV */
  777. O_dModrm }, /* DA-7 FIDIVR */
  778. /* 05 x87-DA-2 */
  779. { O_ST_iST, /* DA-0 FCMOVB */
  780. O_ST_iST, /* DA-1 FCMOVE */
  781. O_ST_iST, /* DA-2 FCMOVBE */
  782. O_ST_iST, /* DA-3 FCMOVU */
  783. O_DoDB, /* DA-4 */
  784. O_NoOperands, /* DA-5 */
  785. O_DoDB, /* DA-6 */
  786. O_DoDB }, /* DA-7 */
  787. /* 06 03 x87-DB-1 */
  788. { O_dModrm, /* DB-0 FILD */
  789. O_DoDB, /* DB-1 */
  790. O_dModrm, /* DB-2 FIST */
  791. O_dModrm, /* DB-3 FISTP */
  792. O_DoDB, /* DB-4 */
  793. O_tModrm, /* DB-5 FLD */
  794. O_DoDB, /* DB-6 */
  795. O_tModrm }, /* DB-7 FSTP */
  796. /* 07 x87-DB-2 ttt=4 */
  797. { O_NoOperands, /* DB-0 FENI */
  798. O_NoOperands, /* DB-1 FDISI */
  799. O_NoOperands, /* DB-2 FCLEX */
  800. O_NoOperands, /* DB-3 FINIT */
  801. O_DoDB, /* DB-4 FSETPM */
  802. O_DoDB, /* DB-5 */
  803. O_DoDB, /* DB-6 */
  804. O_DoDB }, /* DB-7 */
  805. /* 08 04 x87-DC-1 */
  806. { O_qModrm, /* DC-0 FADD */
  807. O_qModrm, /* DC-1 FMUL */
  808. O_qModrm, /* DC-2 FCOM */
  809. O_qModrm, /* DC-3 FCOMP */
  810. O_qModrm, /* DC-4 FSUB */
  811. O_qModrm, /* DC-5 FSUBR */
  812. O_qModrm, /* DC-6 FDIV */
  813. O_qModrm }, /* DC-7 FDIVR */
  814. /* 09 x87-DC-2 */
  815. { O_iST_ST, /* DC-0 FADD */
  816. O_iST_ST, /* DC-1 FMUL */
  817. O_iST, /* DC-2 FCOM */
  818. O_iST, /* DC-3 FCOMP */
  819. O_iST_ST, /* DC-4 FSUB */
  820. O_iST_ST, /* DC-5 FSUBR */
  821. O_iST_ST, /* DC-6 FDIVR */
  822. O_iST_ST }, /* DC-7 FDIV */
  823. /* 10 05 x87-DD-1 */
  824. { O_qModrm, /* DD-0 FLD */
  825. O_DoDB, /* DD-1 */
  826. O_qModrm, /* DD-2 FST */
  827. O_qModrm, /* DD-3 FSTP */
  828. O_Modrm, /* DD-4 FRSTOR */
  829. O_DoDB, /* DD-5 */
  830. O_Modrm, /* DD-6 FSAVE */
  831. O_Modrm }, /* DD-7 FSTSW */
  832. /* 11 x87-DD-2 */
  833. { O_iST, /* DD-0 FFREE */
  834. O_iST, /* DD-1 FXCH */
  835. O_iST, /* DD-2 FST */
  836. O_iST, /* DD-3 FSTP */
  837. O_iST, /* DD-4 FUCOM */
  838. O_iST, /* DD-5 FUCOMP */
  839. O_DoDB, /* DD-6 */
  840. O_DoDB }, /* DD-7 */
  841. /* 12 06 x87-DE-1 */
  842. { O_wModrm, /* DE-0 FIADD */
  843. O_wModrm, /* DE-1 FIMUL */
  844. O_wModrm, /* DE-2 FICOM */
  845. O_wModrm, /* DE-3 FICOMP */
  846. O_wModrm, /* DE-4 FISUB */
  847. O_wModrm, /* DE-5 FISUBR */
  848. O_wModrm, /* DE-6 FIDIV */
  849. O_wModrm }, /* DE-7 FIDIVR */
  850. /* 13 x87-DE-2 */
  851. { O_iST_ST, /* DE-0 FADDP */
  852. O_iST_ST, /* DE-1 FMULP */
  853. O_iST, /* DE-2 FCOMP */
  854. O_NoOperands, /* DE-3 FCOMPP */
  855. O_iST_ST, /* DE-4 FSUBP */
  856. O_iST_ST, /* DE-5 FSUBRP */
  857. O_iST_ST, /* DE-6 FDIVP */
  858. O_iST_ST }, /* DE-7 FDIVRP */
  859. /* 14 07 x87-DF-1 */
  860. { O_wModrm, /* DF-0 FILD */
  861. O_DoDB, /* DF-1 */
  862. O_wModrm, /* DF-2 FIST */
  863. O_wModrm, /* DF-3 FISTP */
  864. O_tModrm, /* DF-4 FBLD */
  865. O_qModrm, /* DF-5 FILD */
  866. O_tModrm, /* DF-6 FBSTP */
  867. O_qModrm }, /* DF-7 FISTP */
  868. /* 15 x87-DF-2 */
  869. { O_iST, /* DF-0 FFREE */
  870. O_iST, /* DF-1 FXCH */
  871. O_iST, /* DF-2 FST */
  872. O_iST, /* DF-3 FSTP */
  873. O_NoOperands, /* DF-4 FSTSW */
  874. O_ST_iST, /* DF-5 FUCOMIP */
  875. O_ST_iST, /* DF-6 FCOMIP */
  876. O_DoDB }, /* DF-7 */
  877. /* 16 01 x87-D9 Mod=3 TTT=4 */
  878. { O_NoOperands, /* D9-0 FCHS */
  879. O_NoOperands, /* D9-1 FABS */
  880. O_DoDB, /* D9-2 */
  881. O_DoDB, /* D9-3 */
  882. O_NoOperands, /* D9-4 FTST */
  883. O_NoOperands, /* D9-5 FXAM */
  884. O_DoDB, /* D9-6 */
  885. O_DoDB }, /* D9-7 */
  886. /* 17 01 x87-D9 Mod=3 TTT=5 */
  887. { O_NoOperands, /* D9-0 FLD1 */
  888. O_NoOperands, /* D9-1 FLDL2T */
  889. O_NoOperands, /* D9-2 FLDL2E */
  890. O_NoOperands, /* D9-3 FLDPI */
  891. O_NoOperands, /* D9-4 FLDLG2 */
  892. O_NoOperands, /* D9-5 FLDLN2 */
  893. O_NoOperands, /* D9-6 FLDZ */
  894. O_DoDB }, /* D9-7 */
  895. /* 18 01 x87-D9 Mod=3 TTT=6 */
  896. { O_NoOperands, /* D9-0 F2XM1 */
  897. O_NoOperands, /* D9-1 FYL2X */
  898. O_NoOperands, /* D9-2 FPTAN */
  899. O_NoOperands, /* D9-3 FPATAN */
  900. O_NoOperands, /* D9-4 FXTRACT */
  901. O_NoOperands, /* D9-5 FPREM1 */
  902. O_NoOperands, /* D9-6 FDECSTP */
  903. O_NoOperands }, /* D9-7 FINCSTP */
  904. /* 19 01 x87-D9 Mod=3 TTT=7 */
  905. { O_NoOperands, /* D9-0 FPREM */
  906. O_NoOperands, /* D9-1 FYL2XP1 */
  907. O_NoOperands, /* D9-2 FSQRT */
  908. O_NoOperands, /* D9-3 FSINCOS */
  909. O_NoOperands, /* D9-4 FRNDINT */
  910. O_NoOperands, /* D9-5 FSCALE */
  911. O_NoOperands, /* D9-6 FSIN */
  912. O_NoOperands }, /* D9-7 FCOS */
  913. /* 20 group 3 */
  914. { O_bModrm_Ib, /* F6-0 TEST */
  915. O_DoDB, /* F6-1 */
  916. O_bModrm, /* F6-2 NOT */
  917. O_bModrm, /* F6-3 NEG */
  918. O_bModrm, /* F6-4 MUL */
  919. O_bModrm, /* F6-5 IMUL */
  920. O_bModrm, /* F6-6 DIV */
  921. O_bModrm }, /* F6-7 IDIV */
  922. /* 21 group 3 */
  923. { O_vModrm_Iv, /* F7-0 TEST */
  924. O_DoDB, /* F7-1 */
  925. O_vModrm, /* F7-2 NOT */
  926. O_vModrm, /* F7-3 NEG */
  927. O_vModrm, /* F7-4 MUL */
  928. O_vModrm, /* F7-5 IMUL */
  929. O_vModrm, /* F7-6 DIV */
  930. O_vModrm }, /* F7-7 IDIV */
  931. /* 22 group 5 */
  932. { O_vModrm, /* FF-0 INC */
  933. O_vModrm, /* FF-1 DEC */
  934. O_vModrm, /* FF-2 CALL */
  935. O_fModrm, /* FF-3 CALL */
  936. O_vModrm, /* FF-4 JMP */
  937. O_fModrm, /* FF-5 JMP */
  938. O_vModrm, /* FF-6 PUSH */
  939. O_DoDB }, /* FF-7 */
  940. /* 23 group 7 */
  941. { O_Modrm, /* 0F-0 SGDT */
  942. O_Modrm, /* 0F-1 SIDT */
  943. O_Modrm, /* 0F-2 LGDT */
  944. O_Modrm, /* 0F-3 LIDT */
  945. O_wModrm, /* 0F-4 MSW */
  946. O_DoDB, /* 0F-5 */
  947. O_wModrm, /* 0F-6 LMSW */
  948. O_Modrm }, /* 0F-7 INVLPG */
  949. /* 24 x87-DB Mod=3 TTT != 4 */
  950. { O_ST_iST, /* DB-0 FCMOVNB */
  951. O_ST_iST, /* DB-1 FCMOVNE */
  952. O_ST_iST, /* DB-2 FCMOVNBE */
  953. O_ST_iST, /* DB-3 FCMOVNU */
  954. O_DoDB, /* DB-4 */
  955. O_ST_iST, /* DB-5 FUCOMI */
  956. O_ST_iST, /* DB-6 FCOMI */
  957. O_DoDB } /* DB-7 */
  958. };
  959. DWORD
  960. GetInstructionLengthFromAddress(LPBYTE pEip)
  961. {
  962. int G_mode_32;
  963. int mode_32; // local addressing mode indicator
  964. int opsize_32; // operand size flag
  965. int opcode; // current opcode
  966. int olen = 2; // operand length
  967. int alen = 2; // address length
  968. int end = FALSE; // end of instruction flag
  969. int mrm = FALSE; // indicator that modrm is generated
  970. unsigned char *action; // action for operand interpretation
  971. long tmp; // temporary storage field
  972. int indx; // temporary index
  973. int action2; // secondary action
  974. int instlen; // instruction length
  975. int segOvr = 0; // segment override opcode
  976. unsigned char BOPaction;
  977. int subcode; // bop subcode
  978. DECODEDATA decodeData;
  979. decodeData.mod = 0;
  980. decodeData.rm = 0;
  981. decodeData.ttt = 0;
  982. decodeData.fMovX = FALSE;
  983. decodeData.fMmRegEa = FALSE;
  984. decodeData.EAsize[0] = decodeData.EAsize[1] = 0; // no effective address
  985. G_mode_32 = 1;
  986. mode_32 = opsize_32 = (G_mode_32 == 1); // local addressing mode
  987. olen = alen = (1 + mode_32) << 1; // set operand/address lengths
  988. // 2 for 16-bit and 4 for 32-bit
  989. decodeData.pMem = pEip; // point to begin of instruction
  990. opcode = *(decodeData.pMem)++; // get opcode
  991. if (opcode == 0xc4 && *(decodeData.pMem) == 0xC4)
  992. {
  993. (decodeData.pMem)++;
  994. action = &BOPaction;
  995. BOPaction = IB | END;
  996. subcode = *(decodeData.pMem);
  997. if (subcode == 0x50 || subcode == 0x52 ||
  998. subcode == 0x53 || subcode == 0x54 ||
  999. subcode == 0x57 || subcode == 0x58 ||
  1000. subcode == 0x58)
  1001. {
  1002. BOPaction = IW | END;
  1003. }
  1004. } else
  1005. {
  1006. action = actiontbl + distbl[opcode].opr; /* get operand action */
  1007. }
  1008. // loop through all operand actions
  1009. do {
  1010. action2 = (*action) & 0xc0;
  1011. switch((*action++) & 0x3f) {
  1012. case ALT: // alter the opcode if 32-bit
  1013. if (opsize_32)
  1014. {
  1015. indx = *action++;
  1016. }
  1017. break;
  1018. case STROP:
  1019. // compute size of operands in indx
  1020. // also if dword operands, change fifth
  1021. // opcode letter from 'w' to 'd'.
  1022. if (opcode & 1)
  1023. {
  1024. if (opsize_32)
  1025. {
  1026. indx = 4;
  1027. }
  1028. else
  1029. {
  1030. indx = 2;
  1031. }
  1032. }
  1033. else
  1034. {
  1035. indx = 1;
  1036. }
  1037. break;
  1038. case CHR: // insert a character
  1039. action++;
  1040. break;
  1041. case CREG: // set debug, test or control reg
  1042. break;
  1043. case SREG2: // segment register
  1044. // Handle special case for fs/gs (OPC0F adds SECTAB_OFFSET_5
  1045. // to these codes)
  1046. if (opcode > 0x7e)
  1047. {
  1048. decodeData.ttt = BIT53((opcode-SECTAB_OFFSET_5));
  1049. }
  1050. else
  1051. {
  1052. decodeData.ttt = BIT53(opcode); // set value to fall through
  1053. }
  1054. case SREG3: // segment register
  1055. break;
  1056. case BRSTR: // get index to register string
  1057. decodeData.ttt = *action++; // from action table
  1058. goto BREGlabel;
  1059. case BOREG: // byte register (in opcode)
  1060. decodeData.ttt = BIT20(opcode); // register is part of opcode
  1061. goto BREGlabel;
  1062. case ALSTR:
  1063. decodeData.ttt = 0; // point to AL register
  1064. BREGlabel:
  1065. case BREG: // general register
  1066. break;
  1067. case WRSTR: // get index to register string
  1068. decodeData.ttt = *action++; // from action table
  1069. goto WREGlabel;
  1070. case VOREG: // register is part of opcode
  1071. decodeData.ttt = BIT20(opcode);
  1072. goto VREGlabel;
  1073. case AXSTR:
  1074. decodeData.ttt = 0; // point to eAX register
  1075. VREGlabel:
  1076. case VREG: // general register
  1077. WREGlabel:
  1078. case WREG: // register is word size
  1079. break;
  1080. case MMWREG:
  1081. break;
  1082. case IST_ST:
  1083. break;
  1084. case ST_IST:
  1085. ;
  1086. case IST:
  1087. ;
  1088. break;
  1089. case xBYTE: // set instruction to byte only
  1090. decodeData.EAsize[0] = 1;
  1091. break;
  1092. case VAR:
  1093. if (opsize_32)
  1094. goto DWORDlabel;
  1095. case xWORD:
  1096. decodeData.EAsize[0] = 2;
  1097. break;
  1098. case EDWORD:
  1099. opsize_32 = 1; // for control reg move, use eRegs
  1100. case xDWORD:
  1101. DWORDlabel:
  1102. decodeData.EAsize[0] = 4;
  1103. break;
  1104. case MMQWORD:
  1105. decodeData.fMmRegEa = TRUE;
  1106. case QWORD:
  1107. decodeData.EAsize[0] = 8;
  1108. break;
  1109. case xTBYTE:
  1110. decodeData.EAsize[0] = 10;
  1111. break;
  1112. case FARPTR:
  1113. if (opsize_32) {
  1114. decodeData.EAsize[0] = 6;
  1115. }
  1116. else {
  1117. decodeData.EAsize[0] = 4;
  1118. }
  1119. break;
  1120. case LMODRM: // output modRM data type
  1121. if (decodeData.mod != 3)
  1122. ;
  1123. else
  1124. decodeData.EAsize[0] = 0;
  1125. case MODRM: // output modrm string
  1126. if (segOvr) // in case of segment override
  1127. 0;
  1128. break;
  1129. case ADDRP: // address pointer
  1130. decodeData.pMem += olen + 2;
  1131. break;
  1132. case REL8: // relative address 8-bit
  1133. tmp = (long)*(char *)(decodeData.pMem)++; // get the 8-bit rel offset
  1134. goto DoRelDispl;
  1135. case REL16: // relative address 16-/32-bit
  1136. tmp = 0;
  1137. if (mode_32)
  1138. MoveMemory(&tmp,decodeData.pMem,sizeof(long));
  1139. else
  1140. MoveMemory(&tmp,decodeData.pMem,sizeof(short));
  1141. decodeData.pMem += alen; // skip over offset
  1142. DoRelDispl:
  1143. break;
  1144. case UBYTE: // unsigned byte for int/in/out
  1145. decodeData.pMem++;
  1146. break;
  1147. case IB: // operand is immediate byte
  1148. if ((opcode & ~1) == 0xd4) { // postop for AAD/AAM is 0x0a
  1149. if (*(decodeData.pMem)++ != 0x0a) // test post-opcode byte
  1150. 0;
  1151. break;
  1152. }
  1153. olen = 1; // set operand length
  1154. goto DoImmed;
  1155. case IW: // operand is immediate word
  1156. olen = 2; // set operand length
  1157. case IV: // operand is word or dword
  1158. DoImmed:
  1159. decodeData.pMem += olen;
  1160. break;
  1161. case OFFS: // operand is offset
  1162. decodeData.EAsize[0] = (opcode & 1) ? olen : 1;
  1163. if (segOvr) // in case of segment override
  1164. 0;
  1165. decodeData.pMem += alen;
  1166. break;
  1167. case GROUP: // operand is of group 1,2,4,6 or 8
  1168. action++; // output opcode symbol
  1169. break;
  1170. case GROUPT: // operand is of group 3,5 or 7
  1171. indx = *action; // get indx into group from action
  1172. goto doGroupT;
  1173. case EGROUPT: // x87 ESC (D8-DF) group index
  1174. indx = BIT20(opcode) * 2; // get group index from opcode
  1175. if (decodeData.mod == 3)
  1176. { // some operand variations exists
  1177. // for x87 and mod == 3
  1178. ++indx; // take the next group table entry
  1179. if (indx == 3)
  1180. { // for x87 ESC==D9 and mod==3
  1181. if (decodeData.ttt > 3)
  1182. { // for those D9 instructions
  1183. indx = 12 + decodeData.ttt; // offset index to table by 12
  1184. decodeData.ttt = decodeData.rm; // set secondary index to rm
  1185. }
  1186. }
  1187. else if (indx == 7)
  1188. { // for x87 ESC==DB and mod==3
  1189. if (decodeData.ttt == 4)
  1190. {
  1191. decodeData.ttt = decodeData.rm; // set secondary group table index
  1192. } else if ((decodeData.ttt<4)||(decodeData.ttt>4 && decodeData.ttt<7))
  1193. {
  1194. // adjust for pentium pro opcodes
  1195. indx = 24; // offset index to table by 24
  1196. }
  1197. }
  1198. }
  1199. doGroupT:
  1200. // handle group with different types of operands
  1201. action = actiontbl + groupt[indx][decodeData.ttt].opr;
  1202. // get new action
  1203. break;
  1204. //
  1205. // The secondary opcode table has been compressed in the
  1206. // original design. Hence while disassembling the 0F sequence,
  1207. // opcode needs to be displaced by an appropriate amount depending
  1208. // on the number of "filled" entries in the secondary table.
  1209. // These displacements are used throughout the code.
  1210. //
  1211. case OPC0F: // secondary opcode table (opcode 0F)
  1212. opcode = *(decodeData.pMem)++; // get real opcode
  1213. decodeData.fMovX = (BOOL)(opcode == 0xBF || opcode == 0xB7);
  1214. if (opcode < 12) // for the first 12 opcodes
  1215. opcode += SECTAB_OFFSET_1; // point to begin of sec op tab
  1216. else if (opcode > 0x1f && opcode < 0x27)
  1217. opcode += SECTAB_OFFSET_2; // adjust for undefined opcodes
  1218. else if (opcode > 0x2f && opcode < 0x34)
  1219. opcode += SECTAB_OFFSET_3; // adjust for undefined opcodes
  1220. else if (opcode > 0x3f && opcode < 0x50)
  1221. opcode += SECTAB_OFFSET_4; // adjust for undefined opcodes
  1222. else if (opcode > 0x5f && opcode < 0xff)
  1223. opcode += SECTAB_OFFSET_5; // adjust for undefined opcodes
  1224. else
  1225. opcode = SECTAB_OFFSET_UNDEF; // all non-existing opcodes
  1226. goto getNxtByte1;
  1227. case ADR_OVR: // address override
  1228. mode_32 = !G_mode_32; // override addressing mode
  1229. alen = (mode_32 + 1) << 1; // toggle address length
  1230. goto getNxtByte;
  1231. case OPR_OVR: // operand size override
  1232. opsize_32 = !G_mode_32; // override operand size
  1233. olen = (opsize_32 + 1) << 1; // toggle operand length
  1234. goto getNxtByte;
  1235. case SEG_OVR: // handle segment override
  1236. segOvr = opcode; // save segment override opcode
  1237. goto getNxtByte;
  1238. case REP: // handle rep/lock prefixes
  1239. getNxtByte:
  1240. opcode = *(decodeData.pMem)++; // next byte is opcode
  1241. getNxtByte1:
  1242. action = actiontbl + distbl[opcode].opr;
  1243. default: // opcode has no operand
  1244. break;
  1245. }
  1246. switch (action2)
  1247. { // secondary action
  1248. case MRM: // generate modrm for later use
  1249. if (!mrm)
  1250. { // ignore if it has been generated
  1251. //DIdoModrm(segOvr, &decodeData);
  1252. int newmrm; // modrm byte
  1253. int sib = 0;
  1254. int ss;
  1255. int ind;
  1256. int oldrm;
  1257. newmrm = *(decodeData.pMem)++; // get the mrm byte from instruction
  1258. decodeData.mod = BIT76(newmrm); // get mod
  1259. decodeData.ttt = BIT53(newmrm); // get reg - used outside routine
  1260. decodeData.rm = BIT20(newmrm); // get rm
  1261. if (decodeData.mod == 3)
  1262. { // register only mode
  1263. decodeData.EAsize[0] = 0; // no EA value to output
  1264. }
  1265. else
  1266. {
  1267. // 32-bit addressing mode
  1268. oldrm = decodeData.rm;
  1269. if (decodeData.rm == 4)
  1270. { // rm == 4 implies sib byte
  1271. sib = *(decodeData.pMem)++; // get s_i_b byte
  1272. decodeData.rm = BIT20(sib); // return base
  1273. }
  1274. if (decodeData.mod == 0 && decodeData.rm == 5)
  1275. {
  1276. decodeData.pMem += 4;
  1277. }
  1278. if (oldrm == 4)
  1279. {
  1280. // finish processing sib
  1281. ind = BIT53(sib);
  1282. if (ind != 4)
  1283. {
  1284. ss = 1 << BIT76(sib);
  1285. }
  1286. }
  1287. // output any displacement
  1288. if (decodeData.mod == 1)
  1289. {
  1290. decodeData.pMem++;
  1291. }
  1292. else if (decodeData.mod == 2)
  1293. {
  1294. decodeData.pMem += 4;
  1295. }
  1296. }
  1297. mrm = TRUE; // remember its generation
  1298. }
  1299. break;
  1300. case COM: // insert a comma after operand
  1301. break;
  1302. case END: // end of instruction
  1303. end = TRUE;
  1304. break;
  1305. }
  1306. }
  1307. while (!end); // loop til end of instruction
  1308. instlen = (decodeData.pMem) - pEip;
  1309. return instlen;
  1310. }
  1311. #endif
  1312. IMPLEMENT_SHIM_END