x86_64.h 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456
  1. /* Universal Disassembler Function Library
  2. * https://gitlab.com/bztsrc/udisasm
  3. *
  4. * ----- (NOT YET) GENERATED FILE, DO NOT EDIT! -----
  5. *
  6. * Copyright (C) 2017 bzt (bztsrc@gitlab)
  7. *
  8. * Permission is hereby granted, free of charge, to any person
  9. * obtaining a copy of this software and associated documentation
  10. * files (the "Software"), to deal in the Software without
  11. * restriction, including without limitation the rights to use, copy,
  12. * modify, merge, publish, distribute, sublicense, and/or sell copies
  13. * of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be
  17. * included in all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  23. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  24. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  26. * DEALINGS IN THE SOFTWARE.
  27. *
  28. * @brief Disassembler source generated from x86_64.txt
  29. */
  30. #define disasm_arch "x86_64"
  31. /*** private functions ***/
  32. enum {
  33. DA_BYTE,
  34. DA_WORD,
  35. DA_LONG,
  36. DA_QUAD,
  37. DA_SNGL,
  38. DA_DBLR,
  39. DA_EXTR,
  40. DA_SDEP,
  41. DA_NONE,
  42. DA_MODRM=0x80
  43. };
  44. enum {
  45. DA_INVALID,
  46. DA_E,
  47. DA_EInd,
  48. DA_Ew,
  49. DA_Eb,
  50. DA_R,
  51. DA_Rw,
  52. DA_Ri,
  53. DA_S,
  54. DA_Si,
  55. DA_A,
  56. DA_BX,
  57. DA_CL,
  58. DA_DX,
  59. DA_SI,
  60. DA_DI,
  61. DA_CR,
  62. DA_DR,
  63. DA_TR,
  64. DA_I,
  65. DA_Is,
  66. DA_Ib,
  67. DA_Ibs,
  68. DA_Iw,
  69. DA_Iq,
  70. DA_O,
  71. DA_Db,
  72. DA_Dl,
  73. DA_o1,
  74. DA_o3,
  75. DA_OS,
  76. DA_ST,
  77. DA_STI,
  78. DA_X,
  79. DA_XA,
  80. DA_Ril,
  81. DA_Iba,
  82. DA_ME,
  83. DA_Rq,
  84. DA2_A_Ri = DA_A*256+DA_Ri,
  85. DA2_I_Ri = DA_I*256+DA_Ri,
  86. DA2_Ib_Ri = DA_Ib*256+DA_Ri,
  87. DA2_Iq_Ri = DA_Iq*256+DA_Ri,
  88. DA2_Iq_Ib = DA_Iq*256+DA_Ib,
  89. DA2_E_R = DA_E*256+DA_R,
  90. DA2_E_A = DA_E*256+DA_A,
  91. DA2_O_A = DA_O*256+DA_A,
  92. DA2_A_O = DA_A*256+DA_O,
  93. DA2_Eb_R = DA_Eb*256+DA_R,
  94. DA2_Ew_R = DA_Ew*256+DA_R,
  95. DA2_Ei_R = DA_EInd*256+DA_R,
  96. DA2_CL_E = DA_CL*256+DA_E,
  97. DA2_R_E = DA_R*256+DA_E,
  98. DA2_R_I = DA_R*256+DA_I,
  99. DA2_I_E = DA_I*256+DA_E,
  100. DA2_Ib_E = DA_Ib*256+DA_E,
  101. DA2_Iw_E = DA_Iw*256+DA_E,
  102. DA2_I_EInd= DA_I*256+DA_EInd,
  103. DA2_I_A = DA_I*256+DA_A,
  104. DA2_Ib_A = DA_Ib*256+DA_A,
  105. DA2_A_Ib = DA_A*256+DA_Ib,
  106. DA2_DX_A = DA_DX*256+DA_A,
  107. DA2_A_DX = DA_A*256+DA_DX,
  108. DA2_CR_E = DA_CR*256+DA_E,
  109. DA2_DR_E = DA_DR*256+DA_E,
  110. DA2_TR_E = DA_DR*256+DA_E,
  111. DA2_E_CR = DA_E*256+DA_CR,
  112. DA2_E_DR = DA_E*256+DA_DR,
  113. DA2_E_TR = DA_E*256+DA_TR,
  114. DA2_S_Ew = DA_S*256+DA_Ew,
  115. DA2_Ew_S = DA_Ew*256+DA_S,
  116. DA2_STI_ST= DA_STI*256+DA_ST,
  117. DA2_ST_STI= DA_ST*256+DA_STI,
  118. DA2_SI_DI = DA_SI*256+DA_DI,
  119. DA2_DX_DI = DA_DX*256+DA_DI,
  120. DA2_SI_DX = DA_SI*256+DA_DX,
  121. DA2_o1_E = DA_o1*256+DA_E,
  122. DA3_Ib_R_E= DA_Ib*65536+DA_R*256+DA_E,
  123. DA3_CL_R_E= DA_CL*65536+DA_R*256+DA_E,
  124. DA3_Ib_E_R= DA_Ib*65536+DA_E*256+DA_R,
  125. DA3_CL_E_R= DA_CL*65536+DA_E*256+DA_R,
  126. DA3_I_E_R = DA_I*65536+DA_E*256+DA_R
  127. };
  128. /* opcodes
  129. * 1 byte: inst_tbl
  130. * 2 bytes: first byte 0f, inst_tbl0f -> inst0fX
  131. */
  132. typedef struct {
  133. char *name;
  134. uint8_t size;
  135. uint32_t mode;
  136. void *ext;
  137. } instdesc;
  138. char *grp1[] = {
  139. "add",
  140. "or",
  141. "adc",
  142. "sbb",
  143. "and",
  144. "sub",
  145. "xor",
  146. "cmp"
  147. };
  148. char *grp2[] = {
  149. "rol",
  150. "ror",
  151. "rcl",
  152. "rcr",
  153. "shl",
  154. "shr",
  155. "sal",
  156. "sar"
  157. };
  158. instdesc grp3[] = {
  159. { "test", DA_NONE+DA_MODRM, DA2_I_E, 0 },
  160. { "test", DA_NONE+DA_MODRM, DA2_I_E, 0 },
  161. { "not", DA_NONE+DA_MODRM, DA_E, 0 },
  162. { "neg", DA_NONE+DA_MODRM, DA_E, 0 },
  163. { "mul", DA_NONE+DA_MODRM, DA2_E_A, 0 },
  164. { "imul", DA_NONE+DA_MODRM, DA2_E_A, 0 },
  165. { "div", DA_NONE+DA_MODRM, DA2_E_A, 0 },
  166. { "idiv", DA_NONE+DA_MODRM, DA2_E_A, 0 },
  167. };
  168. instdesc grp4[] = {
  169. { "inc", DA_BYTE+DA_MODRM, DA_E, 0 },
  170. { "dec", DA_BYTE+DA_MODRM, DA_E, 0 },
  171. { "", DA_NONE+DA_MODRM, 0, 0 },
  172. { "", DA_NONE+DA_MODRM, 0, 0 },
  173. { "", DA_NONE+DA_MODRM, 0, 0 },
  174. { "", DA_NONE+DA_MODRM, 0, 0 },
  175. { "", DA_NONE+DA_MODRM, 0, 0 },
  176. { "", DA_NONE+DA_MODRM, 0, 0 }
  177. };
  178. instdesc grp5[] = {
  179. { "inc", DA_LONG+DA_MODRM, DA_E, 0 },
  180. { "dec", DA_LONG+DA_MODRM, DA_E, 0 },
  181. { "call", DA_QUAD+DA_MODRM, DA_EInd, 0 },
  182. { "lcall", DA_NONE+DA_MODRM, DA_EInd, 0 },
  183. { "jmp", DA_NONE+DA_MODRM, DA_EInd, 0 },
  184. { "ljmp", DA_NONE+DA_MODRM, DA_EInd, 0 },
  185. { "push", DA_QUAD+DA_MODRM, DA_E, 0 },
  186. { "", DA_NONE+DA_MODRM, 0, 0 }
  187. };
  188. char *grp6[] = {
  189. "sldt",
  190. "str",
  191. "lldt",
  192. "ltr",
  193. "verr",
  194. "verw",
  195. "",
  196. ""
  197. };
  198. char *inst0f00[] = {
  199. "invplg",
  200. "swapgs",
  201. "rdtscp",
  202. "",
  203. "",
  204. "",
  205. "",
  206. ""
  207. };
  208. instdesc grp7[] = {
  209. { "sgdt", DA_QUAD+DA_MODRM, DA_ME, 0 },
  210. { "sidt", DA_QUAD+DA_MODRM, DA_ME, 0 },
  211. { "lgdt", DA_QUAD+DA_MODRM, DA_ME, 0 },
  212. { "lidt", DA_QUAD+DA_MODRM, DA_ME, 0 },
  213. { "smsw", DA_NONE+DA_MODRM, DA_Rw, 0 },
  214. { "", DA_NONE+DA_MODRM, DA_Rw, 0 },
  215. { "lmsw", DA_NONE+DA_MODRM, DA_Rw, 0 },
  216. { NULL, DA_NONE+DA_MODRM, DA_Rw, inst0f00 }
  217. };
  218. char *grp8[] = {
  219. "",
  220. "",
  221. "",
  222. "",
  223. "bt",
  224. "bts",
  225. "btr",
  226. "btc"
  227. };
  228. char *grp9[] = {
  229. "",
  230. "cmpxchg8b",
  231. "",
  232. "",
  233. "",
  234. "",
  235. "",
  236. ""
  237. };
  238. char *grpA[] = {
  239. "",
  240. "cmpxchg8b",
  241. "",
  242. "",
  243. "",
  244. "",
  245. "",
  246. ""
  247. };
  248. char *grpB[] = {
  249. "xstorerng",
  250. "xcryptecb",
  251. "xcryptcbc",
  252. "",
  253. "xcryptcfb",
  254. "xcryptofb",
  255. "",
  256. ""
  257. };
  258. char *inst0f71[] = {
  259. "",
  260. "",
  261. "psrlw",
  262. "",
  263. "psraw",
  264. "",
  265. "psllw",
  266. ""
  267. };
  268. char *inst0f72[] = {
  269. "",
  270. "",
  271. "psrld",
  272. "",
  273. "psrad",
  274. "",
  275. "pslld",
  276. ""
  277. };
  278. char *inst0f73[] = {
  279. "",
  280. "psrlq",
  281. "psrldq",
  282. "psraq",
  283. "",
  284. "psllq",
  285. "pslldq"
  286. };
  287. char *inst0fae[] = {
  288. "sfence",
  289. "clflush",
  290. "",
  291. "",
  292. "",
  293. "",
  294. "",
  295. ""
  296. };
  297. instdesc inst0f0[] = {
  298. { NULL, DA_NONE+DA_MODRM, DA_Ew, grp6 },
  299. { NULL, DA_NONE+DA_MODRM, DA_Ew, grp7 },
  300. { "lar", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  301. { "lsl", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  302. { "", DA_NONE, 0, 0 },
  303. { "syscall",DA_NONE, 0, 0 },
  304. { "clts", DA_NONE, 0, 0 },
  305. { "sysret", DA_NONE, 0, 0 },
  306. { "invd", DA_NONE, 0, 0 },
  307. { "wbinvd", DA_NONE, 0, 0 },
  308. { "", DA_NONE, 0, 0 },
  309. { "", DA_NONE, 0, 0 },
  310. { "", DA_NONE, 0, 0 },
  311. { "", DA_NONE, 0, 0 },
  312. { "", DA_NONE, 0, 0 },
  313. { "", DA_NONE, 0, 0 }
  314. };
  315. instdesc inst0f2[] = {
  316. { "mov", DA_LONG+DA_MODRM, DA2_CR_E, 0 },
  317. { "mov", DA_LONG+DA_MODRM, DA2_DR_E, 0 },
  318. { "mov", DA_LONG+DA_MODRM, DA2_E_CR, 0 },
  319. { "mov", DA_LONG+DA_MODRM, DA2_E_DR, 0 },
  320. { "mov", DA_LONG+DA_MODRM, DA2_TR_E, 0 },
  321. { "", DA_NONE, 0, 0 },
  322. { "mov", DA_LONG+DA_MODRM, DA2_E_TR, 0 },
  323. { "", DA_NONE, 0, 0 },
  324. { "", DA_NONE, 0, 0 },
  325. { "", DA_NONE, 0, 0 },
  326. { "", DA_NONE, 0, 0 },
  327. { "", DA_NONE, 0, 0 },
  328. { "", DA_NONE, 0, 0 },
  329. { "", DA_NONE, 0, 0 },
  330. { "", DA_NONE, 0, 0 },
  331. { "", DA_NONE, 0, 0 }
  332. };
  333. instdesc inst0f3[] = {
  334. { "wrmsr", DA_NONE, 0, 0 },
  335. { "rdtsc", DA_NONE, 0, 0 },
  336. { "rdmsr", DA_NONE, 0, 0 },
  337. { "rdpmc", DA_NONE, 0, 0 },
  338. { "", DA_NONE, 0, 0 },
  339. { "", DA_NONE, 0, 0 },
  340. { "", DA_NONE, 0, 0 },
  341. { "", DA_NONE, 0, 0 },
  342. { "", DA_NONE, 0, 0 },
  343. { "", DA_NONE, 0, 0 },
  344. { "", DA_NONE, 0, 0 },
  345. { "", DA_NONE, 0, 0 },
  346. { "", DA_NONE, 0, 0 },
  347. { "", DA_NONE, 0, 0 },
  348. { "", DA_NONE, 0, 0 },
  349. { "", DA_NONE, 0, 0 }
  350. };
  351. instdesc inst0f7[] = {
  352. { "", DA_NONE, 0, 0 },
  353. { NULL, DA_NONE, 0, inst0f71 },
  354. { "", DA_NONE, 0, 0 },
  355. { "", DA_NONE, 0, 0 },
  356. { "", DA_NONE, 0, 0 },
  357. { "", DA_NONE, 0, 0 },
  358. { "", DA_NONE, 0, 0 },
  359. { "", DA_NONE, 0, 0 },
  360. { "", DA_NONE, 0, 0 },
  361. { "", DA_NONE, 0, 0 },
  362. { "", DA_NONE, 0, 0 },
  363. { "", DA_NONE, 0, 0 },
  364. { "", DA_NONE, 0, 0 },
  365. { "", DA_NONE, 0, 0 },
  366. { "", DA_NONE, 0, 0 },
  367. { "", DA_NONE, 0, 0 },
  368. { "", DA_NONE, 0, 0 }
  369. };
  370. instdesc inst0f8[] = {
  371. { "jo", DA_NONE, DA_Dl, 0 },
  372. { "jno", DA_NONE, DA_Dl, 0 },
  373. { "jb", DA_NONE, DA_Dl, 0 },
  374. { "jnb", DA_NONE, DA_Dl, 0 },
  375. { "jz", DA_NONE, DA_Dl, 0 },
  376. { "jnz", DA_NONE, DA_Dl, 0 },
  377. { "jbe", DA_NONE, DA_Dl, 0 },
  378. { "jnbe", DA_NONE, DA_Dl, 0 },
  379. { "js", DA_NONE, DA_Dl, 0 },
  380. { "jns", DA_NONE, DA_Dl, 0 },
  381. { "jp", DA_NONE, DA_Dl, 0 },
  382. { "jnp", DA_NONE, DA_Dl, 0 },
  383. { "jl", DA_NONE, DA_Dl, 0 },
  384. { "jnl", DA_NONE, DA_Dl, 0 },
  385. { "jle", DA_NONE, DA_Dl, 0 },
  386. { "jnle", DA_NONE, DA_Dl, 0 }
  387. };
  388. instdesc inst0f9[] = {
  389. { "seto", DA_NONE+DA_MODRM, DA_Eb, 0 },
  390. { "setno", DA_NONE+DA_MODRM, DA_Eb, 0 },
  391. { "setb", DA_NONE+DA_MODRM, DA_Eb, 0 },
  392. { "setnb", DA_NONE+DA_MODRM, DA_Eb, 0 },
  393. { "setz", DA_NONE+DA_MODRM, DA_Eb, 0 },
  394. { "setnz", DA_NONE+DA_MODRM, DA_Eb, 0 },
  395. { "setbe", DA_NONE+DA_MODRM, DA_Eb, 0 },
  396. { "setnbe", DA_NONE+DA_MODRM, DA_Eb, 0 },
  397. { "sets", DA_NONE+DA_MODRM, DA_Eb, 0 },
  398. { "setns", DA_NONE+DA_MODRM, DA_Eb, 0 },
  399. { "setp", DA_NONE+DA_MODRM, DA_Eb, 0 },
  400. { "setnp", DA_NONE+DA_MODRM, DA_Eb, 0 },
  401. { "setl", DA_NONE+DA_MODRM, DA_Eb, 0 },
  402. { "setnl", DA_NONE+DA_MODRM, DA_Eb, 0 },
  403. { "setle", DA_NONE+DA_MODRM, DA_Eb, 0 },
  404. { "setnle", DA_NONE+DA_MODRM, DA_Eb, 0 }
  405. };
  406. instdesc inst0fa[] = {
  407. { "push", DA_QUAD, DA_Si, 0 },
  408. { "pop", DA_QUAD, DA_Si, 0 },
  409. { "cpuid", DA_NONE, 0, 0 },
  410. { "bt", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  411. { "shld", DA_LONG+DA_MODRM, DA3_Ib_R_E, 0 },
  412. { "shld", DA_LONG+DA_MODRM, DA3_CL_R_E, 0 },
  413. { "", DA_NONE, 0, 0 },
  414. { "", DA_NONE+DA_MODRM, 0, grpB },
  415. { "push", DA_QUAD, DA_Si, 0 },
  416. { "pop", DA_QUAD, DA_Si, 0 },
  417. { "", DA_NONE, 0, 0 },
  418. { "bts", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  419. { "shrd", DA_LONG+DA_MODRM, DA3_Ib_R_E, 0 },
  420. { "shrd", DA_LONG+DA_MODRM, DA3_CL_R_E, 0 },
  421. { NULL, DA_NONE+DA_MODRM, DA_E, grp9 },
  422. { "imul", DA_LONG+DA_MODRM, DA2_E_R, 0 }
  423. };
  424. instdesc inst0fb[] = {
  425. { "cmpxchg",DA_BYTE+DA_MODRM, DA2_R_E, 0 },
  426. { "cmpxchg",DA_LONG+DA_MODRM, DA2_R_E, 0 },
  427. { "lss", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  428. { "btr", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  429. { "lfs", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  430. { "lgs", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  431. { "movzb", DA_LONG+DA_MODRM, DA2_Eb_R, 0 },
  432. { "movzw", DA_LONG+DA_MODRM, DA2_Ew_R, 0 },
  433. { "", DA_NONE, 0, 0 },
  434. { "", DA_NONE, 0, 0 },
  435. { NULL, DA_LONG+DA_MODRM, DA2_Ib_E, grp8 },
  436. { "btc", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  437. { "bsf", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  438. { "bsr", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  439. { "movsb", DA_LONG+DA_MODRM, DA2_Eb_R, 0 },
  440. { "movsw", DA_LONG+DA_MODRM, DA2_Ew_R, 0 }
  441. };
  442. instdesc inst0fc[] = {
  443. { "xadd", DA_BYTE+DA_MODRM, DA2_R_E, 0 },
  444. { "xadd", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  445. { "", DA_NONE, 0, 0 },
  446. { "", DA_NONE, 0, 0 },
  447. { "", DA_NONE, 0, 0 },
  448. { "", DA_NONE, 0, 0 },
  449. { "", DA_NONE, 0, 0 },
  450. { NULL, DA_NONE+DA_MODRM, DA_E, grp9 },
  451. { "bswap", DA_LONG, DA_Ril, 0 },
  452. { "bswap", DA_LONG, DA_Ril, 0 },
  453. { "bswap", DA_LONG, DA_Ril, 0 },
  454. { "bswap", DA_LONG, DA_Ril, 0 },
  455. { "bswap", DA_LONG, DA_Ril, 0 },
  456. { "bswap", DA_LONG, DA_Ril, 0 },
  457. { "bswap", DA_LONG, DA_Ril, 0 },
  458. { "bswap", DA_LONG, DA_Ril, 0 }
  459. };
  460. char *esc92[] = {
  461. "fnop",
  462. "",
  463. "",
  464. "",
  465. "",
  466. "",
  467. "",
  468. ""
  469. };
  470. char *esc94[] = {
  471. "fchs",
  472. "fabs",
  473. "",
  474. "",
  475. "ftst",
  476. "fxam",
  477. "",
  478. ""
  479. };
  480. char *esc95[] = {
  481. "fld1",
  482. "fldl2t",
  483. "fldl2e",
  484. "fldpi",
  485. "fldlg2",
  486. "fldln2",
  487. "fldz",
  488. ""
  489. };
  490. char *esc96[] = {
  491. "f2xm1",
  492. "fyl2x",
  493. "fptan",
  494. "fpatan",
  495. "fxtract",
  496. "fprem1",
  497. "fdecstp",
  498. "fincstp"
  499. };
  500. char *esc97[] = {
  501. "fprem",
  502. "fyl2xp1",
  503. "fsqrt",
  504. "fsincos",
  505. "frndint",
  506. "fscale",
  507. "fsin",
  508. "fcos"
  509. };
  510. char *esca5[] = {
  511. "",
  512. "fucompp",
  513. "",
  514. "",
  515. "",
  516. "",
  517. "",
  518. ""
  519. };
  520. char *escb4[] = {
  521. "fneni",
  522. "fndisi",
  523. "fnclex",
  524. "fninit",
  525. "fsetpm",
  526. "",
  527. "",
  528. ""
  529. };
  530. char *esce3[] = {
  531. "",
  532. "fcompp",
  533. "",
  534. "",
  535. "",
  536. "",
  537. "",
  538. ""
  539. };
  540. char *escf4[] = {
  541. "fnstsw",
  542. "",
  543. "",
  544. "",
  545. "",
  546. "",
  547. "",
  548. ""
  549. };
  550. instdesc esc8[] = {
  551. { "fadd", DA_SNGL, DA2_STI_ST, 0 },
  552. { "fmul", DA_SNGL, DA2_STI_ST, 0 },
  553. { "fcom", DA_SNGL, DA2_STI_ST, 0 },
  554. { "fcomp", DA_SNGL, DA2_STI_ST, 0 },
  555. { "fsub", DA_SNGL, DA2_STI_ST, 0 },
  556. { "fsubr", DA_SNGL, DA2_STI_ST, 0 },
  557. { "fdiv", DA_SNGL, DA2_STI_ST, 0 },
  558. { "fdivr", DA_SNGL, DA2_STI_ST, 0 }
  559. };
  560. instdesc esc9[] = {
  561. { "fld", DA_SNGL, DA_STI, 0 },
  562. { "", DA_NONE, DA_STI, "fxch" },
  563. { "fst", DA_SNGL, DA_X, esc92 },
  564. { "fstp", DA_SNGL, DA_X, 0 },
  565. { "fldenv", DA_NONE, DA_X, esc94 },
  566. { "fldcw", DA_NONE, DA_X, esc95 },
  567. { "fnstenv",DA_NONE, DA_X, esc96 },
  568. { "fnstcw", DA_NONE, DA_X, esc97 }
  569. };
  570. instdesc esca[] = {
  571. { "fiadd", DA_LONG, 0, 0 },
  572. { "fimul", DA_LONG, 0, 0 },
  573. { "ficom", DA_LONG, 0, 0 },
  574. { "ficomp", DA_LONG, 0, 0 },
  575. { "fisub", DA_LONG, DA_X, 0 },
  576. { "fisubr", DA_LONG, 0, 0 },
  577. { "fidiv", DA_LONG, 0, 0 },
  578. { "fidivr", DA_LONG, 0, 0 }
  579. };
  580. instdesc escb[] = {
  581. { "fild", DA_LONG, 0, 0 },
  582. { "", DA_NONE, 0, 0 },
  583. { "fist", DA_LONG, 0, 0 },
  584. { "fistp", DA_LONG, 0, 0 },
  585. { "", DA_WORD, DA_X, escb4 },
  586. { "fld", DA_EXTR, 0, 0 },
  587. { "", DA_NONE, 0, 0 },
  588. { "fstp", DA_EXTR, 0, 0 }
  589. };
  590. instdesc escc[] = {
  591. { "fadd", DA_DBLR, DA2_STI_ST, 0 },
  592. { "fmul", DA_DBLR, DA2_STI_ST, 0 },
  593. { "fcom", DA_DBLR, DA2_STI_ST, 0 },
  594. { "fcomp", DA_DBLR, DA2_STI_ST, 0 },
  595. { "fsub", DA_DBLR, DA2_STI_ST, 0 },
  596. { "fsubr", DA_DBLR, DA2_STI_ST, 0 },
  597. { "fdiv", DA_DBLR, DA2_STI_ST, 0 },
  598. { "fdivr", DA_DBLR, DA2_STI_ST, 0 }
  599. };
  600. instdesc escd[] = {
  601. { "fld", DA_DBLR, DA_STI, "ffree" },
  602. { "", DA_NONE, 0, 0 },
  603. { "fst", DA_DBLR, DA_STI, 0 },
  604. { "fstp", DA_DBLR, DA_STI, 0 },
  605. { "frstor", DA_NONE, DA_STI, "fucom" },
  606. { "", DA_NONE, DA_STI, "fucomp" },
  607. { "fnsave", DA_NONE, 0, 0 },
  608. { "fnstsw", DA_NONE, 0, 0 }
  609. };
  610. instdesc esce[] = {
  611. { "fiadd", DA_WORD, DA2_ST_STI, "faddp" },
  612. { "fimul", DA_WORD, DA2_ST_STI, "fmulp" },
  613. { "ficom", DA_WORD, 0, 0 },
  614. { "ficomp", DA_WORD, DA_X, esce3 },
  615. { "fisub", DA_WORD, DA2_ST_STI, "fsubrp" },
  616. { "fisubr", DA_WORD, DA2_ST_STI, "fsubp" },
  617. { "fidiv", DA_WORD, DA2_ST_STI, "fdivrp" },
  618. { "fidivr", DA_WORD, DA2_ST_STI, "fdivp" }
  619. };
  620. instdesc escf[] = {
  621. { "fild", DA_WORD, 0, 0 },
  622. { "", DA_NONE, 0, 0 },
  623. { "fist", DA_WORD, 0, 0 },
  624. { "fistp", DA_WORD, 0, 0 },
  625. { "fbld", DA_NONE, DA_XA, escf4 },
  626. { "fild", DA_QUAD, 0, 0 },
  627. { "fbstp", DA_NONE, 0, 0 },
  628. { "fistp", DA_QUAD, 0, 0 }
  629. };
  630. instdesc inst_tbl[] = {
  631. { "add", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*00*/
  632. { "add", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  633. { "add", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  634. { "add", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  635. { "add", DA_BYTE, DA2_Ib_A, 0 },
  636. { "add", DA_LONG, DA2_I_A, 0 },
  637. { "", DA_NONE, DA_Si, 0 },
  638. { "", DA_NONE, DA_Si, 0 },
  639. { "or", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*08*/
  640. { "or", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  641. { "or", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  642. { "or", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  643. { "or", DA_BYTE, DA2_Ib_A, 0 },
  644. { "or", DA_LONG, DA2_I_A, 0 },
  645. { "", DA_NONE, 0, 0 },
  646. { "", DA_NONE, 0, 0 },
  647. { "adc", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*10*/
  648. { "adc", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  649. { "adc", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  650. { "adc", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  651. { "adc", DA_BYTE, DA2_Ib_A, 0 },
  652. { "adc", DA_LONG, DA2_I_A, 0 },
  653. { "", DA_NONE, 0, 0 },
  654. { "", DA_NONE, 0, 0 },
  655. { "sbb", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*18*/
  656. { "sbb", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  657. { "sbb", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  658. { "sbb", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  659. { "sbb", DA_BYTE, DA2_Ib_A, 0 },
  660. { "sbb", DA_LONG, DA2_I_A, 0 },
  661. { "", DA_NONE, 0, 0 },
  662. { "", DA_NONE, 0, 0 },
  663. { "and", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*20*/
  664. { "and", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  665. { "and", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  666. { "and", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  667. { "and", DA_BYTE, DA2_Ib_A, 0 },
  668. { "and", DA_LONG, DA2_I_A, 0 },
  669. { "", DA_NONE, 0, 0 },
  670. { "", DA_NONE, 0, 0 },
  671. { "sub", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*28*/
  672. { "sub", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  673. { "sub", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  674. { "sub", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  675. { "sub", DA_BYTE, DA2_Ib_A, 0 },
  676. { "sub", DA_LONG, DA2_I_A, 0 },
  677. { "", DA_NONE, 0, 0 },
  678. { "", DA_NONE, 0, 0 },
  679. { "xor", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*30*/
  680. { "xor", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  681. { "xor", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  682. { "xor", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  683. { "xor", DA_BYTE, DA2_Ib_A, 0 },
  684. { "xor", DA_LONG, DA2_I_A, 0 },
  685. { "", DA_NONE, 0, 0 },
  686. { "", DA_NONE, 0, 0 },
  687. { "cmp", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*38*/
  688. { "cmp", DA_BYTE+DA_MODRM, DA2_R_E, 0 },
  689. { "cmp", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  690. { "cmp", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  691. { "cmp", DA_BYTE, DA2_Ib_A, 0 },
  692. { "cmp", DA_LONG, DA2_I_A, 0 },
  693. { "", DA_NONE, 0, 0 },
  694. { "", DA_NONE, 0, 0 },
  695. { "", DA_LONG, DA_Ri, 0 }, /*40*/
  696. { "", DA_LONG, DA_Ri, 0 },
  697. { "", DA_LONG, DA_Ri, 0 },
  698. { "", DA_LONG, DA_Ri, 0 },
  699. { "", DA_LONG, DA_Ri, 0 },
  700. { "", DA_LONG, DA_Ri, 0 },
  701. { "", DA_LONG, DA_Ri, 0 },
  702. { "", DA_LONG, DA_Ri, 0 },
  703. { "", DA_LONG, DA_Ri, 0 }, /*48*/
  704. { "", DA_LONG, DA_Ri, 0 },
  705. { "", DA_LONG, DA_Ri, 0 },
  706. { "", DA_LONG, DA_Ri, 0 },
  707. { "", DA_LONG, DA_Ri, 0 },
  708. { "", DA_LONG, DA_Ri, 0 },
  709. { "", DA_LONG, DA_Ri, 0 },
  710. { "", DA_LONG, DA_Ri, 0 },
  711. { "push", DA_QUAD, DA_Rq, 0 }, /*50*/
  712. { "push", DA_QUAD, DA_Rq, 0 },
  713. { "push", DA_QUAD, DA_Rq, 0 },
  714. { "push", DA_QUAD, DA_Rq, 0 },
  715. { "push", DA_QUAD, DA_Rq, 0 },
  716. { "push", DA_QUAD, DA_Rq, 0 },
  717. { "push", DA_QUAD, DA_Rq, 0 },
  718. { "push", DA_QUAD, DA_Rq, 0 },
  719. { "pop", DA_QUAD, DA_Rq, 0 }, /*58*/
  720. { "pop", DA_QUAD, DA_Rq, 0 },
  721. { "pop", DA_QUAD, DA_Rq, 0 },
  722. { "pop", DA_QUAD, DA_Rq, 0 },
  723. { "pop", DA_QUAD, DA_Rq, 0 },
  724. { "pop", DA_QUAD, DA_Rq, 0 },
  725. { "pop", DA_QUAD, DA_Rq, 0 },
  726. { "pop", DA_QUAD, DA_Rq, 0 },
  727. { "", DA_LONG, 0, 0 }, /*60*/
  728. { "", DA_LONG, 0, 0 },
  729. { "", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  730. { "movsxd", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  731. { "", DA_NONE, 0, 0 },
  732. { "", DA_NONE, 0, 0 },
  733. { "", DA_NONE, 0, 0 },
  734. { "", DA_NONE, 0, 0 },
  735. { "push", DA_LONG, DA_I, 0 }, /*68*/
  736. { "imul", DA_LONG+DA_MODRM, DA3_I_E_R, 0 },
  737. { "push", DA_QUAD, DA_Ib, 0 },
  738. { "imul", DA_LONG+DA_MODRM, DA3_Ib_E_R, 0 },
  739. { "ins", DA_BYTE, DA2_DX_DI, 0 },
  740. { "ins", DA_LONG, DA2_DX_DI, 0 },
  741. { "outs", DA_BYTE, DA2_SI_DX, 0 },
  742. { "outs", DA_LONG, DA2_SI_DX, 0 },
  743. { "jo", DA_NONE, DA_Db, 0 }, /*70*/
  744. { "jno", DA_NONE, DA_Db, 0 },
  745. { "jb", DA_NONE, DA_Db, 0 },
  746. { "jnb", DA_NONE, DA_Db, 0 },
  747. { "jz", DA_NONE, DA_Db, 0 },
  748. { "jnz", DA_NONE, DA_Db, 0 },
  749. { "jbe", DA_NONE, DA_Db, 0 },
  750. { "jnbe", DA_NONE, DA_Db, 0 },
  751. { "js", DA_NONE, DA_Db, 0 }, /*78*/
  752. { "jns", DA_NONE, DA_Db, 0 },
  753. { "jp", DA_NONE, DA_Db, 0 },
  754. { "jnp", DA_NONE, DA_Db, 0 },
  755. { "jl", DA_NONE, DA_Db, 0 },
  756. { "jnl", DA_NONE, DA_Db, 0 },
  757. { "jle", DA_NONE, DA_Db, 0 },
  758. { "jnle", DA_NONE, DA_Db, 0 },
  759. { NULL, DA_BYTE+DA_MODRM, DA2_Ib_E, grp1 }, /*80*/
  760. { NULL, DA_LONG+DA_MODRM, DA2_I_E, grp1 },
  761. { NULL, DA_BYTE+DA_MODRM, DA2_Ib_E, grp1 },
  762. { NULL, DA_LONG+DA_MODRM, DA2_Ib_E, grp1 },
  763. { "test", DA_BYTE+DA_MODRM, DA2_R_E, 0 },
  764. { "test", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  765. { "xchg", DA_BYTE+DA_MODRM, DA2_R_E, 0 },
  766. { "xchg", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  767. { "mov", DA_BYTE+DA_MODRM, DA2_R_E, 0 }, /*88*/
  768. { "mov", DA_LONG+DA_MODRM, DA2_R_E, 0 },
  769. { "mov", DA_BYTE+DA_MODRM, DA2_E_R, 0 },
  770. { "mov", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  771. { "mov", DA_NONE+DA_MODRM, DA2_S_Ew, 0 },
  772. { "lea", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  773. { "mov", DA_NONE+DA_MODRM, DA2_Ew_S, 0 },
  774. { "pop", DA_QUAD+DA_MODRM, DA_E, 0 },
  775. { "nop", DA_NONE, 0, 0 }, /*90*/
  776. { "xchg", DA_LONG, DA2_A_Ri, 0 },
  777. { "xchg", DA_LONG, DA2_A_Ri, 0 },
  778. { "xchg", DA_LONG, DA2_A_Ri, 0 },
  779. { "xchg", DA_LONG, DA2_A_Ri, 0 },
  780. { "xchg", DA_LONG, DA2_A_Ri, 0 },
  781. { "xchg", DA_LONG, DA2_A_Ri, 0 },
  782. { "xchg", DA_LONG, DA2_A_Ri, 0 },
  783. { "cbw", DA_SDEP, 0, "cdqe" }, /*98*/
  784. { "cwd", DA_SDEP, 0, "cqo" },
  785. { "", DA_NONE, DA_OS, 0 },
  786. { "wait", DA_NONE, 0, 0 },
  787. { "pushf", DA_QUAD, 0, 0 },
  788. { "popf", DA_QUAD, 0, 0 },
  789. { "sahf", DA_NONE, 0, 0 },
  790. { "lahf", DA_NONE, 0, 0 },
  791. { "mov", DA_BYTE, DA2_O_A, 0 }, /*A0*/
  792. { "mov", DA_LONG, DA2_O_A, 0 },
  793. { "mov", DA_BYTE, DA2_A_O, 0 },
  794. { "mov", DA_LONG, DA2_A_O, 0 },
  795. { "movsb", DA_BYTE, 0, 0 },
  796. { "movsd", DA_LONG, 0, 0 },
  797. { "cmpsb", DA_BYTE, 0, 0 },
  798. { "cmpsd", DA_LONG, 0, 0 },
  799. { "test", DA_BYTE, DA2_I_A, 0 }, /*A8*/
  800. { "test", DA_LONG, DA2_I_A, 0 },
  801. { "stosb", DA_BYTE, 0, 0 },
  802. { "stosw", DA_WORD, 0, 0 },
  803. { "lodsb", DA_BYTE, 0, 0 },
  804. { "lodsw", DA_WORD, 0, 0 },
  805. { "scasb", DA_BYTE, 0, 0 },
  806. { "scasd", DA_LONG, 0, 0 },
  807. { "mov", DA_BYTE, DA2_Ib_Ri, 0 }, /*B0*/
  808. { "mov", DA_BYTE, DA2_Ib_Ri, 0 },
  809. { "mov", DA_BYTE, DA2_Ib_Ri, 0 },
  810. { "mov", DA_BYTE, DA2_Ib_Ri, 0 },
  811. { "mov", DA_BYTE, DA2_Ib_Ri, 0 },
  812. { "mov", DA_BYTE, DA2_Ib_Ri, 0 },
  813. { "mov", DA_BYTE, DA2_Ib_Ri, 0 },
  814. { "mov", DA_BYTE, DA2_Ib_Ri, 0 },
  815. { "mov", DA_LONG, DA2_I_Ri, 0 }, /*B8*/
  816. { "mov", DA_LONG, DA2_I_Ri, 0 },
  817. { "mov", DA_LONG, DA2_I_Ri, 0 },
  818. { "mov", DA_LONG, DA2_I_Ri, 0 },
  819. { "mov", DA_LONG, DA2_Iq_Ri, 0 },
  820. { "mov", DA_LONG, DA2_Iq_Ri, 0 },
  821. { "mov", DA_LONG, DA2_Iq_Ri, 0 },
  822. { "mov", DA_LONG, DA2_Iq_Ri, 0 },
  823. { NULL, DA_BYTE+DA_MODRM, DA2_Ib_E, grp2 }, /*C0*/
  824. { NULL, DA_LONG+DA_MODRM, DA2_Ib_E, grp2 },
  825. { "ret", DA_NONE, DA_Iw, 0 },
  826. { "ret", DA_NONE, 0, 0 },
  827. { "", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  828. { "", DA_LONG+DA_MODRM, DA2_E_R, 0 },
  829. { "mov", DA_BYTE+DA_MODRM, DA2_I_E, 0 },
  830. { "mov", DA_LONG+DA_MODRM, DA2_I_E, 0 },
  831. { "enter", DA_NONE, DA2_Iq_Ib, 0 }, /*C8*/
  832. { "leave", DA_NONE, 0, 0 },
  833. { "lret", DA_NONE, DA_Iw, 0 },
  834. { "lret", DA_NONE, 0, 0 },
  835. { "int", DA_NONE, DA_o3, 0 },
  836. { "int", DA_NONE, DA_Ib, 0 },
  837. { "", DA_NONE, 0, 0 },
  838. { "iret", DA_NONE, 0, 0 },
  839. { NULL, DA_BYTE+DA_MODRM, DA2_o1_E, grp2 }, /*D0*/
  840. { NULL, DA_LONG+DA_MODRM, DA2_o1_E, grp2 },
  841. { NULL, DA_BYTE+DA_MODRM, DA2_CL_E, grp2 },
  842. { NULL, DA_LONG+DA_MODRM, DA2_CL_E, grp2 },
  843. { "", DA_NONE+DA_MODRM, DA_Ib, 0 },
  844. { "", DA_NONE+DA_MODRM, DA_Ib, 0 },
  845. { "", DA_NONE, 0, 0 },
  846. { "xlat", DA_BYTE, DA_BX, 0 },
  847. { "", DA_NONE+DA_MODRM, 0, esc8 }, /*D8*/
  848. { "", DA_NONE+DA_MODRM, 0, esc9 },
  849. { "", DA_NONE+DA_MODRM, 0, esca },
  850. { "", DA_NONE+DA_MODRM, 0, escb },
  851. { "", DA_NONE+DA_MODRM, 0, escc },
  852. { "", DA_NONE+DA_MODRM, 0, escd },
  853. { "", DA_NONE+DA_MODRM, 0, esce },
  854. { "", DA_NONE+DA_MODRM, 0, escf },
  855. { "loopne", DA_NONE, DA_Db, 0 }, /*E0*/
  856. { "loope", DA_NONE, DA_Db, 0 },
  857. { "loop", DA_NONE, DA_Db, 0 },
  858. { "jcxz", DA_SDEP, DA_Db, "jrcxz" },
  859. { "in", DA_BYTE, DA2_Ib_A, 0 },
  860. { "in", DA_LONG, DA2_Ib_A, 0 },
  861. { "out", DA_BYTE, DA2_A_Ib, 0 },
  862. { "out", DA_LONG, DA2_A_Ib, 0 },
  863. { "call", DA_LONG, DA_Dl, 0 }, /*E8*/
  864. { "jmp", DA_LONG, DA_Dl, 0 },
  865. { "", DA_NONE, DA_OS, 0 },
  866. { "jmp", DA_NONE, DA_Db, 0 },
  867. { "in", DA_BYTE, DA2_DX_A, 0 },
  868. { "in", DA_LONG, DA2_DX_A, 0 },
  869. { "out", DA_BYTE, DA2_A_DX, 0 },
  870. { "out", DA_LONG, DA2_A_DX, 0 },
  871. { "", DA_NONE, 0, 0 }, /*F0*/
  872. { "", DA_NONE, 0, 0 },
  873. { "", DA_NONE, 0, 0 },
  874. { "", DA_NONE, 0, 0 },
  875. { "hlt", DA_NONE, 0, 0 },
  876. { "cmc", DA_NONE, 0, 0 },
  877. { NULL, DA_BYTE+DA_MODRM, 0, grp3 },
  878. { NULL, DA_LONG+DA_MODRM, 0, grp3 },
  879. { "clc", DA_NONE, 0, 0 }, /*F8*/
  880. { "stc", DA_NONE, 0, 0 },
  881. { "cli", DA_NONE, 0, 0 },
  882. { "sti", DA_NONE, 0, 0 },
  883. { "cld", DA_NONE, 0, 0 },
  884. { "std", DA_NONE, 0, 0 },
  885. { NULL, DA_NONE+DA_MODRM, 0, grp4 },
  886. { NULL, DA_NONE+DA_MODRM, 0, grp5 }
  887. };
  888. instdesc *inst_tbl0f[] = {
  889. inst0f0,
  890. 0,
  891. inst0f2,
  892. inst0f3,
  893. 0,
  894. 0,
  895. 0,
  896. inst0f7,
  897. inst0f8,
  898. inst0f9,
  899. inst0fa,
  900. inst0fb,
  901. inst0fc,
  902. 0,
  903. 0,
  904. 0
  905. };
  906. char *sizestr[7] = {
  907. "byte",
  908. "word",
  909. "dword",
  910. "qword",
  911. "single",
  912. "double",
  913. "extend"
  914. };
  915. char *regs[4][16] = {
  916. { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"},
  917. { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"},
  918. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"},
  919. { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }
  920. };
  921. char *sregs[8] = {
  922. "es", "cs", "ss", "ds", "fs", "gs", "?", "?"
  923. };
  924. char *unkmnemonic = "???";
  925. /* cím feloldás */
  926. uint8_t addr_reg;
  927. uint8_t addr_scale;
  928. uint64_t addr_disp;
  929. uint8_t addr_seg;
  930. uint8_t addr_saddr;
  931. char *addr_base;
  932. char *addr_idx;
  933. char *disasm_prtaddr(char *str, uint64_t addr, uint8_t mode, uint8_t size, uint8_t reg)
  934. {
  935. if(addr_reg) {
  936. if(size > 3) size = 3;
  937. str += sprintf(str, regs[size][reg]);
  938. } else {
  939. if(size > 6) size = 6;
  940. str += sprintf(str,"%s ", sizestr[size]);
  941. if (addr_seg)
  942. str += sprintf(str, "%cs:", addr_seg);
  943. str += sprintf(str,"[");
  944. if(addr_base!=NULL) {
  945. str += sprintf(str,"%s", addr_base);
  946. if(addr_idx!=NULL) {
  947. str += sprintf(str,"+%s", addr_idx);
  948. if(addr_scale>1)
  949. str += sprintf(str,"*%d", addr_scale);
  950. }
  951. } else {
  952. if(mode!=DA_E)
  953. addr_disp += addr;
  954. }
  955. if(addr_disp) {
  956. str += sprintf(str,"%s%x", addr_base!=NULL?"+":"", addr_disp);
  957. } else if(addr_base==NULL) *str++ = '0';
  958. str += sprintf(str,"]");
  959. }
  960. return str;
  961. }
  962. /*** public API ***/
  963. uint64_t disasm(uint64_t addr, char *str)
  964. {
  965. uint64_t disasmstart;
  966. uint8_t rex = 0;
  967. uint8_t opcode = 0, opcode2 = 0;
  968. uint8_t modrm = 0;
  969. uint8_t sib = 0;
  970. uint64_t imm = 0;
  971. uint64_t disp = 0;
  972. uint8_t size = DA_LONG;
  973. uint8_t reg = 0;
  974. instdesc *inst;
  975. uint32_t i_size = DA_NONE;
  976. uint32_t i_mode;
  977. uint8_t mod, rm;
  978. uint16_t idx;
  979. char *i_name;
  980. disasmstart = addr;
  981. addr_seg = 0;
  982. addr_saddr = DA_QUAD;
  983. addr_base = NULL;
  984. addr_idx = NULL;
  985. getprefix:
  986. opcode = *((uint8_t*)addr);
  987. addr++;
  988. /* szegmens felülbírálás CS, DS, ES, SS nem használt long módban */
  989. if(opcode==0x26||opcode==0x36||opcode==0x2e||opcode==0x3e)
  990. goto getprefix;
  991. /* fs */
  992. if(opcode==0x64) {
  993. addr_seg='f';
  994. goto getprefix;
  995. }
  996. /* gs */
  997. if(opcode==0x65) {
  998. addr_seg='g';
  999. goto getprefix;
  1000. }
  1001. /* adatméret módosító prefix */
  1002. if(opcode==0x66) {
  1003. rex=0x40;
  1004. size=DA_WORD;
  1005. goto getprefix;
  1006. }
  1007. /* címméret módosító */
  1008. if(opcode==0x67) {
  1009. addr_saddr=DA_LONG;
  1010. goto getprefix;
  1011. }
  1012. if(opcode==0xf0) {
  1013. if(str!=NULL)
  1014. str += sprintf(str, "lock ");
  1015. goto getprefix;
  1016. }
  1017. if(opcode==0xf2) {
  1018. if(str!=NULL)
  1019. str += sprintf(str, "repnz ");
  1020. goto getprefix;
  1021. }
  1022. if(opcode==0xf3) {
  1023. if(str!=NULL)
  1024. str += sprintf(str, "repe ");
  1025. goto getprefix;
  1026. }
  1027. /* rex */
  1028. if((opcode&0xF0)==0x40) {
  1029. rex = opcode;
  1030. if(rex&0x08)
  1031. size=DA_QUAD;
  1032. goto getopcode;
  1033. }
  1034. goto prefixend;
  1035. getopcode:
  1036. opcode = *((uint8_t*)addr);
  1037. addr++;
  1038. prefixend:
  1039. /* nop */
  1040. if(opcode==0x90) {
  1041. i_size = 1;
  1042. while(*((uint8_t*)addr)==0x90) { i_size++; addr++; }
  1043. if(str != NULL)
  1044. str += sprintf(str, " %d x nop", i_size);
  1045. goto end2;
  1046. }
  1047. /* 2 bájtos opkód? */
  1048. if (opcode == 0x0f) {
  1049. opcode2 = *((uint8_t*)addr);
  1050. addr++;
  1051. inst = inst_tbl0f[opcode2>>4];
  1052. if (inst != NULL)
  1053. inst = &inst[opcode2&0xf];
  1054. } else {
  1055. inst = &inst_tbl[opcode];
  1056. }
  1057. if (inst == NULL) {
  1058. unknown:
  1059. if(str != NULL)
  1060. str += sprintf(str, unkmnemonic);
  1061. goto end;
  1062. }
  1063. /* van modrm? */
  1064. if(inst->size & DA_MODRM) {
  1065. modrm = *((uint8_t*)addr);
  1066. addr++;
  1067. mod = (modrm>>6) & 3;
  1068. rm = ((rex & 0x01)<<3) + (modrm & 7);
  1069. reg = ((rex & 0x04)<<1) + ((modrm>>3) & 7);
  1070. addr_disp = 0;
  1071. addr_base = addr_idx = NULL;
  1072. addr_scale = addr_reg = false;
  1073. if(mod==3) {
  1074. addr_reg = true;
  1075. addr_disp = (uint64_t)((uint8_t)rm);
  1076. } else {
  1077. /* van sib bájt? */
  1078. if((modrm & 7)==0x04) {
  1079. sib = *((uint8_t*)addr);
  1080. addr++;
  1081. addr_scale=sib>>6;
  1082. idx=((rex&2)<<2)+((sib>>3)&7);
  1083. if(idx!=4)
  1084. addr_idx=regs[DA_QUAD][idx];
  1085. rm = ((rex&1)<<3)+(sib&7);
  1086. }
  1087. addr_base = regs[DA_QUAD][rm];
  1088. if(mod==0) {
  1089. if(rm==5) {
  1090. addr_disp = (uint64_t)(*((uint32_t*)addr));
  1091. addr += 4;
  1092. addr_base = NULL;
  1093. }
  1094. } else
  1095. if(mod==1) {
  1096. addr_disp = (uint64_t)(*((uint8_t*)addr));
  1097. addr++;
  1098. } else
  1099. if(mod==2) {
  1100. addr_disp = (uint64_t)(*((uint32_t*)addr));
  1101. addr += 4;
  1102. }
  1103. }
  1104. }
  1105. /* ModRM specifikus */
  1106. if((inst->name==NULL||inst->name[0]==0) && inst->ext != 0) {
  1107. if(opcode>=0xd0&&opcode<=0xd8){
  1108. /* esc */
  1109. inst = (instdesc*)inst->ext;
  1110. inst = &inst[(modrm>>3)&7];
  1111. goto unknown;
  1112. } else {
  1113. /* typeof inst->ext == instdesc*? */
  1114. if(inst->ext==grp3 || inst->ext==grp4 || inst->ext==grp5 ||
  1115. inst->ext==grp7) {
  1116. inst = (instdesc*)inst->ext;
  1117. inst = &inst[(modrm>>3)&7];
  1118. }
  1119. }
  1120. }
  1121. if(inst==NULL) goto unknown;
  1122. i_name = inst->name!=NULL ? inst->name : ((char**)inst->ext)[reg];
  1123. i_size = inst->size&0xf;
  1124. i_mode = inst->mode;
  1125. if(i_name==NULL||i_name[0]==0) goto unknown;
  1126. /* mnemonic */
  1127. if (i_size == DA_SDEP) {
  1128. if (size == DA_LONG)
  1129. i_name=(char *)inst->ext;
  1130. i_size = size;
  1131. }
  1132. if(rex)
  1133. i_size = size;
  1134. if(str!=NULL)
  1135. str += sprintf(str, "%6s\t", i_name);
  1136. /* argumentumok */
  1137. for (;i_mode != 0; i_mode >>= 8) {
  1138. if (str!=NULL && *(str-1)!='\t')
  1139. str += sprintf(str, ", ");
  1140. switch (i_mode & 0xFF) {
  1141. case DA_E:
  1142. case DA_EInd:
  1143. if(str != NULL)
  1144. str = disasm_prtaddr(str, addr, i_mode&0xFF, i_size, addr_disp);
  1145. break;
  1146. case DA_Ew:
  1147. if(str != NULL)
  1148. str = disasm_prtaddr(str, addr, i_mode&0xFF, DA_WORD, reg);
  1149. break;
  1150. case DA_Eb:
  1151. if(str != NULL)
  1152. str = disasm_prtaddr(str, addr, i_mode&0xFF, DA_BYTE, reg);
  1153. break;
  1154. case DA_ME:
  1155. if(str != NULL)
  1156. str += sprintf(str, addr_base ? addr_base : "0");
  1157. break;
  1158. case DA_R:
  1159. if(str != NULL)
  1160. str += sprintf(str, regs[i_size][reg]);
  1161. break;
  1162. case DA_Rw:
  1163. if(str != NULL)
  1164. str += sprintf(str, regs[DA_WORD][reg]);
  1165. break;
  1166. case DA_Ri:
  1167. if(str != NULL)
  1168. str += sprintf(str, regs[i_size][(opcode&7)+((rex&1)<<3)]);
  1169. break;
  1170. case DA_Rq:
  1171. if(str != NULL)
  1172. str += sprintf(str, regs[DA_QUAD][(opcode&7)+((rex&1)<<3)]);
  1173. break;
  1174. case DA_Ril:
  1175. if(str != NULL)
  1176. str += sprintf(str, regs[DA_LONG][(opcode&7)+((rex&1)<<3)]);
  1177. break;
  1178. case DA_S:
  1179. if(str != NULL)
  1180. str += sprintf(str, sregs[(modrm&7)]);
  1181. break;
  1182. case DA_Si:
  1183. if(str != NULL)
  1184. str += sprintf(str, sregs[(opcode&7)]);
  1185. break;
  1186. case DA_A:
  1187. if(str != NULL)
  1188. str += sprintf(str, regs[i_size][0]);
  1189. break;
  1190. case DA_BX:
  1191. if(str != NULL) {
  1192. if (addr_seg)
  1193. str += sprintf(str, "%cs:", addr_seg);
  1194. str += sprintf(str,"%s [%s]", sizestr[i_size], regs[addr_saddr][3]);
  1195. }
  1196. break;
  1197. case DA_CL:
  1198. if(str != NULL)
  1199. str += sprintf(str, regs[DA_BYTE][1]);
  1200. break;
  1201. case DA_DX:
  1202. if(str != NULL)
  1203. str += sprintf(str, regs[DA_WORD][2]);
  1204. break;
  1205. case DA_SI:
  1206. if(str != NULL) {
  1207. if (addr_seg)
  1208. str += sprintf(str, "%cs:", addr_seg);
  1209. str += sprintf(str,"%s [%s]", sizestr[i_size], regs[addr_saddr][6]);
  1210. }
  1211. break;
  1212. case DA_DI:
  1213. if(str != NULL) {
  1214. if (addr_seg)
  1215. str += sprintf(str, "%cs:", addr_seg);
  1216. str += sprintf(str,"%s [%s]", sizestr[i_size], regs[addr_saddr][7]);
  1217. }
  1218. break;
  1219. case DA_CR:
  1220. if (str != NULL)
  1221. str += sprintf(str, "cr%d", reg);
  1222. break;
  1223. case DA_DR:
  1224. if (str != NULL)
  1225. str += sprintf(str, "dr%d", reg);
  1226. break;
  1227. case DA_TR:
  1228. if (str != NULL)
  1229. str += sprintf(str, "tr%d", reg);
  1230. break;
  1231. case DA_I:
  1232. case DA_Is:
  1233. if(i_size == DA_WORD) {
  1234. imm = (uint64_t)(*((int16_t*)addr));
  1235. addr += 2;
  1236. } else {
  1237. imm = (uint64_t)(*((int32_t*)addr));
  1238. addr += 4;
  1239. }
  1240. if (str != NULL)
  1241. str += sprintf(str, "%xh", imm);
  1242. break;
  1243. case DA_Ib:
  1244. imm = (uint64_t)(*((uint8_t*)addr));
  1245. addr++;
  1246. if (str != NULL)
  1247. str += sprintf(str, "%1xh", imm);
  1248. break;
  1249. case DA_Iba:
  1250. case DA_Ibs:
  1251. imm = (uint64_t)(*((uint8_t*)addr));
  1252. addr++;
  1253. if (str != NULL && imm !=0x0a)
  1254. str += sprintf(str, "%1xh", imm);
  1255. break;
  1256. case DA_Iw:
  1257. imm = (uint64_t)(*((uint16_t*)addr));
  1258. addr += 2;
  1259. if (str != NULL)
  1260. str += sprintf(str, "%2xh", imm);
  1261. break;
  1262. case DA_Iq:
  1263. imm = (uint64_t)(*((uint64_t*)addr));
  1264. addr += 8;
  1265. if (str != NULL)
  1266. str += sprintf(str, "%8xh", imm);
  1267. break;
  1268. case DA_O:
  1269. /*
  1270. if (addr_saddr==DA_QUAD) {
  1271. disp = (uint64_t)(*((uint32_t*)addr));
  1272. addr += 4;
  1273. } else {
  1274. */
  1275. disp = (uint64_t)(*((uint16_t*)addr));
  1276. addr += 2;
  1277. /* } */
  1278. if(str != NULL) {
  1279. if (addr_seg)
  1280. str += sprintf(str, "%cs:", addr_seg);
  1281. str += sprintf(str,"%xh", disp);
  1282. }
  1283. break;
  1284. case DA_Db:
  1285. disp = (uint64_t)(*((int8_t*)addr));
  1286. addr++;
  1287. disp += addr;
  1288. if(str != NULL)
  1289. str += sprintf(str, "%xh", disp);
  1290. break;
  1291. case DA_Dl:
  1292. /*
  1293. if (i_size==DA_QUAD) {
  1294. disp = (uint64_t)(*((uint64_t*)addr));
  1295. addr+=8;
  1296. } else if (i_size==DA_LONG) {
  1297. */
  1298. disp = (uint64_t)(*((int32_t*)addr));
  1299. addr+=4;
  1300. /*
  1301. } else if (i_size==DA_WORD) {
  1302. disp = (uint64_t)(*((int16_t*)addr));
  1303. addr+=2;
  1304. } else if (i_size==DA_BYTE) {
  1305. disp = (uint64_t)(*((int8_t*)addr));
  1306. addr++;
  1307. }
  1308. */
  1309. disp += addr;
  1310. if(str != NULL)
  1311. str += sprintf(str, "%xh", disp);
  1312. break;
  1313. case DA_o1:
  1314. if(str != NULL)
  1315. str += sprintf(str, "1");
  1316. break;
  1317. case DA_o3:
  1318. if(str != NULL)
  1319. str += sprintf(str, "3");
  1320. break;
  1321. case DA_OS:
  1322. if (size==DA_QUAD) {
  1323. disp = (uint64_t)(*((int64_t*)addr));
  1324. addr+=8;
  1325. } else if (size==DA_LONG) {
  1326. disp = (uint64_t)(*((int32_t*)addr));
  1327. addr+=4;
  1328. } else if (size==DA_WORD) {
  1329. disp = (uint64_t)(*((int16_t*)addr));
  1330. addr+=2;
  1331. } else if (size==DA_BYTE) {
  1332. disp = (uint64_t)(*((int8_t*)addr));
  1333. addr++;
  1334. }
  1335. imm = (uint64_t)(*((uint16_t*)addr));
  1336. addr+=2;
  1337. if(str != NULL)
  1338. str += sprintf(str, "%x:%xh", imm, disp);
  1339. break;
  1340. default:
  1341. if(str != NULL)
  1342. str += sprintf(str, "?");
  1343. break;
  1344. }
  1345. }
  1346. end:
  1347. if (addr - disasmstart > 15 && str!=NULL)
  1348. str += sprintf(str," <too long>");
  1349. end2:
  1350. if(str!=NULL)
  1351. *str=0;
  1352. return addr;
  1353. }