db_disasm.c 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816
  1. /*
  2. * Mach Operating System
  3. * Copyright (c) 1991,1990 Carnegie Mellon University
  4. * All Rights Reserved.
  5. *
  6. * Permission to use, copy, modify and distribute this software and its
  7. * documentation is hereby granted, provided that both the copyright
  8. * notice and this permission notice appear in all copies of the
  9. * software, derivative works or modified versions, and any portions
  10. * thereof, and that both notices appear in supporting documentation.
  11. *
  12. * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13. * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14. * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15. *
  16. * Carnegie Mellon requests users of this software to return to
  17. *
  18. * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
  19. * School of Computer Science
  20. * Carnegie Mellon University
  21. * Pittsburgh PA 15213-3890
  22. *
  23. * any improvements or extensions that they make and grant Carnegie Mellon
  24. * the rights to redistribute these changes.
  25. */
  26. /*
  27. * HISTORY
  28. *
  29. * Revision 2.6 92/01/03 20:05:00 dbg
  30. * Add a switch to disassemble 16-bit code.
  31. * Fix spelling of 'lods' opcodes.
  32. * [91/10/30 dbg]
  33. *
  34. * Revision 2.5 91/10/09 16:05:58 af
  35. * Supported disassemble of non current task by passing task parameter.
  36. * [91/08/29 tak]
  37. *
  38. * Revision 2.4 91/05/14 16:05:04 mrt
  39. * Correcting copyright
  40. *
  41. * Revision 2.3 91/02/05 17:11:03 mrt
  42. * Changed to new Mach copyright
  43. * [91/02/01 17:31:03 mrt]
  44. *
  45. * Revision 2.2 90/08/27 21:55:56 dbg
  46. * Fix register operand for move to/from control/test/debug
  47. * register instructions. Add i486 instructions.
  48. * [90/08/27 dbg]
  49. *
  50. * Import db_sym.h. Print instruction displacements in
  51. * current radix (signed). Change calling sequence of
  52. * db_disasm.
  53. * [90/08/21 dbg]
  54. * Fix includes.
  55. * [90/08/08 dbg]
  56. * Created.
  57. * [90/07/25 dbg]
  58. *
  59. */
  60. /*
  61. * Instruction disassembler.
  62. */
  63. #include "debugger.h"
  64. #if defined(__i386__) || defined(__x86_64__)
  65. /*
  66. * Switch to disassemble 16-bit code.
  67. */
  68. static BOOL db_disasm_16 = FALSE;
  69. /*
  70. * Flag to indicate whether we need to display instruction,
  71. * or whether we just need to know the address of the next
  72. * instruction.
  73. */
  74. static BOOL db_display = FALSE;
  75. /*
  76. * Size attributes
  77. */
  78. #define BYTE 0
  79. #define WORD 1
  80. #define LONG 2
  81. #define QUAD 3
  82. #define DQUA 4
  83. #define SNGL 5
  84. #define DBLR 6
  85. #define EXTR 7
  86. #define SDEP 8
  87. #define NONE 9
  88. /*
  89. * Addressing modes
  90. */
  91. #define E 1 /* general effective address */
  92. #define Eind 2 /* indirect address (jump, call) */
  93. #define Ew 3 /* address, word size */
  94. #define Eb 4 /* address, byte size */
  95. #define R 5 /* register, in 'reg' field */
  96. #define Rw 6 /* word register, in 'reg' field */
  97. #define Ri 7 /* register in instruction */
  98. #define S 8 /* segment reg, in 'reg' field */
  99. #define Si 9 /* segment reg, in instruction */
  100. #define A 10 /* accumulator */
  101. #define BX 11 /* (bx) */
  102. #define CL 12 /* cl, for shifts */
  103. #define DX 13 /* dx, for IO */
  104. #define SI 14 /* si */
  105. #define DI 15 /* di */
  106. #define CR 16 /* control register */
  107. #define DR 17 /* debug register */
  108. #define TR 18 /* test register */
  109. #define I 19 /* immediate, unsigned */
  110. #define Is 20 /* immediate, signed */
  111. #define Ib 21 /* byte immediate, unsigned */
  112. #define Ibs 22 /* byte immediate, signed */
  113. #define Iw 23 /* word immediate, unsigned */
  114. #define Il 24 /* long immediate */
  115. #define O 25 /* direct address */
  116. #define Db 26 /* byte displacement from EIP */
  117. #define Dl 27 /* long displacement from EIP */
  118. #define o1 28 /* constant 1 */
  119. #define o3 29 /* constant 3 */
  120. #define OS 30 /* immediate offset/segment */
  121. #define ST 31 /* FP stack top */
  122. #define STI 32 /* FP stack */
  123. #define X 33 /* extended FP op */
  124. #define XA 34 /* for 'fstcw %ax' */
  125. #define MX 35 /* special register (MMX reg %mm0-7) */
  126. #define EMX 36 /* special register (MMX reg %mm0-7) */
  127. #define XMM 37 /* special register (floating point reg %xmm0-7) */
  128. #define EXMM 38 /* special register (floating point reg %xmm0-7) */
  129. struct inst {
  130. const char *i_name; /* name */
  131. short i_has_modrm; /* has regmodrm byte */
  132. short i_size; /* operand size */
  133. int i_mode; /* addressing modes */
  134. const char *i_extra; /* pointer to extra opcode table */
  135. };
  136. #define op1(x) (x)
  137. #define op2(x,y) ((x)|((y)<<8))
  138. #define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
  139. struct finst {
  140. const char *f_name; /* name for memory instruction */
  141. int f_size; /* size for memory instruction */
  142. int f_rrmode; /* mode for rr instruction */
  143. const char *f_rrname; /* name for rr instruction
  144. (or pointer to table) */
  145. };
  146. static const char * const db_Grp6[] = {
  147. "sldt",
  148. "str",
  149. "lldt",
  150. "ltr",
  151. "verr",
  152. "verw",
  153. "",
  154. ""
  155. };
  156. static const char * const db_Grp7[] = {
  157. "sgdt",
  158. "sidt",
  159. "lgdt",
  160. "lidt",
  161. "smsw",
  162. "",
  163. "lmsw",
  164. "invlpg"
  165. };
  166. static const char * const db_Grp8[] = {
  167. "",
  168. "",
  169. "",
  170. "",
  171. "bt",
  172. "bts",
  173. "btr",
  174. "btc"
  175. };
  176. static const char * const db_Grp10[] = {
  177. "(bad)",
  178. "(bad)",
  179. "psrlw",
  180. "(bad)",
  181. "psraw",
  182. "(bad)",
  183. "psllw",
  184. "(bad)"
  185. };
  186. static const char * const db_Grp11[] = {
  187. "(bad)",
  188. "(bad)",
  189. "psrld",
  190. "(bad)",
  191. "psrad",
  192. "(bad)",
  193. "pslld",
  194. "(bad)"
  195. };
  196. static const char * const db_Grp12[] = {
  197. "(bad)",
  198. "(bad)",
  199. "psrlq",
  200. "(bad)",
  201. "psraq",
  202. "(bad)",
  203. "psllq",
  204. "(bad)"
  205. };
  206. static const struct inst db_inst_0f0x[] = {
  207. /*00*/ { "", TRUE, NONE, op1(Ew), (const char *)db_Grp6 },
  208. /*01*/ { "", TRUE, NONE, op1(Ew), (const char *)db_Grp7 },
  209. /*02*/ { "lar", TRUE, LONG, op2(E,R), 0 },
  210. /*03*/ { "lsl", TRUE, LONG, op2(E,R), 0 },
  211. /*04*/ { "", FALSE, NONE, 0, 0 },
  212. /*05*/ { "syscall", FALSE, NONE, 0, 0 },
  213. /*06*/ { "clts", FALSE, NONE, 0, 0 },
  214. /*07*/ { "sysret", FALSE, NONE, 0, 0 },
  215. /*08*/ { "invd", FALSE, NONE, 0, 0 },
  216. /*09*/ { "wbinvd",FALSE, NONE, 0, 0 },
  217. /*0a*/ { "", FALSE, NONE, 0, 0 },
  218. /*0b*/ { "", FALSE, NONE, 0, 0 },
  219. /*0c*/ { "", FALSE, NONE, 0, 0 },
  220. /*0d*/ { "", FALSE, NONE, 0, 0 },
  221. /*0e*/ { "", FALSE, NONE, 0, 0 },
  222. /*0f*/ { "", FALSE, NONE, 0, 0 },
  223. };
  224. static const struct inst db_inst_0f2x[] = {
  225. /*20*/ { "mov", TRUE, LONG, op2(CR,E), 0 }, /* use E for reg */
  226. /*21*/ { "mov", TRUE, LONG, op2(DR,E), 0 }, /* since mod == 11 */
  227. /*22*/ { "mov", TRUE, LONG, op2(E,CR), 0 },
  228. /*23*/ { "mov", TRUE, LONG, op2(E,DR), 0 },
  229. /*24*/ { "mov", TRUE, LONG, op2(TR,E), 0 },
  230. /*25*/ { "(bad)", FALSE, NONE, 0, 0 },
  231. /*26*/ { "mov", TRUE, LONG, op2(E,TR), 0 },
  232. /*27*/ { "(bad)", FALSE, NONE, 0, 0 },
  233. /*28*/ { "", FALSE, NONE, 0, 0 },
  234. /*29*/ { "", FALSE, NONE, 0, 0 },
  235. /*2a*/ { "", FALSE, NONE, 0, 0 },
  236. /*2b*/ { "", FALSE, NONE, 0, 0 },
  237. /*2c*/ { "", FALSE, NONE, 0, 0 },
  238. /*2d*/ { "", FALSE, NONE, 0, 0 },
  239. /*2e*/ { "", FALSE, NONE, 0, 0 },
  240. /*2f*/ { "", FALSE, NONE, 0, 0 },
  241. };
  242. static const struct inst db_inst_0f3x[] = {
  243. /*30*/ { "wrmsr", FALSE, NONE, 0, 0 },
  244. /*31*/ { "rdtsc", FALSE, NONE, 0, 0 },
  245. /*32*/ { "rdmsr", FALSE, NONE, 0, 0 },
  246. /*33*/ { "rdpmc", FALSE, NONE, 0, 0 },
  247. /*34*/ { "sysenter",FALSE,NONE, 0, 0 },
  248. /*35*/ { "sysexit",FALSE,NONE, 0, 0 },
  249. /*36*/ { "(bad)", FALSE, NONE, 0, 0 },
  250. /*37*/ { "(bad)", FALSE, NONE, 0, 0 },
  251. /*38*/ { "(bad)",FALSE, NONE, 0, 0 },
  252. /*39*/ { "(bad)",FALSE, NONE, 0, 0 },
  253. /*3a*/ { "(bad)",FALSE, NONE, 0, 0 },
  254. /*3b*/ { "(bad)",FALSE, NONE, 0, 0 },
  255. /*3c*/ { "(bad)",FALSE, NONE, 0, 0 },
  256. /*3d*/ { "(bad)",FALSE, NONE, 0, 0 },
  257. /*3e*/ { "(bad)",FALSE, NONE, 0, 0 },
  258. /*3f*/ { "(bad)",FALSE, NONE, 0, 0 },
  259. };
  260. static const struct inst db_inst_0f4x[] = {
  261. /*40*/ { "cmovo", TRUE, NONE, op2(E, R), 0 },
  262. /*41*/ { "cmovno", TRUE, NONE, op2(E, R), 0 },
  263. /*42*/ { "cmovnae",TRUE, NONE, op2(E, R), 0 },
  264. /*43*/ { "cmovnb", TRUE, NONE, op2(E, R), 0 },
  265. /*44*/ { "cmove", TRUE, NONE, op2(E, R), 0 },
  266. /*45*/ { "cmovne", TRUE, NONE, op2(E, R), 0 },
  267. /*46*/ { "cmovna", TRUE, NONE, op2(E, R), 0 },
  268. /*47*/ { "cmova", TRUE, NONE, op2(E, R), 0 },
  269. /*48*/ { "cmovs", TRUE, NONE, op2(E, R), 0 },
  270. /*49*/ { "cmovns", TRUE, NONE, op2(E, R), 0 },
  271. /*4a*/ { "cmovpe", TRUE, NONE, op2(E, R), 0 },
  272. /*4b*/ { "cmovpo", TRUE, NONE, op2(E, R), 0 },
  273. /*4c*/ { "cmovl", TRUE, NONE, op2(E, R), 0 },
  274. /*4d*/ { "cmovge", TRUE, NONE, op2(E, R), 0 },
  275. /*4e*/ { "cmovle", TRUE, NONE, op2(E, R), 0 },
  276. /*4f*/ { "cmovnle",TRUE, NONE, op2(E, R), 0 },
  277. };
  278. static const struct inst db_inst_0f5x[] = {
  279. /*50*/ { "movmskps",TRUE, NONE, op2(EXMM, R), 0 },
  280. /*51*/ { "sqrtps", TRUE, NONE, op2(EXMM, XMM), 0 },
  281. /*52*/ { "rsqrtps", TRUE, NONE, op2(EXMM, XMM), 0 },
  282. /*53*/ { "rcpps", TRUE, NONE, op2(EXMM, XMM), 0 },
  283. /*54*/ { "andps", TRUE, NONE, op2(EXMM, XMM), 0 },
  284. /*55*/ { "andnps", TRUE, NONE, op2(EXMM, XMM), 0 },
  285. /*56*/ { "orps", TRUE, NONE, op2(EXMM, XMM), 0 },
  286. /*57*/ { "xorps", TRUE, NONE, op2(EXMM, XMM), 0 },
  287. /*58*/ { "addps", TRUE, NONE, op2(EXMM, XMM), 0 },
  288. /*59*/ { "mulps", TRUE, NONE, op2(EXMM, XMM), 0 },
  289. /*5a*/ { "cvtps2pd",TRUE, NONE, op2(EXMM, XMM), 0 },
  290. /*5b*/ { "cvtdq2ps",TRUE, NONE, op2(EXMM, XMM), 0 },
  291. /*5c*/ { "subps", TRUE, NONE, op2(EXMM, XMM), 0 },
  292. /*5d*/ { "minps", TRUE, NONE, op2(EXMM, XMM), 0 },
  293. /*5e*/ { "divps", TRUE, NONE, op2(EXMM, XMM), 0 },
  294. /*5f*/ { "maxps", TRUE, NONE, op2(EXMM, XMM), 0 },
  295. };
  296. static const struct inst db_inst_0f6x[] = {
  297. /*60*/ { "punpcklbw", TRUE, NONE, op2(E, MX), 0 },
  298. /*61*/ { "punpcklwd", TRUE, NONE, op2(E, MX), 0 },
  299. /*62*/ { "punpckldq", TRUE, NONE, op2(E, MX), 0 },
  300. /*63*/ { "packsswb", TRUE, NONE, op2(E, MX), 0 },
  301. /*64*/ { "pcmpgtb", TRUE, NONE, op2(E, MX), 0 },
  302. /*65*/ { "pcmpgtw", TRUE, NONE, op2(E, MX), 0 },
  303. /*66*/ { "pcmpgtd", TRUE, NONE, op2(E, MX), 0 },
  304. /*67*/ { "packuswb", TRUE, NONE, op2(E, MX), 0 },
  305. /*68*/ { "punpckhbw", TRUE, NONE, op2(E, MX), 0 },
  306. /*69*/ { "punpckhwd", TRUE, NONE, op2(E, MX), 0 },
  307. /*6a*/ { "punpckhdq", TRUE, NONE, op2(E, MX), 0 },
  308. /*6b*/ { "packssdw", TRUE, NONE, op2(E, MX), 0 },
  309. /*6c*/ { "(bad)", TRUE, NONE, 0, 0 },
  310. /*6d*/ { "(bad)", TRUE, NONE, 0, 0 },
  311. /*6e*/ { "movd", TRUE, NONE, op2(E, MX), 0 },
  312. /*6f*/ { "movq", TRUE, NONE, op2(EMX, MX), 0 },
  313. };
  314. static const struct inst db_inst_0f7x[] = {
  315. /*70*/ { "pshufw", TRUE, NONE, op2(MX, EMX), 0 },
  316. /*71*/ { "(grp10)", TRUE, BYTE, op2(EMX, I), (const char*)db_Grp10 },
  317. /*72*/ { "(grp11)", TRUE, BYTE, op2(EMX, I), (const char*)db_Grp11 },
  318. /*73*/ { "(grp12)", TRUE, BYTE, op2(EMX, I), (const char*)db_Grp12 },
  319. /*74*/ { "pcmpeqb", TRUE, NONE, op2(E, MX), 0 },
  320. /*75*/ { "pcmpeqw", TRUE, NONE, op2(E, MX), 0 },
  321. /*76*/ { "pcmpeqd", TRUE, NONE, op2(E, MX), 0 },
  322. /*77*/ { "emms", FALSE,NONE, 0, 0 },
  323. /*78*/ { "(bad)", TRUE, NONE, 0, 0 },
  324. /*79*/ { "(bad)", TRUE, NONE, 0, 0 },
  325. /*7a*/ { "(bad)", TRUE, NONE, 0, 0 },
  326. /*7b*/ { "(bad)", TRUE, NONE, 0, 0 },
  327. /*7c*/ { "(bad)", TRUE, NONE, 0, 0 },
  328. /*7d*/ { "(bad)", TRUE, NONE, 0, 0 },
  329. /*7e*/ { "movd", TRUE, NONE, op2(E, MX), 0 },
  330. /*7f*/ { "movq", TRUE, NONE, op2(MX, EMX), 0 },
  331. };
  332. static const struct inst db_inst_0f8x[] = {
  333. /*80*/ { "jo", FALSE, NONE, op1(Dl), 0 },
  334. /*81*/ { "jno", FALSE, NONE, op1(Dl), 0 },
  335. /*82*/ { "jb", FALSE, NONE, op1(Dl), 0 },
  336. /*83*/ { "jnb", FALSE, NONE, op1(Dl), 0 },
  337. /*84*/ { "jz", FALSE, NONE, op1(Dl), 0 },
  338. /*85*/ { "jnz", FALSE, NONE, op1(Dl), 0 },
  339. /*86*/ { "jbe", FALSE, NONE, op1(Dl), 0 },
  340. /*87*/ { "jnbe", FALSE, NONE, op1(Dl), 0 },
  341. /*88*/ { "js", FALSE, NONE, op1(Dl), 0 },
  342. /*89*/ { "jns", FALSE, NONE, op1(Dl), 0 },
  343. /*8a*/ { "jp", FALSE, NONE, op1(Dl), 0 },
  344. /*8b*/ { "jnp", FALSE, NONE, op1(Dl), 0 },
  345. /*8c*/ { "jl", FALSE, NONE, op1(Dl), 0 },
  346. /*8d*/ { "jnl", FALSE, NONE, op1(Dl), 0 },
  347. /*8e*/ { "jle", FALSE, NONE, op1(Dl), 0 },
  348. /*8f*/ { "jnle", FALSE, NONE, op1(Dl), 0 },
  349. };
  350. static const struct inst db_inst_0f9x[] = {
  351. /*90*/ { "seto", TRUE, NONE, op1(Eb), 0 },
  352. /*91*/ { "setno", TRUE, NONE, op1(Eb), 0 },
  353. /*92*/ { "setb", TRUE, NONE, op1(Eb), 0 },
  354. /*93*/ { "setnb", TRUE, NONE, op1(Eb), 0 },
  355. /*94*/ { "setz", TRUE, NONE, op1(Eb), 0 },
  356. /*95*/ { "setnz", TRUE, NONE, op1(Eb), 0 },
  357. /*96*/ { "setbe", TRUE, NONE, op1(Eb), 0 },
  358. /*97*/ { "setnbe",TRUE, NONE, op1(Eb), 0 },
  359. /*98*/ { "sets", TRUE, NONE, op1(Eb), 0 },
  360. /*99*/ { "setns", TRUE, NONE, op1(Eb), 0 },
  361. /*9a*/ { "setp", TRUE, NONE, op1(Eb), 0 },
  362. /*9b*/ { "setnp", TRUE, NONE, op1(Eb), 0 },
  363. /*9c*/ { "setl", TRUE, NONE, op1(Eb), 0 },
  364. /*9d*/ { "setnl", TRUE, NONE, op1(Eb), 0 },
  365. /*9e*/ { "setle", TRUE, NONE, op1(Eb), 0 },
  366. /*9f*/ { "setnle",TRUE, NONE, op1(Eb), 0 },
  367. };
  368. static const struct inst db_inst_0fax[] = {
  369. /*a0*/ { "push", FALSE, NONE, op1(Si), 0 },
  370. /*a1*/ { "pop", FALSE, NONE, op1(Si), 0 },
  371. /*a2*/ { "cpuid", FALSE, NONE, 0, 0 },
  372. /*a3*/ { "bt", TRUE, LONG, op2(E,R), 0 },
  373. /*a4*/ { "shld", TRUE, LONG, op3(Ib,E,R), 0 },
  374. /*a5*/ { "shld", TRUE, LONG, op3(CL,E,R), 0 },
  375. /*a6*/ { "", FALSE, NONE, 0, 0 },
  376. /*a7*/ { "", FALSE, NONE, 0, 0 },
  377. /*a8*/ { "push", FALSE, NONE, op1(Si), 0 },
  378. /*a9*/ { "pop", FALSE, NONE, op1(Si), 0 },
  379. /*aa*/ { "", FALSE, NONE, 0, 0 },
  380. /*ab*/ { "bts", TRUE, LONG, op2(E,R), 0 },
  381. /*ac*/ { "shrd", TRUE, LONG, op3(Ib,E,R), 0 },
  382. /*ad*/ { "shrd", TRUE, LONG, op3(CL,E,R), 0 },
  383. /*a6*/ { "", FALSE, NONE, 0, 0 },
  384. /*a7*/ { "imul", TRUE, LONG, op2(E,R), 0 },
  385. };
  386. static const struct inst db_inst_0fbx[] = {
  387. /*b0*/ { "cmpxchg",TRUE, BYTE, op2(E, R), 0 },
  388. /*b1*/ { "cmpxchg",TRUE, LONG, op2(E, R), 0 },
  389. /*b2*/ { "lss", TRUE, LONG, op2(E, R), 0 },
  390. /*b3*/ { "bts", TRUE, LONG, op2(R, E), 0 },
  391. /*b4*/ { "lfs", TRUE, LONG, op2(E, R), 0 },
  392. /*b5*/ { "lgs", TRUE, LONG, op2(E, R), 0 },
  393. /*b6*/ { "movzb", TRUE, LONG, op2(E, R), 0 },
  394. /*b7*/ { "movzw", TRUE, LONG, op2(E, R), 0 },
  395. /*b8*/ { "", FALSE, NONE, 0, 0 },
  396. /*b9*/ { "", FALSE, NONE, 0, 0 },
  397. /*ba*/ { "", TRUE, LONG, op2(Ib, E), (const char *)db_Grp8 },
  398. /*bb*/ { "btc", TRUE, LONG, op2(R, E), 0 },
  399. /*bc*/ { "bsf", TRUE, LONG, op2(E, R), 0 },
  400. /*bd*/ { "bsr", TRUE, LONG, op2(E, R), 0 },
  401. /*be*/ { "movsb", TRUE, LONG, op2(E, R), 0 },
  402. /*bf*/ { "movsw", TRUE, LONG, op2(E, R), 0 },
  403. };
  404. static const struct inst db_inst_0fcx[] = {
  405. /*c0*/ { "xadd", TRUE, BYTE, op2(R, E), 0 },
  406. /*c1*/ { "xadd", TRUE, LONG, op2(R, E), 0 },
  407. /*c2*/ { "", FALSE, NONE, 0, 0 },
  408. /*c3*/ { "", FALSE, NONE, 0, 0 },
  409. /*c4*/ { "", FALSE, NONE, 0, 0 },
  410. /*c5*/ { "", FALSE, NONE, 0, 0 },
  411. /*c6*/ { "", FALSE, NONE, 0, 0 },
  412. /*c7*/ { "", FALSE, NONE, 0, 0 },
  413. /*c8*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
  414. /*c9*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
  415. /*ca*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
  416. /*cb*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
  417. /*cc*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
  418. /*cd*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
  419. /*ce*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
  420. /*cf*/ { "bswap", FALSE, LONG, op1(Ri), 0 },
  421. };
  422. static const struct inst db_inst_0fdx[] = {
  423. /*d0*/ { "(bad)", FALSE, NONE,0, 0 },
  424. /*d1*/ { "psrlw", TRUE, NONE,op2(MX,EMX), 0 },
  425. /*d2*/ { "psrld", TRUE, NONE,op2(MX,EMX), 0 },
  426. /*d3*/ { "psrld", TRUE, NONE,op2(MX,EMX), 0 },
  427. /*d4*/ { "(bad)", FALSE, NONE,0, 0 },
  428. /*d5*/ { "pmulww", TRUE, NONE,op2(MX,EMX), 0 },
  429. /*d6*/ { "(bad)", FALSE, NONE,0, 0 },
  430. /*d7*/ { "pmovmskb",FALSE, NONE,op2(MX,EMX),0 },
  431. /*d8*/ { "psubusb", TRUE, NONE,op2(MX,EMX), 0 },
  432. /*d9*/ { "psubusw", TRUE, NONE,op2(MX,EMX), 0 },
  433. /*da*/ { "pminub", TRUE, NONE,op2(MX,EMX), 0 },
  434. /*db*/ { "pand", TRUE, NONE,op2(MX,EMX), 0 },
  435. /*dc*/ { "paddusb", TRUE, NONE,op2(MX,EMX), 0 },
  436. /*dd*/ { "paddusw", TRUE, NONE,op2(MX,EMX), 0 },
  437. /*de*/ { "pmaxub", TRUE, NONE,op2(MX,EMX), 0 },
  438. /*df*/ { "pandn", TRUE, NONE,op2(MX,EMX), 0 },
  439. };
  440. static const struct inst db_inst_0fex[] = {
  441. /*e0*/ { "pavgb", TRUE, NONE, op2(MX, EMX), 0 },
  442. /*e1*/ { "psraw", TRUE, NONE, op2(MX, EMX), 0 },
  443. /*e2*/ { "psrad", TRUE, NONE, op2(MX, EMX), 0 },
  444. /*e3*/ { "pavgw", TRUE, NONE, op2(MX, EMX), 0 },
  445. /*e4*/ { "pmulhuw",TRUE, NONE, op2(MX, EMX), 0 },
  446. /*e5*/ { "pmulhw", TRUE, NONE, op2(MX, EMX), 0 },
  447. /*e6*/ { "(bad)", FALSE,NONE, 0, 0 },
  448. /*e7*/ { "movntq", TRUE, NONE, op2(MX, EMX), 0 },
  449. /*e8*/ { "psubsb", TRUE, NONE, op2(MX, EMX), 0 },
  450. /*e9*/ { "psubsw", TRUE, NONE, op2(MX, EMX), 0 },
  451. /*ea*/ { "pminsw", TRUE, NONE, op2(MX, EMX), 0 },
  452. /*eb*/ { "por", TRUE, NONE, op2(MX, EMX), 0 },
  453. /*ec*/ { "paddsb", TRUE, NONE, op2(MX, EMX), 0 },
  454. /*ed*/ { "paddsw", TRUE, NONE, op2(MX, EMX), 0 },
  455. /*ee*/ { "pmaxsw", TRUE, NONE, op2(MX, EMX), 0 },
  456. /*ef*/ { "pxor", TRUE, NONE, op2(MX, EMX), 0 },
  457. };
  458. static const struct inst db_inst_0ffx[] = {
  459. /*f0*/ { "(bad)", FALSE,NONE, 0, 0 },
  460. /*f1*/ { "psllw", TRUE, NONE, op2(MX, EMX), 0 },
  461. /*f2*/ { "pslld", TRUE, NONE, op2(MX, EMX), 0 },
  462. /*f3*/ { "psllq", TRUE, NONE, op2(MX, EMX), 0 },
  463. /*f4*/ { "(bad)", FALSE,NONE, 0, 0 },
  464. /*f5*/ { "pmaddwd",TRUE, NONE, op2(MX, EMX), 0 },
  465. /*f6*/ { "psadbw", TRUE, NONE, op2(MX, EMX), 0 },
  466. /*f7*/ { "maskmovq",TRUE,NONE, op2(MX, EMX), 0 },
  467. /*f8*/ { "psubb", TRUE, NONE, op2(MX, EMX), 0 },
  468. /*f9*/ { "psubw", TRUE, NONE, op2(MX, EMX), 0 },
  469. /*fa*/ { "psubd", TRUE, NONE, op2(MX, EMX), 0 },
  470. /*fb*/ { "(bad)", FALSE,NONE, 0, 0 },
  471. /*fc*/ { "paddb", TRUE, NONE, op2(MX, EMX), 0 },
  472. /*fd*/ { "paddw", TRUE, NONE, op2(MX, EMX), 0 },
  473. /*fe*/ { "paddd", TRUE, NONE, op2(MX, EMX), 0 },
  474. /*ff*/ { "(bad)", FALSE, NONE, 0, 0 },
  475. };
  476. static const struct inst * const db_inst_0f[] = {
  477. db_inst_0f0x,
  478. 0,
  479. db_inst_0f2x,
  480. db_inst_0f3x,
  481. db_inst_0f4x,
  482. db_inst_0f5x,
  483. db_inst_0f6x,
  484. db_inst_0f7x,
  485. db_inst_0f8x,
  486. db_inst_0f9x,
  487. db_inst_0fax,
  488. db_inst_0fbx,
  489. db_inst_0fcx,
  490. db_inst_0fdx,
  491. db_inst_0fex,
  492. db_inst_0ffx
  493. };
  494. static const char * const db_Esc92[] = {
  495. "fnop", "", "", "", "", "", "", ""
  496. };
  497. static const char * const db_Esc93[] = {
  498. "", "", "", "", "", "", "", ""
  499. };
  500. static const char * const db_Esc94[] = {
  501. "fchs", "fabs", "", "", "ftst", "fxam", "", ""
  502. };
  503. static const char * const db_Esc95[] = {
  504. "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz",""
  505. };
  506. static const char * const db_Esc96[] = {
  507. "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp",
  508. "fincstp"
  509. };
  510. static const char * const db_Esc97[] = {
  511. "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"
  512. };
  513. static const char * const db_Esca4[] = {
  514. "", "fucompp","", "", "", "", "", ""
  515. };
  516. static const char * const db_Escb4[] = {
  517. "", "", "fnclex","fninit","", "", "", ""
  518. };
  519. static const char * const db_Esce3[] = {
  520. "", "fcompp","", "", "", "", "", ""
  521. };
  522. static const char * const db_Escf4[] = {
  523. "fnstsw","", "", "", "", "", "", ""
  524. };
  525. static const struct finst db_Esc8[] = {
  526. /*0*/ { "fadd", SNGL, op2(STI,ST), 0 },
  527. /*1*/ { "fmul", SNGL, op2(STI,ST), 0 },
  528. /*2*/ { "fcom", SNGL, op2(STI,ST), 0 },
  529. /*3*/ { "fcomp", SNGL, op2(STI,ST), 0 },
  530. /*4*/ { "fsub", SNGL, op2(STI,ST), 0 },
  531. /*5*/ { "fsubr", SNGL, op2(STI,ST), 0 },
  532. /*6*/ { "fdiv", SNGL, op2(STI,ST), 0 },
  533. /*7*/ { "fdivr", SNGL, op2(STI,ST), 0 },
  534. };
  535. static const struct finst db_Esc9[] = {
  536. /*0*/ { "fld", SNGL, op1(STI), 0 },
  537. /*1*/ { "", NONE, op1(STI), "fxch" },
  538. /*2*/ { "fst", SNGL, op1(X), (const char *)db_Esc92 },
  539. /*3*/ { "fstp", SNGL, op1(X), (const char *)db_Esc93 },
  540. /*4*/ { "fldenv", NONE, op1(X), (const char *)db_Esc94 },
  541. /*5*/ { "fldcw", NONE, op1(X), (const char *)db_Esc95 },
  542. /*6*/ { "fnstenv",NONE, op1(X), (const char *)db_Esc96 },
  543. /*7*/ { "fnstcw", NONE, op1(X), (const char *)db_Esc97 },
  544. };
  545. static const struct finst db_Esca[] = {
  546. /*0*/ { "fiadd", WORD, 0, 0 },
  547. /*1*/ { "fimul", WORD, 0, 0 },
  548. /*2*/ { "ficom", WORD, 0, 0 },
  549. /*3*/ { "ficomp", WORD, 0, 0 },
  550. /*4*/ { "fisub", WORD, op1(X), (const char *)db_Esca4 },
  551. /*5*/ { "fisubr", WORD, 0, 0 },
  552. /*6*/ { "fidiv", WORD, 0, 0 },
  553. /*7*/ { "fidivr", WORD, 0, 0 }
  554. };
  555. static const struct finst db_Escb[] = {
  556. /*0*/ { "fild", WORD, 0, 0 },
  557. /*1*/ { "", NONE, 0, 0 },
  558. /*2*/ { "fist", WORD, 0, 0 },
  559. /*3*/ { "fistp", WORD, 0, 0 },
  560. /*4*/ { "", WORD, op1(X), (const char *)db_Escb4 },
  561. /*5*/ { "fld", EXTR, 0, 0 },
  562. /*6*/ { "", WORD, 0, 0 },
  563. /*7*/ { "fstp", EXTR, 0, 0 },
  564. };
  565. static const struct finst db_Escc[] = {
  566. /*0*/ { "fadd", DBLR, op2(ST,STI), 0 },
  567. /*1*/ { "fmul", DBLR, op2(ST,STI), 0 },
  568. /*2*/ { "fcom", DBLR, op2(ST,STI), 0 },
  569. /*3*/ { "fcomp", DBLR, op2(ST,STI), 0 },
  570. /*4*/ { "fsub", DBLR, op2(ST,STI), "fsubr" },
  571. /*5*/ { "fsubr", DBLR, op2(ST,STI), "fsub" },
  572. /*6*/ { "fdiv", DBLR, op2(ST,STI), "fdivr" },
  573. /*7*/ { "fdivr", DBLR, op2(ST,STI), "fdiv" },
  574. };
  575. static const struct finst db_Escd[] = {
  576. /*0*/ { "fld", DBLR, op1(STI), "ffree" },
  577. /*1*/ { "", NONE, 0, 0 },
  578. /*2*/ { "fst", DBLR, op1(STI), 0 },
  579. /*3*/ { "fstp", DBLR, op1(STI), 0 },
  580. /*4*/ { "frstor", NONE, op1(STI), "fucom" },
  581. /*5*/ { "", NONE, op1(STI), "fucomp" },
  582. /*6*/ { "fnsave", NONE, 0, 0 },
  583. /*7*/ { "fnstsw", NONE, 0, 0 },
  584. };
  585. static const struct finst db_Esce[] = {
  586. /*0*/ { "fiadd", LONG, op2(ST,STI), "faddp" },
  587. /*1*/ { "fimul", LONG, op2(ST,STI), "fmulp" },
  588. /*2*/ { "ficom", LONG, 0, 0 },
  589. /*3*/ { "ficomp", LONG, op1(X), (const char *)db_Esce3 },
  590. /*4*/ { "fisub", LONG, op2(ST,STI), "fsubrp" },
  591. /*5*/ { "fisubr", LONG, op2(ST,STI), "fsubp" },
  592. /*6*/ { "fidiv", LONG, op2(ST,STI), "fdivrp" },
  593. /*7*/ { "fidivr", LONG, op2(ST,STI), "fdivp" },
  594. };
  595. static const struct finst db_Escf[] = {
  596. /*0*/ { "fild", LONG, 0, 0 },
  597. /*1*/ { "", LONG, 0, 0 },
  598. /*2*/ { "fist", LONG, 0, 0 },
  599. /*3*/ { "fistp", LONG, 0, 0 },
  600. /*4*/ { "fbld", NONE, op1(XA), (const char *)db_Escf4 },
  601. /*5*/ { "fld", QUAD, 0, 0 },
  602. /*6*/ { "fbstp", NONE, 0, 0 },
  603. /*7*/ { "fstp", QUAD, 0, 0 },
  604. };
  605. static const struct finst * const db_Esc_inst[] = {
  606. db_Esc8, db_Esc9, db_Esca, db_Escb,
  607. db_Escc, db_Escd, db_Esce, db_Escf
  608. };
  609. static const char * const db_Grp1[] = {
  610. "add",
  611. "or",
  612. "adc",
  613. "sbb",
  614. "and",
  615. "sub",
  616. "xor",
  617. "cmp"
  618. };
  619. static const char * const db_Grp2[] = {
  620. "rol",
  621. "ror",
  622. "rcl",
  623. "rcr",
  624. "shl",
  625. "shr",
  626. "shl",
  627. "sar"
  628. };
  629. static const struct inst db_Grp3[] = {
  630. { "test", TRUE, NONE, op2(I,E), 0 },
  631. { "test", TRUE, NONE, op2(I,E), 0 },
  632. { "not", TRUE, NONE, op1(E), 0 },
  633. { "neg", TRUE, NONE, op1(E), 0 },
  634. { "mul", TRUE, NONE, op2(E,A), 0 },
  635. { "imul", TRUE, NONE, op2(E,A), 0 },
  636. { "div", TRUE, NONE, op2(E,A), 0 },
  637. { "idiv", TRUE, NONE, op2(E,A), 0 },
  638. };
  639. static const struct inst db_Grp4[] = {
  640. { "inc", TRUE, BYTE, op1(E), 0 },
  641. { "dec", TRUE, BYTE, op1(E), 0 },
  642. { "", TRUE, NONE, 0, 0 },
  643. { "", TRUE, NONE, 0, 0 },
  644. { "", TRUE, NONE, 0, 0 },
  645. { "", TRUE, NONE, 0, 0 },
  646. { "", TRUE, NONE, 0, 0 },
  647. { "", TRUE, NONE, 0, 0 }
  648. };
  649. static const struct inst db_Grp5[] = {
  650. { "inc", TRUE, LONG, op1(E), 0 },
  651. { "dec", TRUE, LONG, op1(E), 0 },
  652. { "call", TRUE, NONE, op1(Eind),0 },
  653. { "lcall", TRUE, NONE, op1(Eind),0 },
  654. { "jmp", TRUE, NONE, op1(Eind),0 },
  655. { "ljmp", TRUE, NONE, op1(Eind),0 },
  656. { "push", TRUE, LONG, op1(E), 0 },
  657. { "", TRUE, NONE, 0, 0 }
  658. };
  659. static const struct inst db_inst_table[256] = {
  660. /*00*/ { "add", TRUE, BYTE, op2(R, E), 0 },
  661. /*01*/ { "add", TRUE, LONG, op2(R, E), 0 },
  662. /*02*/ { "add", TRUE, BYTE, op2(E, R), 0 },
  663. /*03*/ { "add", TRUE, LONG, op2(E, R), 0 },
  664. /*04*/ { "add", FALSE, BYTE, op2(Is, A), 0 },
  665. /*05*/ { "add", FALSE, LONG, op2(Is, A), 0 },
  666. /*06*/ { "push", FALSE, NONE, op1(Si), 0 },
  667. /*07*/ { "pop", FALSE, NONE, op1(Si), 0 },
  668. /*08*/ { "or", TRUE, BYTE, op2(R, E), 0 },
  669. /*09*/ { "or", TRUE, LONG, op2(R, E), 0 },
  670. /*0a*/ { "or", TRUE, BYTE, op2(E, R), 0 },
  671. /*0b*/ { "or", TRUE, LONG, op2(E, R), 0 },
  672. /*0c*/ { "or", FALSE, BYTE, op2(I, A), 0 },
  673. /*0d*/ { "or", FALSE, LONG, op2(I, A), 0 },
  674. /*0e*/ { "push", FALSE, NONE, op1(Si), 0 },
  675. /*0f*/ { "", FALSE, NONE, 0, 0 },
  676. /*10*/ { "adc", TRUE, BYTE, op2(R, E), 0 },
  677. /*11*/ { "adc", TRUE, LONG, op2(R, E), 0 },
  678. /*12*/ { "adc", TRUE, BYTE, op2(E, R), 0 },
  679. /*13*/ { "adc", TRUE, LONG, op2(E, R), 0 },
  680. /*14*/ { "adc", FALSE, BYTE, op2(Is, A), 0 },
  681. /*15*/ { "adc", FALSE, LONG, op2(Is, A), 0 },
  682. /*16*/ { "push", FALSE, NONE, op1(Si), 0 },
  683. /*17*/ { "pop", FALSE, NONE, op1(Si), 0 },
  684. /*18*/ { "sbb", TRUE, BYTE, op2(R, E), 0 },
  685. /*19*/ { "sbb", TRUE, LONG, op2(R, E), 0 },
  686. /*1a*/ { "sbb", TRUE, BYTE, op2(E, R), 0 },
  687. /*1b*/ { "sbb", TRUE, LONG, op2(E, R), 0 },
  688. /*1c*/ { "sbb", FALSE, BYTE, op2(Is, A), 0 },
  689. /*1d*/ { "sbb", FALSE, LONG, op2(Is, A), 0 },
  690. /*1e*/ { "push", FALSE, NONE, op1(Si), 0 },
  691. /*1f*/ { "pop", FALSE, NONE, op1(Si), 0 },
  692. /*20*/ { "and", TRUE, BYTE, op2(R, E), 0 },
  693. /*21*/ { "and", TRUE, LONG, op2(R, E), 0 },
  694. /*22*/ { "and", TRUE, BYTE, op2(E, R), 0 },
  695. /*23*/ { "and", TRUE, LONG, op2(E, R), 0 },
  696. /*24*/ { "and", FALSE, BYTE, op2(I, A), 0 },
  697. /*25*/ { "and", FALSE, LONG, op2(I, A), 0 },
  698. /*26*/ { "", FALSE, NONE, 0, 0 },
  699. /*27*/ { "aaa", FALSE, NONE, 0, 0 },
  700. /*28*/ { "sub", TRUE, BYTE, op2(R, E), 0 },
  701. /*29*/ { "sub", TRUE, LONG, op2(R, E), 0 },
  702. /*2a*/ { "sub", TRUE, BYTE, op2(E, R), 0 },
  703. /*2b*/ { "sub", TRUE, LONG, op2(E, R), 0 },
  704. /*2c*/ { "sub", FALSE, BYTE, op2(Is, A), 0 },
  705. /*2d*/ { "sub", FALSE, LONG, op2(Is, A), 0 },
  706. /*2e*/ { "", FALSE, NONE, 0, 0 },
  707. /*2f*/ { "das", FALSE, NONE, 0, 0 },
  708. /*30*/ { "xor", TRUE, BYTE, op2(R, E), 0 },
  709. /*31*/ { "xor", TRUE, LONG, op2(R, E), 0 },
  710. /*32*/ { "xor", TRUE, BYTE, op2(E, R), 0 },
  711. /*33*/ { "xor", TRUE, LONG, op2(E, R), 0 },
  712. /*34*/ { "xor", FALSE, BYTE, op2(I, A), 0 },
  713. /*35*/ { "xor", FALSE, LONG, op2(I, A), 0 },
  714. /*36*/ { "", FALSE, NONE, 0, 0 },
  715. /*37*/ { "daa", FALSE, NONE, 0, 0 },
  716. /*38*/ { "cmp", TRUE, BYTE, op2(R, E), 0 },
  717. /*39*/ { "cmp", TRUE, LONG, op2(R, E), 0 },
  718. /*3a*/ { "cmp", TRUE, BYTE, op2(E, R), 0 },
  719. /*3b*/ { "cmp", TRUE, LONG, op2(E, R), 0 },
  720. /*3c*/ { "cmp", FALSE, BYTE, op2(Is, A), 0 },
  721. /*3d*/ { "cmp", FALSE, LONG, op2(Is, A), 0 },
  722. /*3e*/ { "", FALSE, NONE, 0, 0 },
  723. /*3f*/ { "aas", FALSE, NONE, 0, 0 },
  724. /*40*/ { "inc", FALSE, LONG, op1(Ri), 0 },
  725. /*41*/ { "inc", FALSE, LONG, op1(Ri), 0 },
  726. /*42*/ { "inc", FALSE, LONG, op1(Ri), 0 },
  727. /*43*/ { "inc", FALSE, LONG, op1(Ri), 0 },
  728. /*44*/ { "inc", FALSE, LONG, op1(Ri), 0 },
  729. /*45*/ { "inc", FALSE, LONG, op1(Ri), 0 },
  730. /*46*/ { "inc", FALSE, LONG, op1(Ri), 0 },
  731. /*47*/ { "inc", FALSE, LONG, op1(Ri), 0 },
  732. /*48*/ { "dec", FALSE, LONG, op1(Ri), 0 },
  733. /*49*/ { "dec", FALSE, LONG, op1(Ri), 0 },
  734. /*4a*/ { "dec", FALSE, LONG, op1(Ri), 0 },
  735. /*4b*/ { "dec", FALSE, LONG, op1(Ri), 0 },
  736. /*4c*/ { "dec", FALSE, LONG, op1(Ri), 0 },
  737. /*4d*/ { "dec", FALSE, LONG, op1(Ri), 0 },
  738. /*4e*/ { "dec", FALSE, LONG, op1(Ri), 0 },
  739. /*4f*/ { "dec", FALSE, LONG, op1(Ri), 0 },
  740. /*50*/ { "push", FALSE, LONG, op1(Ri), 0 },
  741. /*51*/ { "push", FALSE, LONG, op1(Ri), 0 },
  742. /*52*/ { "push", FALSE, LONG, op1(Ri), 0 },
  743. /*53*/ { "push", FALSE, LONG, op1(Ri), 0 },
  744. /*54*/ { "push", FALSE, LONG, op1(Ri), 0 },
  745. /*55*/ { "push", FALSE, LONG, op1(Ri), 0 },
  746. /*56*/ { "push", FALSE, LONG, op1(Ri), 0 },
  747. /*57*/ { "push", FALSE, LONG, op1(Ri), 0 },
  748. /*58*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  749. /*59*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  750. /*5a*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  751. /*5b*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  752. /*5c*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  753. /*5d*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  754. /*5e*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  755. /*5f*/ { "pop", FALSE, LONG, op1(Ri), 0 },
  756. /*60*/ { "pusha", FALSE, LONG, 0, 0 },
  757. /*61*/ { "popa", FALSE, LONG, 0, 0 },
  758. /*62*/ { "bound", TRUE, LONG, op2(E, R), 0 },
  759. /*63*/ { "arpl", TRUE, NONE, op2(Ew,Rw), 0 },
  760. /*64*/ { "", FALSE, NONE, 0, 0 },
  761. /*65*/ { "", FALSE, NONE, 0, 0 },
  762. /*66*/ { "", FALSE, NONE, 0, 0 },
  763. /*67*/ { "", FALSE, NONE, 0, 0 },
  764. /*68*/ { "push", FALSE, LONG, op1(I), 0 },
  765. /*69*/ { "imul", TRUE, LONG, op3(I,E,R), 0 },
  766. /*6a*/ { "push", FALSE, LONG, op1(Ib), 0 },
  767. /*6b*/ { "imul", TRUE, LONG, op3(Ibs,E,R),0 },
  768. /*6c*/ { "ins", FALSE, BYTE, op2(DX, DI), 0 },
  769. /*6d*/ { "ins", FALSE, LONG, op2(DX, DI), 0 },
  770. /*6e*/ { "outs", FALSE, BYTE, op2(SI, DX), 0 },
  771. /*6f*/ { "outs", FALSE, LONG, op2(SI, DX), 0 },
  772. /*70*/ { "jo", FALSE, NONE, op1(Db), 0 },
  773. /*71*/ { "jno", FALSE, NONE, op1(Db), 0 },
  774. /*72*/ { "jb", FALSE, NONE, op1(Db), 0 },
  775. /*73*/ { "jnb", FALSE, NONE, op1(Db), 0 },
  776. /*74*/ { "jz", FALSE, NONE, op1(Db), 0 },
  777. /*75*/ { "jnz", FALSE, NONE, op1(Db), 0 },
  778. /*76*/ { "jbe", FALSE, NONE, op1(Db), 0 },
  779. /*77*/ { "jnbe", FALSE, NONE, op1(Db), 0 },
  780. /*78*/ { "js", FALSE, NONE, op1(Db), 0 },
  781. /*79*/ { "jns", FALSE, NONE, op1(Db), 0 },
  782. /*7a*/ { "jp", FALSE, NONE, op1(Db), 0 },
  783. /*7b*/ { "jnp", FALSE, NONE, op1(Db), 0 },
  784. /*7c*/ { "jl", FALSE, NONE, op1(Db), 0 },
  785. /*7d*/ { "jnl", FALSE, NONE, op1(Db), 0 },
  786. /*7e*/ { "jle", FALSE, NONE, op1(Db), 0 },
  787. /*7f*/ { "jnle", FALSE, NONE, op1(Db), 0 },
  788. /*80*/ { "", TRUE, BYTE, op2(I, E), (const char *)db_Grp1 },
  789. /*81*/ { "", TRUE, LONG, op2(I, E), (const char *)db_Grp1 },
  790. /*82*/ { "", TRUE, BYTE, op2(Is,E), (const char *)db_Grp1 },
  791. /*83*/ { "", TRUE, LONG, op2(Ibs,E), (const char *)db_Grp1 },
  792. /*84*/ { "test", TRUE, BYTE, op2(R, E), 0 },
  793. /*85*/ { "test", TRUE, LONG, op2(R, E), 0 },
  794. /*86*/ { "xchg", TRUE, BYTE, op2(R, E), 0 },
  795. /*87*/ { "xchg", TRUE, LONG, op2(R, E), 0 },
  796. /*88*/ { "mov", TRUE, BYTE, op2(R, E), 0 },
  797. /*89*/ { "mov", TRUE, LONG, op2(R, E), 0 },
  798. /*8a*/ { "mov", TRUE, BYTE, op2(E, R), 0 },
  799. /*8b*/ { "mov", TRUE, LONG, op2(E, R), 0 },
  800. /*8c*/ { "mov", TRUE, NONE, op2(S, Ew), 0 },
  801. /*8d*/ { "lea", TRUE, LONG, op2(E, R), 0 },
  802. /*8e*/ { "mov", TRUE, NONE, op2(Ew, S), 0 },
  803. /*8f*/ { "pop", TRUE, LONG, op1(E), 0 },
  804. /*90*/ { "nop", FALSE, NONE, 0, 0 },
  805. /*91*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  806. /*92*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  807. /*93*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  808. /*94*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  809. /*95*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  810. /*96*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  811. /*97*/ { "xchg", FALSE, LONG, op2(A, Ri), 0 },
  812. /*98*/ { "cbw", FALSE, SDEP, 0, "cwde" }, /* cbw/cwde */
  813. /*99*/ { "cwd", FALSE, SDEP, 0, "cdq" }, /* cwd/cdq */
  814. /*9a*/ { "lcall", FALSE, NONE, op1(OS), 0 },
  815. /*9b*/ { "wait", FALSE, NONE, 0, 0 },
  816. /*9c*/ { "pushf", FALSE, LONG, 0, 0 },
  817. /*9d*/ { "popf", FALSE, LONG, 0, 0 },
  818. /*9e*/ { "sahf", FALSE, NONE, 0, 0 },
  819. /*9f*/ { "lahf", FALSE, NONE, 0, 0 },
  820. /*a0*/ { "mov", FALSE, BYTE, op2(O, A), 0 },
  821. /*a1*/ { "mov", FALSE, LONG, op2(O, A), 0 },
  822. /*a2*/ { "mov", FALSE, BYTE, op2(A, O), 0 },
  823. /*a3*/ { "mov", FALSE, LONG, op2(A, O), 0 },
  824. /*a4*/ { "movs", FALSE, BYTE, op2(SI,DI), 0 },
  825. /*a5*/ { "movs", FALSE, LONG, op2(SI,DI), 0 },
  826. /*a6*/ { "cmps", FALSE, BYTE, op2(SI,DI), 0 },
  827. /*a7*/ { "cmps", FALSE, LONG, op2(SI,DI), 0 },
  828. /*a8*/ { "test", FALSE, BYTE, op2(I, A), 0 },
  829. /*a9*/ { "test", FALSE, LONG, op2(I, A), 0 },
  830. /*aa*/ { "stos", FALSE, BYTE, op1(DI), 0 },
  831. /*ab*/ { "stos", FALSE, LONG, op1(DI), 0 },
  832. /*ac*/ { "lods", FALSE, BYTE, op1(SI), 0 },
  833. /*ad*/ { "lods", FALSE, LONG, op1(SI), 0 },
  834. /*ae*/ { "scas", FALSE, BYTE, op1(DI), 0 },
  835. /*af*/ { "scas", FALSE, LONG, op1(DI), 0 },
  836. /*b0*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  837. /*b1*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  838. /*b2*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  839. /*b3*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  840. /*b4*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  841. /*b5*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  842. /*b6*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  843. /*b7*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
  844. /*b8*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
  845. /*b9*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
  846. /*ba*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
  847. /*bb*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
  848. /*bc*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
  849. /*bd*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
  850. /*be*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
  851. /*bf*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
  852. /*c0*/ { "", TRUE, BYTE, op2(Ib, E), (const char *)db_Grp2 },
  853. /*c1*/ { "", TRUE, LONG, op2(Ib, E), (const char *)db_Grp2 },
  854. /*c2*/ { "ret", FALSE, NONE, op1(Iw), 0 },
  855. /*c3*/ { "ret", FALSE, NONE, 0, 0 },
  856. /*c4*/ { "les", TRUE, LONG, op2(E, R), 0 },
  857. /*c5*/ { "lds", TRUE, LONG, op2(E, R), 0 },
  858. /*c6*/ { "mov", TRUE, BYTE, op2(I, E), 0 },
  859. /*c7*/ { "mov", TRUE, LONG, op2(I, E), 0 },
  860. /*c8*/ { "enter", FALSE, NONE, op2(Iw, Ib), 0 },
  861. /*c9*/ { "leave", FALSE, NONE, 0, 0 },
  862. /*ca*/ { "lret", FALSE, NONE, op1(Iw), 0 },
  863. /*cb*/ { "lret", FALSE, NONE, 0, 0 },
  864. /*cc*/ { "int", FALSE, NONE, op1(o3), 0 },
  865. /*cd*/ { "int", FALSE, NONE, op1(Ib), 0 },
  866. /*ce*/ { "into", FALSE, NONE, 0, 0 },
  867. /*cf*/ { "iret", FALSE, NONE, 0, 0 },
  868. /*d0*/ { "", TRUE, BYTE, op2(o1, E), (const char *)db_Grp2 },
  869. /*d1*/ { "", TRUE, LONG, op2(o1, E), (const char *)db_Grp2 },
  870. /*d2*/ { "", TRUE, BYTE, op2(CL, E), (const char *)db_Grp2 },
  871. /*d3*/ { "", TRUE, LONG, op2(CL, E), (const char *)db_Grp2 },
  872. /*d4*/ { "aam", TRUE, NONE, 0, 0 },
  873. /*d5*/ { "aad", TRUE, NONE, 0, 0 },
  874. /*d6*/ { "", FALSE, NONE, 0, 0 },
  875. /*d7*/ { "xlat", FALSE, BYTE, op1(BX), 0 },
  876. /*d8*/ { "", TRUE, NONE, 0, (const char *)db_Esc8 },
  877. /*d9*/ { "", TRUE, NONE, 0, (const char *)db_Esc9 },
  878. /*da*/ { "", TRUE, NONE, 0, (const char *)db_Esca },
  879. /*db*/ { "", TRUE, NONE, 0, (const char *)db_Escb },
  880. /*dc*/ { "", TRUE, NONE, 0, (const char *)db_Escc },
  881. /*dd*/ { "", TRUE, NONE, 0, (const char *)db_Escd },
  882. /*de*/ { "", TRUE, NONE, 0, (const char *)db_Esce },
  883. /*df*/ { "", TRUE, NONE, 0, (const char *)db_Escf },
  884. /*e0*/ { "loopne",FALSE, NONE, op1(Db), 0 },
  885. /*e1*/ { "loope", FALSE, NONE, op1(Db), 0 },
  886. /*e2*/ { "loop", FALSE, NONE, op1(Db), 0 },
  887. /*e3*/ { "jcxz", FALSE, SDEP, op1(Db), "jecxz" },
  888. /*e4*/ { "in", FALSE, BYTE, op2(Ib, A), 0 },
  889. /*e5*/ { "in", FALSE, LONG, op2(Ib, A) , 0 },
  890. /*e6*/ { "out", FALSE, BYTE, op2(A, Ib), 0 },
  891. /*e7*/ { "out", FALSE, LONG, op2(A, Ib) , 0 },
  892. /*e8*/ { "call", FALSE, NONE, op1(Dl), 0 },
  893. /*e9*/ { "jmp", FALSE, NONE, op1(Dl), 0 },
  894. /*ea*/ { "ljmp", FALSE, NONE, op1(OS), 0 },
  895. /*eb*/ { "jmp", FALSE, NONE, op1(Db), 0 },
  896. /*ec*/ { "in", FALSE, BYTE, op2(DX, A), 0 },
  897. /*ed*/ { "in", FALSE, LONG, op2(DX, A) , 0 },
  898. /*ee*/ { "out", FALSE, BYTE, op2(A, DX), 0 },
  899. /*ef*/ { "out", FALSE, LONG, op2(A, DX) , 0 },
  900. /*f0*/ { "", FALSE, NONE, 0, 0 },
  901. /*f1*/ { "icebp", FALSE, NONE, 0, 0 },
  902. /*f2*/ { "", FALSE, NONE, 0, 0 },
  903. /*f3*/ { "", FALSE, NONE, 0, 0 },
  904. /*f4*/ { "hlt", FALSE, NONE, 0, 0 },
  905. /*f5*/ { "cmc", FALSE, NONE, 0, 0 },
  906. /*f6*/ { "", TRUE, BYTE, 0, (const char *)db_Grp3 },
  907. /*f7*/ { "", TRUE, LONG, 0, (const char *)db_Grp3 },
  908. /*f8*/ { "clc", FALSE, NONE, 0, 0 },
  909. /*f9*/ { "stc", FALSE, NONE, 0, 0 },
  910. /*fa*/ { "cli", FALSE, NONE, 0, 0 },
  911. /*fb*/ { "sti", FALSE, NONE, 0, 0 },
  912. /*fc*/ { "cld", FALSE, NONE, 0, 0 },
  913. /*fd*/ { "std", FALSE, NONE, 0, 0 },
  914. /*fe*/ { "", TRUE, NONE, 0, (const char *)db_Grp4 },
  915. /*ff*/ { "", TRUE, NONE, 0, (const char *)db_Grp5 },
  916. };
  917. static const struct inst db_bad_inst =
  918. { "???", FALSE, NONE, 0, 0 }
  919. ;
  920. #define f_mod(byte) ((byte)>>6)
  921. #define f_reg(byte) (((byte)>>3)&0x7)
  922. #define f_rm(byte) ((byte)&0x7)
  923. #define sib_ss(byte) ((byte)>>6)
  924. #define sib_index(byte) (((byte)>>3)&0x7)
  925. #define sib_base(byte) ((byte)&0x7)
  926. struct i_addr {
  927. int is_reg; /* if reg, reg number is in 'disp' */
  928. int disp;
  929. const char * base;
  930. const char * index;
  931. int ss;
  932. };
  933. static const char * const db_index_reg_16[8] = {
  934. "%bx,%si",
  935. "%bx,%di",
  936. "%bp,%si",
  937. "%bp,%di",
  938. "%si",
  939. "%di",
  940. "%bp",
  941. "%bx"
  942. };
  943. static const char * const db_reg[5][8] = {
  944. /*BYTE*/{ "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh" },
  945. /*WORD*/{ "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di" },
  946. /*LONG*/{ "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi" },
  947. /*QUAD*/{ "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" },
  948. /*DQUA*/{ "%xmm0","%xmm1","%xmm2","%xmm3","%xmm4","%xmm5","%xmm6","%xmm7" }
  949. };
  950. static const char * const db_seg_reg[8] = {
  951. "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", ""
  952. };
  953. /*
  954. * lengths for size attributes
  955. */
  956. static const int db_lengths[] = {
  957. 1, /* BYTE */
  958. 2, /* WORD */
  959. 4, /* LONG */
  960. 8, /* QUAD */
  961. 16, /* DQUA */
  962. 4, /* SNGL */
  963. 8, /* DBLR */
  964. 10, /* EXTR */
  965. };
  966. static unsigned int db_get_task_value( const ADDRESS64* addr,
  967. int size, int is_signed )
  968. {
  969. unsigned int result = 0;
  970. char buffer[4];
  971. if (size != 1 && size != 2 && size != 4)
  972. {
  973. dbg_printf("Illegal size specified\n");
  974. }
  975. else
  976. {
  977. dbg_read_memory(memory_to_linear_addr(addr), buffer, size);
  978. switch (size)
  979. {
  980. case 4:
  981. if (is_signed) result = (unsigned int) *(int *)buffer;
  982. else result = *(unsigned int *)buffer;
  983. break;
  984. case 2:
  985. if (is_signed) result = (unsigned int) *(short int *)buffer;
  986. else result = *(unsigned short int *)buffer;
  987. break;
  988. case 1:
  989. if (is_signed) result = (unsigned int) *(char *)buffer;
  990. else result = *(unsigned char *)buffer;
  991. break;
  992. }
  993. }
  994. return result;
  995. }
  996. #define get_value_inc(result, addr, size, is_signed) \
  997. result = db_get_task_value((addr), (size), (is_signed)); \
  998. if (!db_disasm_16) (addr)->Offset += (size); \
  999. else (addr)->Offset = ((addr)->Offset + (size)) & 0xffff;
  1000. /*
  1001. * Read address at location and return updated location.
  1002. */
  1003. static void db_read_address( ADDRESS64* addr, int short_addr, int regmodrm,
  1004. struct i_addr *addrp )
  1005. {
  1006. int mod, rm, sib, index, disp;
  1007. mod = f_mod(regmodrm);
  1008. rm = f_rm(regmodrm);
  1009. if (mod == 3) {
  1010. addrp->is_reg = TRUE;
  1011. addrp->disp = rm;
  1012. return;
  1013. }
  1014. addrp->is_reg = FALSE;
  1015. addrp->index = 0;
  1016. if (short_addr) {
  1017. addrp->index = 0;
  1018. addrp->ss = 0;
  1019. switch (mod) {
  1020. case 0:
  1021. if (rm == 6) {
  1022. get_value_inc(disp, addr, 2, TRUE);
  1023. addrp->disp = disp;
  1024. addrp->base = 0;
  1025. }
  1026. else {
  1027. addrp->disp = 0;
  1028. addrp->base = db_index_reg_16[rm];
  1029. }
  1030. break;
  1031. case 1:
  1032. get_value_inc(disp, addr, 1, TRUE);
  1033. addrp->disp = disp;
  1034. addrp->base = db_index_reg_16[rm];
  1035. break;
  1036. case 2:
  1037. get_value_inc(disp, addr, 2, TRUE);
  1038. addrp->disp = disp;
  1039. addrp->base = db_index_reg_16[rm];
  1040. break;
  1041. }
  1042. }
  1043. else {
  1044. if (mod != 3 && rm == 4) {
  1045. get_value_inc(sib, addr, 1, FALSE);
  1046. rm = sib_base(sib);
  1047. index = sib_index(sib);
  1048. if (index != 4)
  1049. addrp->index = db_reg[LONG][index];
  1050. addrp->ss = sib_ss(sib);
  1051. }
  1052. switch (mod) {
  1053. case 0:
  1054. if (rm == 5) {
  1055. get_value_inc(addrp->disp, addr, 4, FALSE);
  1056. addrp->base = 0;
  1057. }
  1058. else {
  1059. addrp->disp = 0;
  1060. addrp->base = db_reg[LONG][rm];
  1061. }
  1062. break;
  1063. case 1:
  1064. get_value_inc(disp, addr, 1, TRUE);
  1065. addrp->disp = disp;
  1066. addrp->base = db_reg[LONG][rm];
  1067. break;
  1068. case 2:
  1069. get_value_inc(disp, addr, 4, FALSE);
  1070. addrp->disp = disp;
  1071. addrp->base = db_reg[LONG][rm];
  1072. break;
  1073. }
  1074. }
  1075. }
  1076. static void db_task_printsym(unsigned int addr, int size)
  1077. {
  1078. ADDRESS64 a;
  1079. a.Mode = AddrModeFlat;
  1080. a.Offset = addr;
  1081. print_address(&a, TRUE);
  1082. }
  1083. static void db_print_address(const char *seg, int size, struct i_addr *addrp, int byref)
  1084. {
  1085. if (addrp->is_reg) {
  1086. dbg_printf("%s", db_reg[size][addrp->disp]);
  1087. return;
  1088. }
  1089. if (seg) {
  1090. dbg_printf("%s:", seg);
  1091. }
  1092. if (addrp->base != 0 || addrp->index != 0) {
  1093. dbg_printf("0x%x(", addrp->disp);
  1094. if (addrp->base)
  1095. dbg_printf("%s", addrp->base);
  1096. if (addrp->index)
  1097. dbg_printf(",%s,%d", addrp->index, 1<<addrp->ss);
  1098. dbg_printf(")");
  1099. }
  1100. else {
  1101. /* try to get destination of indirect call
  1102. does not work for segmented addresses */
  1103. if (!seg && byref) {
  1104. void* a1;
  1105. void* a2;
  1106. dbg_printf("0x%x -> ", addrp->disp);
  1107. if (!dbg_read_memory((void*)(INT_PTR)addrp->disp, &a1, sizeof(a1))) {
  1108. dbg_printf("(invalid source)");
  1109. } else if (!dbg_read_memory(a1, &a2, sizeof(a2))) {
  1110. dbg_printf("(invalid destination)");
  1111. } else {
  1112. db_task_printsym((ULONG_PTR)a1, 0);
  1113. }
  1114. }
  1115. else
  1116. db_task_printsym(addrp->disp, size);
  1117. }
  1118. }
  1119. /*
  1120. * Disassemble floating-point ("escape") instruction
  1121. * and return updated location.
  1122. */
  1123. static void db_disasm_esc( ADDRESS64* addr, int inst, int short_addr,
  1124. int size, const char *seg )
  1125. {
  1126. int regmodrm;
  1127. const struct finst *fp;
  1128. int mod;
  1129. struct i_addr address;
  1130. const char * name;
  1131. get_value_inc(regmodrm, addr, 1, FALSE);
  1132. if( !db_display )
  1133. {
  1134. return;
  1135. }
  1136. fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm)];
  1137. mod = f_mod(regmodrm);
  1138. if (mod != 3) {
  1139. const char* p;
  1140. /*
  1141. * Normal address modes.
  1142. */
  1143. db_read_address( addr, short_addr, regmodrm, &address);
  1144. dbg_printf("%s", fp->f_name);
  1145. switch(fp->f_size) {
  1146. case SNGL: p = "s"; break;
  1147. case DBLR: p = "l"; break;
  1148. case EXTR: p = "t"; break;
  1149. case WORD: p = "s"; break;
  1150. case LONG: p = "l"; break;
  1151. case QUAD: p = "q"; break;
  1152. default: p = ""; break;
  1153. }
  1154. dbg_printf("%s\t", p);
  1155. db_print_address(seg, BYTE, &address, 0);
  1156. }
  1157. else {
  1158. /*
  1159. * 'reg-reg' - special formats
  1160. */
  1161. switch (fp->f_rrmode) {
  1162. case op2(ST,STI):
  1163. name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
  1164. dbg_printf("%s\t%%st,%%st(%d)",name,f_rm(regmodrm));
  1165. break;
  1166. case op2(STI,ST):
  1167. name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
  1168. dbg_printf("%s\t%%st(%d),%%st",name, f_rm(regmodrm));
  1169. break;
  1170. case op1(STI):
  1171. name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
  1172. dbg_printf("%s\t%%st(%d)",name, f_rm(regmodrm));
  1173. break;
  1174. case op1(X):
  1175. dbg_printf("%s", ((char * const*)fp->f_rrname)[f_rm(regmodrm)]);
  1176. break;
  1177. case op1(XA):
  1178. dbg_printf("%s\t%%ax", ((char * const*)fp->f_rrname)[f_rm(regmodrm)]);
  1179. break;
  1180. default:
  1181. dbg_printf("<bad instruction>");
  1182. break;
  1183. }
  1184. }
  1185. }
  1186. /***********************************************************************
  1187. * disasm_one_insn
  1188. *
  1189. * Disassemble instruction at 'addr'. addr is changed to point to the
  1190. * start of the next instruction.
  1191. */
  1192. void be_i386_disasm_one_insn(ADDRESS64 *addr, int display)
  1193. {
  1194. int inst;
  1195. int size;
  1196. int short_addr;
  1197. const char *seg;
  1198. const struct inst *ip;
  1199. const char *i_name;
  1200. int i_size;
  1201. int i_mode;
  1202. int regmodrm = 0;
  1203. BOOL first;
  1204. int displ;
  1205. int prefix;
  1206. int imm;
  1207. int len;
  1208. struct i_addr address;
  1209. /*
  1210. * Set this so we can suppress the printout if we need to.
  1211. */
  1212. db_display = display;
  1213. switch (addr->Mode)
  1214. {
  1215. case AddrModeReal:
  1216. case AddrMode1616: db_disasm_16 = 1; break;
  1217. default: db_disasm_16 = 0; break;
  1218. }
  1219. get_value_inc( inst, addr, 1, FALSE );
  1220. if (db_disasm_16) {
  1221. short_addr = TRUE;
  1222. size = WORD;
  1223. }
  1224. else {
  1225. short_addr = FALSE;
  1226. size = LONG;
  1227. }
  1228. seg = 0;
  1229. /*
  1230. * Get prefixes
  1231. */
  1232. prefix = TRUE;
  1233. do {
  1234. switch (inst) {
  1235. case 0x66: /* data16 */
  1236. if (size == LONG)
  1237. size = WORD;
  1238. else
  1239. size = LONG;
  1240. break;
  1241. case 0x67:
  1242. short_addr = !short_addr;
  1243. break;
  1244. case 0x26:
  1245. seg = "%es";
  1246. break;
  1247. case 0x36:
  1248. seg = "%ss";
  1249. break;
  1250. case 0x2e:
  1251. seg = "%cs";
  1252. break;
  1253. case 0x3e:
  1254. seg = "%ds";
  1255. break;
  1256. case 0x64:
  1257. seg = "%fs";
  1258. break;
  1259. case 0x65:
  1260. seg = "%gs";
  1261. break;
  1262. case 0xf0:
  1263. if( db_display )
  1264. dbg_printf("lock ");
  1265. break;
  1266. case 0xf2:
  1267. if( db_display )
  1268. dbg_printf("repne ");
  1269. break;
  1270. case 0xf3:
  1271. if( db_display )
  1272. dbg_printf("repe "); /* XXX repe VS rep */
  1273. break;
  1274. default:
  1275. prefix = FALSE;
  1276. break;
  1277. }
  1278. if (prefix) {
  1279. get_value_inc(inst, addr, 1, FALSE);
  1280. }
  1281. } while (prefix);
  1282. if (inst >= 0xd8 && inst <= 0xdf)
  1283. {
  1284. db_disasm_esc( addr, inst, short_addr, size, seg);
  1285. return;
  1286. }
  1287. if (inst == 0x0f) {
  1288. get_value_inc(inst, addr, 1, FALSE);
  1289. ip = db_inst_0f[inst>>4];
  1290. if (ip == 0) {
  1291. ip = &db_bad_inst;
  1292. }
  1293. else {
  1294. ip = &ip[inst&0xf];
  1295. }
  1296. }
  1297. else
  1298. ip = &db_inst_table[inst];
  1299. if (ip->i_has_modrm) {
  1300. get_value_inc(regmodrm, addr, 1, FALSE);
  1301. db_read_address( addr, short_addr, regmodrm, &address);
  1302. }
  1303. i_name = ip->i_name;
  1304. i_size = ip->i_size;
  1305. i_mode = ip->i_mode;
  1306. if (ip->i_extra == (const char *)db_Grp1 ||
  1307. ip->i_extra == (const char *)db_Grp2 ||
  1308. ip->i_extra == (const char *)db_Grp6 ||
  1309. ip->i_extra == (const char *)db_Grp7 ||
  1310. ip->i_extra == (const char *)db_Grp8 ||
  1311. ip->i_extra == (const char *)db_Grp10 ||
  1312. ip->i_extra == (const char *)db_Grp11 ||
  1313. ip->i_extra == (const char *)db_Grp12) {
  1314. i_name = ((const char * const*)ip->i_extra)[f_reg(regmodrm)];
  1315. }
  1316. else if (ip->i_extra == (const char *)db_Grp3) {
  1317. ip = (const struct inst *)ip->i_extra;
  1318. ip = &ip[f_reg(regmodrm)];
  1319. i_name = ip->i_name;
  1320. i_mode = ip->i_mode;
  1321. }
  1322. else if (ip->i_extra == (const char *)db_Grp4 ||
  1323. ip->i_extra == (const char *)db_Grp5) {
  1324. ip = (const struct inst *)ip->i_extra;
  1325. ip = &ip[f_reg(regmodrm)];
  1326. i_name = ip->i_name;
  1327. i_mode = ip->i_mode;
  1328. i_size = ip->i_size;
  1329. }
  1330. if (i_size == SDEP) {
  1331. if( db_display )
  1332. {
  1333. if (size == WORD)
  1334. dbg_printf("%s", i_name);
  1335. else
  1336. dbg_printf("%s", ip->i_extra);
  1337. }
  1338. }
  1339. else {
  1340. if( db_display )
  1341. {
  1342. dbg_printf("%s", i_name);
  1343. }
  1344. if (i_size != NONE) {
  1345. if (i_size == BYTE) {
  1346. if( db_display )
  1347. {
  1348. dbg_printf("b");
  1349. }
  1350. size = BYTE;
  1351. }
  1352. else if (i_size == WORD) {
  1353. if( db_display )
  1354. {
  1355. dbg_printf("w");
  1356. }
  1357. size = WORD;
  1358. }
  1359. else if (size == WORD)
  1360. {
  1361. if( db_display )
  1362. {
  1363. dbg_printf("w");
  1364. }
  1365. }
  1366. else
  1367. {
  1368. if( db_display )
  1369. {
  1370. dbg_printf("l");
  1371. }
  1372. }
  1373. }
  1374. }
  1375. if( db_display )
  1376. {
  1377. dbg_printf("\t");
  1378. }
  1379. for (first = TRUE;
  1380. i_mode != 0;
  1381. i_mode >>= 8, first = FALSE)
  1382. {
  1383. if (!first && db_display)
  1384. dbg_printf(",");
  1385. switch (i_mode & 0xFF) {
  1386. case E:
  1387. if( db_display )
  1388. {
  1389. db_print_address(seg, size, &address, 0);
  1390. }
  1391. break;
  1392. case Eind:
  1393. if( db_display )
  1394. {
  1395. dbg_printf("*");
  1396. db_print_address(seg, size, &address, 1);
  1397. }
  1398. break;
  1399. case Ew:
  1400. if( db_display )
  1401. {
  1402. db_print_address(seg, WORD, &address, 0);
  1403. }
  1404. break;
  1405. case Eb:
  1406. if( db_display )
  1407. {
  1408. db_print_address(seg, BYTE, &address, 0);
  1409. }
  1410. break;
  1411. case R:
  1412. if( db_display )
  1413. {
  1414. dbg_printf("%s", db_reg[size][f_reg(regmodrm)]);
  1415. }
  1416. break;
  1417. case MX:
  1418. if( db_display )
  1419. {
  1420. dbg_printf("%%mm%d", f_reg(regmodrm));
  1421. }
  1422. break;
  1423. case EMX:
  1424. if( db_display )
  1425. {
  1426. db_print_address(seg, QUAD, &address, 0);
  1427. }
  1428. break;
  1429. case XMM:
  1430. if( db_display )
  1431. {
  1432. dbg_printf("%%xmm%d", f_reg(regmodrm));
  1433. }
  1434. break;
  1435. case EXMM:
  1436. if( db_display )
  1437. {
  1438. db_print_address(seg, DQUA, &address, 0);
  1439. }
  1440. break;
  1441. case Rw:
  1442. if( db_display )
  1443. {
  1444. dbg_printf("%s", db_reg[WORD][f_reg(regmodrm)]);
  1445. }
  1446. break;
  1447. case Ri:
  1448. if( db_display )
  1449. {
  1450. dbg_printf("%s", db_reg[size][f_rm(inst)]);
  1451. }
  1452. break;
  1453. case S:
  1454. if( db_display )
  1455. {
  1456. dbg_printf("%s", db_seg_reg[f_reg(regmodrm)]);
  1457. }
  1458. break;
  1459. case Si:
  1460. if( db_display )
  1461. {
  1462. dbg_printf("%s", db_seg_reg[f_reg(inst)]);
  1463. }
  1464. break;
  1465. case A:
  1466. if( db_display )
  1467. {
  1468. dbg_printf("%s", db_reg[size][0]); /* acc */
  1469. }
  1470. break;
  1471. case BX:
  1472. if( db_display )
  1473. {
  1474. if (seg)
  1475. dbg_printf("%s:", seg);
  1476. dbg_printf("(%s)", short_addr ? "%bx" : "%ebx");
  1477. }
  1478. break;
  1479. case CL:
  1480. if( db_display )
  1481. {
  1482. dbg_printf("%%cl");
  1483. }
  1484. break;
  1485. case DX:
  1486. if( db_display )
  1487. {
  1488. dbg_printf("%%dx");
  1489. }
  1490. break;
  1491. case SI:
  1492. if( db_display )
  1493. {
  1494. if (seg)
  1495. dbg_printf("%s:", seg);
  1496. dbg_printf("(%s)", short_addr ? "%si" : "%esi");
  1497. }
  1498. break;
  1499. case DI:
  1500. if( db_display )
  1501. {
  1502. dbg_printf("%%es:(%s)", short_addr ? "%di" : "%edi");
  1503. }
  1504. break;
  1505. case CR:
  1506. if( db_display )
  1507. {
  1508. dbg_printf("%%cr%d", f_reg(regmodrm));
  1509. }
  1510. break;
  1511. case DR:
  1512. if( db_display )
  1513. {
  1514. dbg_printf("%%dr%d", f_reg(regmodrm));
  1515. }
  1516. break;
  1517. case TR:
  1518. if( db_display )
  1519. {
  1520. dbg_printf("%%tr%d", f_reg(regmodrm));
  1521. }
  1522. break;
  1523. case I:
  1524. len = db_lengths[size];
  1525. get_value_inc(imm, addr, len, FALSE);/* unsigned */
  1526. if( db_display )
  1527. {
  1528. dbg_printf("$0x%x", imm);
  1529. }
  1530. break;
  1531. case Is:
  1532. len = db_lengths[size];
  1533. get_value_inc(imm, addr, len, TRUE); /* signed */
  1534. if( db_display )
  1535. {
  1536. dbg_printf("$%d", imm);
  1537. }
  1538. break;
  1539. case Ib:
  1540. get_value_inc(imm, addr, 1, FALSE); /* unsigned */
  1541. if( db_display )
  1542. {
  1543. dbg_printf("$0x%x", imm);
  1544. }
  1545. break;
  1546. case Ibs:
  1547. get_value_inc(imm, addr, 1, TRUE); /* signed */
  1548. if( db_display )
  1549. {
  1550. dbg_printf("$%d", imm);
  1551. }
  1552. break;
  1553. case Iw:
  1554. get_value_inc(imm, addr, 2, FALSE); /* unsigned */
  1555. if( db_display )
  1556. {
  1557. dbg_printf("$0x%x", imm);
  1558. }
  1559. break;
  1560. case Il:
  1561. get_value_inc(imm, addr, 4, FALSE);
  1562. if( db_display )
  1563. {
  1564. dbg_printf("$0x%x", imm);
  1565. }
  1566. break;
  1567. case O:
  1568. if (short_addr) {
  1569. get_value_inc(displ, addr, 2, TRUE);
  1570. }
  1571. else {
  1572. get_value_inc(displ, addr, 4, TRUE);
  1573. }
  1574. if( !db_display )
  1575. {
  1576. break;
  1577. }
  1578. if (seg)
  1579. dbg_printf("%s:0x%x",seg, displ);
  1580. else
  1581. db_task_printsym(displ, short_addr ? WORD : LONG);
  1582. break;
  1583. case Db:
  1584. get_value_inc(displ, addr, 1, TRUE);
  1585. if( !db_display )
  1586. {
  1587. break;
  1588. }
  1589. if (size == WORD) {
  1590. /* offset only affects low 16 bits */
  1591. displ = (addr->Offset & 0xffff0000)
  1592. | ((addr->Offset + displ) & 0xffff);
  1593. }
  1594. else displ += addr->Offset;
  1595. db_task_printsym(displ, size);
  1596. break;
  1597. case Dl:
  1598. if (size == WORD) {
  1599. get_value_inc(displ, addr, 2, TRUE);
  1600. /* Offset only affects low 16 bits */
  1601. displ = (addr->Offset & 0xffff0000)
  1602. | ((addr->Offset + displ) & 0xffff);
  1603. }
  1604. else {
  1605. get_value_inc(displ, addr, 4, TRUE);
  1606. displ += addr->Offset;
  1607. }
  1608. if( !db_display )
  1609. {
  1610. break;
  1611. }
  1612. db_task_printsym( displ, size );
  1613. break;
  1614. case o1:
  1615. if( db_display )
  1616. {
  1617. dbg_printf("$1");
  1618. }
  1619. break;
  1620. case o3:
  1621. if( db_display )
  1622. {
  1623. dbg_printf("$3");
  1624. }
  1625. break;
  1626. case OS:
  1627. {
  1628. ADDRESS64 address;
  1629. get_value_inc( address.Offset, addr, /* offset */
  1630. short_addr ? 2 : 4, FALSE );
  1631. get_value_inc( address.Segment, addr, /* segment */
  1632. 2, FALSE );
  1633. dbg_curr_process->be_cpu->build_addr(dbg_curr_thread->handle,
  1634. &dbg_context, &address, address.Segment, address.Offset);
  1635. if( db_display )
  1636. {
  1637. print_address( &address, TRUE );
  1638. }
  1639. }
  1640. break;
  1641. }
  1642. }
  1643. }
  1644. #endif /* __i386__ */