1
0

x86dis.c 88 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. x86dis.c
  5. Abstract:
  6. This module contains routines for disassembling x86 binary code.
  7. Author:
  8. Evan Green 21-Jun-2012
  9. Environment:
  10. Debugging client
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/lib/types.h>
  16. #include "disasm.h"
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <assert.h>
  20. //
  21. // ---------------------------------------------------------------- Definitions
  22. //
  23. //
  24. // Define the meanings of some of size characters used in the encoding table.
  25. //
  26. #define X86_WIDTH_BYTE 'b'
  27. #define X86_WIDTH_WORD 'w'
  28. #define X86_WIDTH_LONG 'l'
  29. #define X86_WIDTH_LONGLONG 'q'
  30. #define X86_FLOATING_POINT_REGISTER 'f'
  31. //
  32. // Define the internal bitfields of the ModR/M and SIB byte.
  33. //
  34. #define X86_MOD_MASK 0xC0
  35. #define X86_REG_MASK 0x38
  36. #define X86_RM_MASK 0x07
  37. #define X86_MOD_SHIFT 6
  38. #define X86_REG_SHIFT 3
  39. #define X86_RM_SHIFT 0
  40. #define X86_SCALE_MASK 0xC0
  41. #define X86_INDEX_MASK 0x38
  42. #define X86_BASE_MASK 0x07
  43. #define X86_SCALE_SHIFT 6
  44. #define X86_INDEX_SHIFT 3
  45. #define X86_BASE_SHIFT 0
  46. //
  47. // Define some of the prefixes that can come at the beginning of an instruction.
  48. //
  49. #define X86_MAX_PREFIXES 4
  50. #define X86_OPERAND_OVERRIDE 0x66
  51. #define X86_ADDRESS_OVERRIDE 0x67
  52. #define X86_ESCAPE_OPCODE 0x0F
  53. #define X86_PREFIX_LOCK 0xF0
  54. #define X86_PREFIX_REP1 0xF2
  55. #define X86_PREFIX_REP2 0xF3
  56. #define X86_PREFIX_CS 0x2E
  57. #define X86_PREFIX_DS 0x3E
  58. #define X86_PREFIX_ES 0x26
  59. #define X86_PREFIX_SS 0x36
  60. //
  61. // This mask/value combination covers the FS prefix, GS prefix, Operand
  62. // override, and Address override.
  63. //
  64. #define X86_PREFIX_FS_GS_OVERRIDE_MASK 0xFC
  65. #define X86_PREFIX_FS_GS_OVERRIDE_VALUE 0x64
  66. //
  67. // For opcode groups with fewer than the maximum number of possible opcodes,
  68. // define how many opcodes each group does have.
  69. //
  70. #define X86_GROUP_4_INSTRUCTION_COUNT 2
  71. #define X86_GROUP_5_INSTRUCTION_COUNT 7
  72. #define X86_GROUP_6_INSTRUCTION_COUNT 6
  73. #define X86_GROUP_8_FIRST_INSTRUCTION 4
  74. #define X86_GROUP_9_ONLY_VALID_INSTRUCTION 1
  75. #define X86_INVALID_GROUP 99
  76. //
  77. // Define the sizes of the register name arrays.
  78. //
  79. #define X86_DEBUG_REGISTER_COUNT 8
  80. #define X86_SEGMENT_REGISTER_COUNT 6
  81. #define X86_REGISTER_NAME_COUNT 8
  82. //
  83. // Define the size of the working buffers.
  84. //
  85. #define X86_WORKING_BUFFER_SIZE 100
  86. //
  87. // Define the multiplication and shift opcodes that have 3 operands.
  88. //
  89. #define X86_OPCODE1_IMUL1 0x69
  90. #define X86_OPCODE1_IMUL2 0x6B
  91. #define X86_OPCODE2_SHLD1 0xA4
  92. #define X86_OPCODE2_SHLD2 0xA5
  93. #define X86_OPCODE2_SHRD1 0xAC
  94. #define X86_OPCODE2_SHRD2 0xAD
  95. //
  96. // Define some x87 floating point support definitions, constants used in
  97. // decoding an x87 coprocessor instruction.
  98. //
  99. #define X87_ESCAPE_OFFSET 0xD8
  100. #define X87_FCOM_MASK 0xF8
  101. #define X87_FCOM_OPCODE 0xD0
  102. #define X87_D9_E0_OFFSET 0xE0
  103. #define X87_DA_C0_MASK 0x38
  104. #define X87_DA_CO_SHIFT 3
  105. #define X87_FUCOMPP_OPCODE 0xE9
  106. #define X87_DB_C0_MASK 0x38
  107. #define X87_DB_C0_SHIFT 3
  108. #define X87_DB_E0_INDEX 4
  109. #define X87_DB_E0_MASK 0x7
  110. #define X87_DF_C0_MASK 0x38
  111. #define X87_DF_C0_SHIFT 3
  112. #define X87_DF_E0_INDEX 4
  113. #define X87_DF_E0_MASK 0x07
  114. #define X87_DF_E0_COUNT 3
  115. #define X87_REGISTER_TARGET "Rf"
  116. #define X87_ST0_TARGET "! st"
  117. #define X87_FLD_MNEMONIC "fld"
  118. #define X87_FXCH_MNEMONIC "fxch"
  119. #define X87_NOP_MNEMONIC "fnop"
  120. #define X87_FSTP1_MNEMONIC "fstp1"
  121. #define X87_FUCOMPP_MNEMONIC "fucompp"
  122. #define X87_DF_E0_TARGET "! ax"
  123. //
  124. // ------------------------------------------------------ Data Type Definitions
  125. //
  126. /*++
  127. Structure Description:
  128. This structure provides basic information about an instruction, including
  129. its mnemonic name, operand encodings, and additional parsing information.
  130. Members:
  131. Mnemonic - Stores a pointer to the string containing the opcode's mnemonic.
  132. Target - Stores a pointer to a string describing the destination operand's
  133. encoding.
  134. Source - Stores a pointer to a string describing the source operand's
  135. encoding.
  136. Group - Stores the opcode group number. Some instructions require furthur
  137. decoding, the group number indicates that.
  138. --*/
  139. typedef struct _X86_INSTRUCTION_DEFINITION {
  140. PSTR Mnemonic;
  141. PSTR Target;
  142. PSTR Source;
  143. INT Group;
  144. } X86_INSTRUCTION_DEFINITION, *PX86_INSTRUCTION_DEFINITION;
  145. /*++
  146. Structure Description:
  147. This structure stores information about an instructions mnemonics and
  148. encoding when an array index is wasteful for describing the actual opcode
  149. number.
  150. Members:
  151. Prefix - Stores the specfic prefix value for which this instruction is
  152. valid.
  153. Opcode - Stores the opcode this definition defines.
  154. Instruction - Stores an array describing the mnemonics and encoding of the
  155. instruction.
  156. --*/
  157. typedef struct _X86_SPARSE_INSTRUCTION_DEFINITION {
  158. BYTE Prefix;
  159. BYTE Opcode;
  160. X86_INSTRUCTION_DEFINITION Instruction;
  161. } X86_SPARSE_INSTRUCTION_DEFINITION, *PX86_SPARSE_INSTRUCTION_DEFINITION;
  162. /*++
  163. Structure Description:
  164. This structure stores all binary information about a decoded instruction.
  165. Members:
  166. Prefix - Stores up to 4 prefix bytes, which is the maximum number of
  167. allowed prefixes in x86 instructions.
  168. Opcode - Stores the first (and many times only) opcode byte.
  169. Opcode2 - Stores the second opcode byte, if necessary (as determined by the
  170. first opcode byte).
  171. ModRm - Stores the ModR/M byte of the instruction, if one exists. Bits 6-7
  172. describe the Mod part of the instruction, which can describe what sort
  173. of addressing/displacement is encoded in the instruction. Bits 5-3 hold
  174. the Reg data, which stores either a register number or additional
  175. decoding information for instruction groups. Bits 2-0 store the R/M
  176. byte, which either stores another register value or describes how the
  177. memory information is encoded.
  178. Sib - Stores the Scale/Index/Base byte of the opcode, if one exists.
  179. Addressing with an sib byte usually looks like (Base + index * 2^Scale),
  180. where Base and Index are both general registers. Bits 6-7 describe the
  181. scale, which is raised to the power of two (and can therefore describe a
  182. scale of 1, 2, 4, or 8). Bits 5-3 describe the index register, and bits
  183. 2-0 describe the base register, both of which are encoded like the Reg
  184. field for general registers.
  185. Displacement - Stores the displacement of the instruction operand.
  186. Immediate - Stores the immediate value that may or may not be encoded in the
  187. instruction.
  188. Length - Stores the total size of this instruction encoding in bytes.
  189. DisplacementSize - Stores the size in bytes of the displacement value. Once
  190. the Displacement field is populated, this field is not too useful.
  191. ImmediateSize - Stores the size in bytes of the immediate value. Once the
  192. Immediate field is populated, this field is not too useful.
  193. OperandOverride - Stores a flag indicating whether or not the operand
  194. override prefix was on this instruction.
  195. AddressOverrride - Stores a flag indicating whether or not the address
  196. override prefix was specified on this instruction.
  197. Definition - Stores a the instruction decoding information,
  198. including the instruction mnemonic.
  199. --*/
  200. typedef struct _X86_INSTRUCTION {
  201. BYTE Prefix[X86_MAX_PREFIXES];
  202. BYTE Opcode;
  203. BYTE Opcode2;
  204. BYTE ModRm;
  205. BYTE Sib;
  206. ULONG Displacement;
  207. ULONG Immediate;
  208. ULONG Length;
  209. ULONG DisplacementSize;
  210. ULONG ImmediateSize;
  211. BOOL OperandOverride;
  212. BOOL AddressOverride;
  213. X86_INSTRUCTION_DEFINITION Definition;
  214. } X86_INSTRUCTION, *PX86_INSTRUCTION;
  215. typedef enum _X86_REGISTER_VALUE {
  216. X86RegisterValueEax,
  217. X86RegisterValueEcx,
  218. X86RegisterValueEdx,
  219. X86RegisterValueEbx,
  220. X86RegisterValueEsp,
  221. X86RegisterValueEbp,
  222. X86RegisterValueEsi,
  223. X86RegisterValueEdi,
  224. X86RegisterValueScaleIndexBase,
  225. X86RegisterValueDisplacement32,
  226. } X86_REGISTER_VALUE, *PX86_REGISTER_VALUE;
  227. typedef enum _X86_MOD_VALUE {
  228. X86ModValueNoDisplacement,
  229. X86ModValueDisplacement8,
  230. X86ModValueDisplacement32,
  231. X86ModValueRegister
  232. } X86_MOD_VALUE, *PX86_MOD_VALUE;
  233. //
  234. // -------------------------------------------------------------------- Globals
  235. //
  236. //
  237. // Define working buffers. Note that this makes the disassembly code not thread
  238. // safe.
  239. //
  240. CHAR DbgX86DisassemblyBuffer[X86_WORKING_BUFFER_SIZE];
  241. CHAR DbgX86OperandBuffer[X86_WORKING_BUFFER_SIZE];
  242. //
  243. // Define the x86 instruction encodings.
  244. //
  245. X86_INSTRUCTION_DEFINITION DbgX86Instructions[256] = {
  246. {"add", "Eb", "Gb", 0}, /* 00 */
  247. {"add", "Ev", "Gv", 0}, /* 01 */
  248. {"add", "Gb", "Eb", 0}, /* 02 */
  249. {"add", "Gv", "Ev", 0}, /* 03 */
  250. {"add", "!bal", "Ib", 0}, /* 04 */
  251. {"add", "!rax", "Iz", 0}, /* 05 */
  252. {"push", "!wes", "", 0}, /* 06 */
  253. {"pop", "!wes", "", 0}, /* 07 */
  254. {"or", "Eb", "Gb", 0}, /* 08 */
  255. {"or", "Ev", "Gv", 0}, /* 09 */
  256. {"or", "Gb", "Eb", 0}, /* 0A */
  257. {"or", "Gv", "Ev", 0}, /* 0B */
  258. {"or", "!bal", "Ib", 0}, /* 0C */
  259. {"or", "!rax", "Iz", 0}, /* 0D */
  260. {"push", "!wcs", "", 0}, /* 0E */
  261. {"2BYTE", "", "", X86_INVALID_GROUP}, /* 0F */ /* Two Byte Opcodes */
  262. {"adc", "Eb", "Gb", 0}, /* 10 */
  263. {"adc", "Ev", "Gv", 0}, /* 11 */
  264. {"adc", "Gb", "Eb", 0}, /* 12 */
  265. {"adc", "Gv", "Ev", 0}, /* 13 */
  266. {"adc", "!bal", "Ib", 0}, /* 14 */
  267. {"adc", "!rax", "Iz", 0}, /* 15 */
  268. {"push", "!wss", "", 0}, /* 16 */
  269. {"pop", "!wss", "", 0}, /* 17 */
  270. {"sbb", "Eb", "Gb", 0}, /* 18 */
  271. {"sbb", "Ev", "Gv", 0}, /* 19 */
  272. {"sbb", "Gb", "Eb", 0}, /* 1A */
  273. {"sbb", "Gv", "Ev", 0}, /* 1B */
  274. {"sbb", "!bal", "Ib", 0}, /* 1C */
  275. {"sbb", "!rax", "Iz", 0}, /* 1D */
  276. {"push", "!wds", "", 0}, /* 1E */
  277. {"pop", "!wds", "", 0}, /* 1F */
  278. {"and", "Eb", "Gb", 0}, /* 20 */
  279. {"and", "Ev", "Gv", 0}, /* 21 */
  280. {"and", "Gb", "Eb", 0}, /* 22 */
  281. {"and", "Gv", "Ev", 0}, /* 23 */
  282. {"and", "!bal", "Ib", 0}, /* 24 */
  283. {"and", "!rax", "Iz", 0}, /* 25 */
  284. {"ES:", "", "", X86_INVALID_GROUP}, /* 26 */ /* ES prefix */
  285. {"daa", "", "", 0}, /* 27 */
  286. {"sub", "Eb", "Gb", 0}, /* 28 */
  287. {"sub", "Ev", "Gv", 0}, /* 29 */
  288. {"sub", "Gb", "Eb", 0}, /* 2A */
  289. {"sub", "Gv", "Ev", 0}, /* 2B */
  290. {"sub", "!bal", "Ib", 0}, /* 2C */
  291. {"sub", "!rax", "Iz", 0}, /* 2D */
  292. {"CS:", "", "", X86_INVALID_GROUP}, /* 2E */ /* CS prefix */
  293. {"das", "", "", 0}, /* 2F */
  294. {"xor", "Eb", "Gb", 0}, /* 30 */
  295. {"xor", "Ev", "Gv", 0}, /* 31 */
  296. {"xor", "Gb", "Eb", 0}, /* 32 */
  297. {"xor", "Gv", "Ev", 0}, /* 33 */
  298. {"xor", "!bal", "Ib", 0}, /* 34 */
  299. {"xor", "!rax", "Iz", 0}, /* 35 */
  300. {"SS:", "", "", X86_INVALID_GROUP}, /* 36 */ /* SS prefix */
  301. {"aaa", "", "", 0}, /* 37 */
  302. {"cmp", "Eb", "Gb", 0}, /* 38 */
  303. {"cmp", "Ev", "Gv", 0}, /* 39 */
  304. {"cmp", "Gb", "Eb", 0}, /* 3A */
  305. {"cmp", "Gv", "Ev", 0}, /* 3B */
  306. {"cmp", "!bal", "Ib", 0}, /* 3C */
  307. {"cmp", "!rax", "Iz", 0}, /* 3D */
  308. {"DS:", "", "", X86_INVALID_GROUP}, /* 3E */ /* DS prefix */
  309. {"aas", "", "", 0}, /* 3F */
  310. {"inc", "!eax", "", 0}, /* 40 */
  311. {"inc", "!ecx", "", 0}, /* 41 */
  312. {"inc", "!edx", "", 0}, /* 42 */
  313. {"inc", "!ebx", "", 0}, /* 43 */
  314. {"inc", "!esp", "", 0}, /* 44 */
  315. {"inc", "!ebp", "", 0}, /* 45 */
  316. {"inc", "!esi", "", 0}, /* 46 */
  317. {"inc", "!edi", "", 0}, /* 47 */
  318. {"dec", "!eax", "", 0}, /* 48 */
  319. {"dec", "!ecx", "", 0}, /* 49 */
  320. {"dec", "!edx", "", 0}, /* 4A */
  321. {"dec", "!ebx", "", 0}, /* 4B */
  322. {"dec", "!esp", "", 0}, /* 4C */
  323. {"dec", "!ebp", "", 0}, /* 4D */
  324. {"dec", "!esi", "", 0}, /* 4E */
  325. {"dec", "!edi", "", 0}, /* 4F */
  326. {"push", "!rax", "", 0}, /* 50 */
  327. {"push", "!rcx", "", 0}, /* 51 */
  328. {"push", "!rdx", "", 0}, /* 52 */
  329. {"push", "!rbx", "", 0}, /* 53 */
  330. {"push", "!rsp", "", 0}, /* 54 */
  331. {"push", "!rbp", "", 0}, /* 55 */
  332. {"push", "!rsi", "", 0}, /* 56 */
  333. {"push", "!rdi", "", 0}, /* 57 */
  334. {"pop", "!rax", "", 0}, /* 58 */
  335. {"pop", "!rcx", "", 0}, /* 59 */
  336. {"pop", "!rdx", "", 0}, /* 5A */
  337. {"pop", "!rbx", "", 0}, /* 5B */
  338. {"pop", "!rsp", "", 0}, /* 5C */
  339. {"pop", "!rbp", "", 0}, /* 5D */
  340. {"pop", "!rsi", "", 0}, /* 5E */
  341. {"pop", "!rdi", "", 0}, /* 5F */
  342. {"pushad", "", "", 0}, /* 60 */
  343. {"popad", "", "", 0}, /* 61 */
  344. {"bound", "Gv", "Ma", 0}, /* 62 */
  345. {"arpl", "Ew", "Gw", 0}, /* 63 */
  346. {"FS:", "", "", X86_INVALID_GROUP}, /* 64 */ /* FS prefix */
  347. {"GS:", "", "", X86_INVALID_GROUP}, /* 65 */ /* GS prefix */
  348. {"OPSIZE:", "", "", X86_INVALID_GROUP}, /* 66 */ /* Operand override */
  349. {"ADSIZE:", "", "", X86_INVALID_GROUP}, /* 67 */ /* Address override */
  350. {"push", "Iz", "", 0}, /* 68 */
  351. {"imul", "Gv", "Ev", 0}, /* 69 */ /* Also has Iz */
  352. {"push", "Ib", "", 0}, /* 6A */
  353. {"imul", "Gv", "Ev", 0}, /* 6B */ /* Also has Ib */
  354. {"ins", "Yb", "!wdx", 0}, /* 6C */
  355. {"ins", "Yz", "!wdx", 0}, /* 6D */
  356. {"outs", "!wdx", "Xb", 0}, /* 6E */
  357. {"outs", "!wdx", "Xz", 0}, /* 6F */
  358. {"jo ", "Jb", "", 0}, /* 70 */
  359. {"jno", "Jb", "", 0}, /* 71 */
  360. {"jb ", "Jb", "", 0}, /* 72 */
  361. {"jnb", "Jb", "", 0}, /* 73 */
  362. {"jz ", "Jb", "", 0}, /* 74 */
  363. {"jnz", "Jb", "", 0}, /* 75 */
  364. {"jbe", "Jb", "", 0}, /* 76 */
  365. {"jnbe", "Jb", "", 0}, /* 77 */
  366. {"js ", "Jb", "", 0}, /* 78 */
  367. {"jns", "Jb", "", 0}, /* 79 */
  368. {"jp ", "Jb", "", 0}, /* 7A */
  369. {"jnp", "Jb", "", 0}, /* 7B */
  370. {"jl ", "Jb", "", 0}, /* 7C */
  371. {"jnl", "Jb", "", 0}, /* 7D */
  372. {"jle", "Jb", "", 0}, /* 7E */
  373. {"jnle", "Jb", "", 0}, /* 7F */
  374. {"GRP1", "Eb", "Ib", 1}, /* 80 */ /* Group 1 opcodes. */
  375. {"GRP1", "Ev", "Iz", 1}, /* 81 */ /* Reg of ModR/M */
  376. {"GRP1", "Eb", "Ib", 1}, /* 82 */ /* extends opcode.*/
  377. {"GRP1", "Ev", "Ib", 1}, /* 83 */
  378. {"test", "Eb", "Gb", 0}, /* 84 */
  379. {"test", "Ev", "Gv", 0}, /* 85 */
  380. {"xchg", "Eb", "Eb", 0}, /* 86 */
  381. {"xchg", "Ev", "Gv", 0}, /* 87 */
  382. {"mov", "Eb", "Gb", 0}, /* 88 */
  383. {"mov", "Ev", "Gv", 0}, /* 89 */
  384. {"mov", "Gb", "Eb", 0}, /* 8A */
  385. {"mov", "Gv", "Ev", 0}, /* 8B */
  386. {"mov", "Ev", "Sw", 0}, /* 8C */
  387. {"lea", "Gv", "Ml", 0}, /* 8D */
  388. {"mov", "Sw", "Ev", 0}, /* 8E */
  389. {"pop", "Ev", "", 10}, /* 8F */ /* Group 10 */
  390. {"nop", "", "", 0}, /* 90 */ /* nop */
  391. {"xchg", "!rcx", "!rax", 0}, /* 91 */
  392. {"xchg", "!rdx", "!rax", 0}, /* 92 */
  393. {"xchg", "!rbx", "!rax", 0}, /* 93 */
  394. {"xchg", "!rsp", "!rax", 0}, /* 94 */
  395. {"xchg", "!rbp", "!rax", 0}, /* 95 */
  396. {"xchg", "!rsi", "!rax", 0}, /* 96 */
  397. {"xchg", "!rdi", "!rax", 0}, /* 97 */
  398. {"cwde", "", "", 0}, /* 98 */
  399. {"cdq", "", "", 0}, /* 99 */
  400. {"call", "Ap", "", 0}, /* 9A */
  401. {"fwait", "", "", 0}, /* 9B */
  402. {"pushf", "", "", 0}, /* 9C */ /* arg1 = Fv */
  403. {"popf", "", "", 0}, /* 9D */ /* arg1 = Fv */
  404. {"sahf", "", "", 0}, /* 9E */
  405. {"lafh", "", "", 0}, /* 9F */
  406. {"mov", "!bal", "Ob", 0}, /* A0 */
  407. {"mov", "!rax", "Ov", 0}, /* A1 */
  408. {"mov", "Ob", "!bal", 0}, /* A2 */
  409. {"mov", "Ov", "!rax", 0}, /* A3 */
  410. {"movs", "Yb", "Xb", 0}, /* A4 */
  411. {"movs", "Yv", "Xv", 0}, /* A5 */
  412. {"cmps", "Yb", "Xb", 0}, /* A6 */
  413. {"cmps", "Yv", "Xv", 0}, /* A7 */
  414. {"test", "!bal", "Ib", 0}, /* A8 */
  415. {"test", "!rax", "Iz", 0}, /* A9 */
  416. {"stos", "Yb", "!bal", 0}, /* AA */
  417. {"stos", "Yv", "!rax", 0}, /* AB */
  418. {"lods", "!bal", "Xb", 0}, /* AC */
  419. {"lods", "!rax", "Xv", 0}, /* AD */
  420. {"scas", "Yb", "!bal", 0}, /* AE */
  421. {"scas", "Yv", "!rax", 0}, /* AF */
  422. {"mov", "!bal", "Ib", 0}, /* B0 */
  423. {"mov", "!bcl", "Ib", 0}, /* B1 */
  424. {"mov", "!bdl", "Ib", 0}, /* B2 */
  425. {"mov", "!bbl", "Ib", 0}, /* B3 */
  426. {"mov", "!bah", "Ib", 0}, /* B4 */
  427. {"mov", "!bch", "Ib", 0}, /* B5 */
  428. {"mov", "!bdh", "Ib", 0}, /* B6 */
  429. {"mov", "!bbh", "Ib", 0}, /* B7 */
  430. {"mov", "!rax", "Iv", 0}, /* B8 */
  431. {"mov", "!rcx", "Iv", 0}, /* B9 */
  432. {"mov", "!rdx", "Iv", 0}, /* BA */
  433. {"mov", "!rbx", "Iv", 0}, /* BB */
  434. {"mov", "!rsp", "Iv", 0}, /* BC */
  435. {"mov", "!rbp", "Iv", 0}, /* BD */
  436. {"mov", "!rsi", "Iv", 0}, /* BE */
  437. {"mov", "!rdi", "Iv", 0}, /* BF */
  438. {"GRP2", "Eb", "Ib", 2}, /* C0 */ /* Group 2 */
  439. {"GRP2", "Ev", "Ib", 2}, /* C1 */ /* Group 2 */
  440. {"ret", "Iw", "", 0}, /* C2 */
  441. {"ret", "", "", 0}, /* C3 */
  442. {"les", "Gz", "Mp", 0}, /* C4 */
  443. {"lds", "Gz", "Mp", 0}, /* C5 */
  444. {"mov", "Eb", "Ib", 12}, /* C6 */ /* Group 12 */
  445. {"mov", "Ev", "Iz", 12}, /* C7 */ /* Group 12 */
  446. {"enter", "Iw", "Ib", 0}, /* C8 */
  447. {"leave", "", "", 0}, /* C9 */
  448. {"retf", "Iw", "", 0}, /* CA */
  449. {"retf", "", "", 0}, /* CB */
  450. {"int", "!b3", "", 0}, /* CC */ /* Int 3 */
  451. {"int", "Ib", "", 0}, /* CD */
  452. {"into", "", "", 0}, /* CE */
  453. {"iret", "", "", 0}, /* CF */
  454. {"GRP2", "Eb", "!b1", 2}, /* D0 */ /* Group 2, arg2 = 1 */
  455. {"GRP2", "Ev", "!b1", 2}, /* D1 */ /* Group 2, arg2 = 1 */
  456. {"GRP2", "Eb", "!bcl", 2}, /* D2 */ /* Group 2 */
  457. {"GRP2", "Ev", "!bcl", 2}, /* D3 */ /* Group 2 */
  458. {"aam", "Ib", "", 0}, /* D4 */
  459. {"aad", "Ib", "", 0}, /* D5 */
  460. {"setalc", "", "", 0}, /* D6 */
  461. {"xlat", "", "", 0}, /* D7 */
  462. {"ESC0", "Ev", "", 0x87}, /* D8 */ /* x87 Floating Pt */
  463. {"ESC1", "Ev", "", 0x87}, /* D9 */
  464. {"ESC2", "Ev", "", 0x87}, /* DA */
  465. {"ESC3", "Ev", "", 0x87}, /* DB */
  466. {"ESC4", "Ev", "", 0x87}, /* DC */
  467. {"ESC5", "Ev", "", 0x87}, /* DD */
  468. {"ESC6", "Ev", "", 0x87}, /* DE */
  469. {"ESC7", "Ev", "", 0x87}, /* DF */
  470. {"loopnz", "Jb", "", 0}, /* E0 */
  471. {"loopz", "Jb", "", 0}, /* E1 */
  472. {"loop", "Jb", "", 0}, /* E2 */
  473. {"jecx", "Jb", "", 0}, /* E3 */
  474. {"in ", "!bal", "Ib", 0}, /* E4 */
  475. {"in ", "!eax", "Iv", 0}, /* E5 */
  476. {"out", "Ib", "!bal", 0}, /* E6 */
  477. {"out", "Ib", "!eax", 0}, /* E7 */
  478. {"call", "Jz", "", 0}, /* E8 */
  479. {"jmp", "Jz", "", 0}, /* E9 */
  480. {"jmp", "Ap", "", 0}, /* EA */
  481. {"jmp", "Jb", "", 0}, /* EB */
  482. {"in ", "!bal", "!wdx", 0}, /* EC */
  483. {"in ", "!eax", "!wdx", 0}, /* ED */
  484. {"out", "!wdx", "!bal", 0}, /* EE */
  485. {"out", "!wdx", "!eax", 0}, /* EF */
  486. {"LOCK:", "", "", 0}, /* F0 */ /* Lock prefix */
  487. {"int", "!b1", "", 0}, /* F1 */ /* Int 1 */
  488. {"REPNE:", "", "", 0}, /* F2 */ /* Repne prefix */
  489. {"REP:", "", "", 0}, /* F3 */ /* Rep prefix */
  490. {"hlt", "", "", 0}, /* F4 */
  491. {"cmc", "", "", 0}, /* F5 */
  492. {"GRP3", "Eb", "", 3}, /* F6 */ /* Group 3 */
  493. {"GRP3", "Ev", "", 0x3A}, /* F7 */ /* Group 3A */
  494. {"clc", "", "", 0}, /* F8 */
  495. {"stc", "", "", 0}, /* F9 */
  496. {"cli", "", "", 0}, /* FA */
  497. {"sti", "", "", 0}, /* FB */
  498. {"cld", "", "", 0}, /* FC */
  499. {"std", "", "", 0}, /* FD */
  500. {"GRP4", "Eb", "", 4}, /* FE */ /* Group 4 */
  501. {"GRP5", "Ev", "", 5}, /* FF */ /* Group 5 */
  502. };
  503. X86_SPARSE_INSTRUCTION_DEFINITION DbgX86TwoByteInstructions[] = {
  504. {0, 0x0, {"GRP6", "", "", 6}}, /* 00 */ /* Group 6 */
  505. {0, 0x1, {"GRP7", "", "", 7}}, /* 01 */ /* Group 7 */
  506. {0, 0x2, {"lar", "Gv", "Ew", 0}}, /* 02 */
  507. {0, 0x3, {"lsl", "Gv", "Ew", 0}}, /* 03 */
  508. {0, 0x5, {"loadall/syscall", "", "", 0}}, /* 05 */
  509. {0, 0x6, {"clts", "", "", 0}}, /* 06 */
  510. {0, 0x7, {"loadall/sysret", "", "", 0}}, /* 07 */
  511. {0, 0x8, {"invd", "", "", 0}}, /* 08 */
  512. {0, 0x9, {"wbinvd", "", "", 0}}, /* 09 */
  513. {0, 0xB, {"ud1", "", "", 0}}, /* 0B */
  514. {0, 0x10, {"umov", "Eb", "Gb", 0}}, /* 10 */
  515. {0, 0x11, {"umov", "Ev", "Gv", 0}}, /* 11 */
  516. {0, 0x12, {"umov", "Gb", "Eb", 0}}, /* 12 */
  517. {0, 0x13, {"umov", "Gv", "Ev", 0}}, /* 13 */
  518. {0, 0x20, {"mov", "Rd", "Cd", 0}}, /* 20 */
  519. {0, 0x21, {"mov", "Rd", "Dd", 0}}, /* 21 */
  520. {0, 0x22, {"mov", "Cd", "Rd", 0}}, /* 22 */
  521. {0, 0x23, {"mov", "Dd", "Rd", 0}}, /* 23 */
  522. {0, 0x30, {"wrmsr", "", "", 0}}, /* 30 */
  523. {0, 0x31, {"rdtsc", "", "", 0}}, /* 31 */
  524. {0, 0x32, {"rdmsr", "", "", 0}}, /* 32 */
  525. {0, 0x33, {"rdpmc", "", "", 0}}, /* 33 */
  526. {0, 0x34, {"sysenter", "", "", 0}}, /* 34 */
  527. {0, 0x35, {"sysexit", "", "", 0}}, /* 35 */
  528. {0, 0x37, {"getsec", "", "", 0}}, /* 37 */
  529. {0, 0x40, {"cmovo", "Gv", "Ev", 0}}, /* 40 */
  530. {0, 0x41, {"cmovno", "Gv", "Ev", 0}}, /* 41 */
  531. {0, 0x42, {"cmovb", "Gv", "Ev", 0}}, /* 42 */
  532. {0, 0x43, {"cmovnb", "Gv", "Ev", 0}}, /* 43 */
  533. {0, 0x44, {"cmovz", "Gv", "Ev", 0}}, /* 44 */
  534. {0, 0x45, {"cmovnz", "Gv", "Ev", 0}}, /* 45 */
  535. {0, 0x46, {"cmovbe", "Gv", "Ev", 0}}, /* 46 */
  536. {0, 0x47, {"cmovnbe", "Gv", "Ev", 0}}, /* 47 */
  537. {0, 0x48, {"cmovs", "Gv", "Ev", 0}}, /* 48 */
  538. {0, 0x49, {"cmovns", "Gv", "Ev", 0}}, /* 49 */
  539. {0, 0x4A, {"cmovp", "Gv", "Ev", 0}}, /* 4A */
  540. {0, 0x4B, {"cmovnp", "Gv", "Ev", 0}}, /* 4B */
  541. {0, 0x4C, {"cmovl", "Gv", "Ev", 0}}, /* 4C */
  542. {0, 0x4D, {"cmovnl", "Gv", "Ev", 0}}, /* 4D */
  543. {0, 0x4E, {"cmovle", "Gv", "Ev", 0}}, /* 4E */
  544. {0, 0x4F, {"cmovnle", "Gv", "Ev", 0}}, /* 4F */
  545. {0, 0x80, {"jo ", "Jz", "", 0}}, /* 80 */
  546. {0, 0x81, {"jno", "Jz", "", 0}}, /* 81 */
  547. {0, 0x82, {"jb ", "Jz", "", 0}}, /* 82 */
  548. {0, 0x83, {"jnb", "Jz", "", 0}}, /* 83 */
  549. {0, 0x84, {"jz ", "Jz", "", 0}}, /* 84 */
  550. {0, 0x85, {"jnz", "Jz", "", 0}}, /* 85 */
  551. {0, 0x86, {"jbe", "Jz", "", 0}}, /* 86 */
  552. {0, 0x87, {"jnbe", "Jz", "", 0}}, /* 87 */
  553. {0, 0x88, {"js ", "Jz", "", 0}}, /* 88 */
  554. {0, 0x89, {"jns", "Jz", "", 0}}, /* 89 */
  555. {0, 0x8A, {"jp", "Jz", "", 0}}, /* 8A */
  556. {0, 0x8B, {"jnp", "Jz", "", 0}}, /* 8B */
  557. {0, 0x8C, {"jl ", "Jz", "", 0}}, /* 8C */
  558. {0, 0x8D, {"jnl", "Jz", "", 0}}, /* 8D */
  559. {0, 0x8E, {"jle", "Jz", "", 0}}, /* 8E */
  560. {0, 0x8F, {"jnle", "Jz", "", 0}}, /* 8F */
  561. {0, 0x90, {"seto", "Eb", "", 0}}, /* 90 */
  562. {0, 0x91, {"setno", "Eb", "", 0}}, /* 91 */
  563. {0, 0x92, {"setb", "Eb", "", 0}}, /* 92 */
  564. {0, 0x93, {"setnb", "Eb", "", 0}}, /* 93 */
  565. {0, 0x94, {"setz", "Eb", "", 0}}, /* 94 */
  566. {0, 0x95, {"setnz", "Eb", "", 0}}, /* 95 */
  567. {0, 0x96, {"setbe", "Eb", "", 0}}, /* 96 */
  568. {0, 0x97, {"setnbe", "Eb", "", 0}}, /* 97 */
  569. {0, 0x98, {"sets", "Eb", "", 0}}, /* 98 */
  570. {0, 0x99, {"setns", "Eb", "", 0}}, /* 99 */
  571. {0, 0x9A, {"setp", "Eb", "", 0}}, /* 9A */
  572. {0, 0x9B, {"setnp", "Eb", "", 0}}, /* 9B */
  573. {0, 0x9C, {"setl", "Eb", "", 0}}, /* 9C */
  574. {0, 0x9D, {"setnl", "Eb", "", 0}}, /* 9D */
  575. {0, 0x9E, {"setle", "Eb", "", 0}}, /* 9E */
  576. {0, 0x9F, {"setnle", "Eb", "", 0}}, /* 9F */
  577. {0, 0xA0, {"push", "!wfs", "", 0}}, /* A0 */
  578. {0, 0xA1, {"pop", "!wfs", "", 0}}, /* A1 */
  579. {0, 0xA2, {"cpuid", "", "", 0}}, /* A2 */
  580. {0, 0xA3, {"bt ", "Ev", "Gv", 0}}, /* A3 */
  581. {0, 0xA4, {"shld", "Ev", "Gv", 0}}, /* A4 */ /* also has Ib */
  582. {0, 0xA5, {"shld", "Ev", "Gv", 0}}, /* A5 */ /* also has !bcl */
  583. {0, 0xA6, {"cmpxchg", "", "", 0}}, /* A6 */
  584. {0, 0xA7, {"cmpxchg", "", "", 0}}, /* A7 */
  585. {0, 0xA8, {"push", "!wgs", "", 0}}, /* A8 */
  586. {0, 0xA9, {"pop", "!gs", "", 0}}, /* A9 */
  587. {0, 0xAA, {"rsm", "", "", 0}}, /* AA */
  588. {0, 0xAB, {"bts", "Ev", "Gv", 0}}, /* AB */
  589. {0, 0xAC, {"shrd", "Ev", "Gv", 0}}, /* AC */ /* Also has Ib */
  590. {0, 0xAD, {"shrd", "Ev", "Gv", 0}}, /* AD */ /* Also has !bcl */
  591. {0, 0xAE, {"GRP15", "", "", 15}}, /* AE */ /* Group 15 */
  592. {0, 0xAF, {"imul", "Gv", "Ev", 0}}, /* AF */
  593. {0, 0xB0, {"cmpxchg", "Eb", "Gb", 0}}, /* B0 */
  594. {0, 0xB1, {"cmpxchg", "Ev", "Gv", 0}}, /* B1 */
  595. {0, 0xB2, {"lss", "Gz", "Mp", 0}}, /* B2 */
  596. {0, 0xB3, {"btr", "Ev", "Gv", 0}}, /* B3 */
  597. {0, 0xB4, {"lfs", "Gz", "Mp", 0}}, /* B4 */
  598. {0, 0xB5, {"lgs", "Gz", "Mp", 0}}, /* B5 */
  599. {0, 0xB6, {"movzx", "Gv", "Eb", 0}}, /* B6 */
  600. {0, 0xB7, {"movxz", "Gv", "Ew", 0}}, /* B7 */
  601. {0, 0xB8, {"jmpe", "Jz", "", 0}}, /* B8 */
  602. {0, 0xB9, {"ud2", "", "", 11}}, /* B9 */ /* Group 11 */
  603. {0, 0xBA, {"GRP8", "Ev", "Ib", 8}}, /* BA */ /* Group 8 */
  604. {0, 0xBB, {"btc", "Ev", "Gv", 0}}, /* BB */
  605. {0, 0xBC, {"bsf", "Gv", "Ev", 0}}, /* BC */
  606. {0, 0xBD, {"bsr", "Gv", "Ev", 0}}, /* BD */
  607. {0, 0xBE, {"movsx", "Gv", "Eb", 0}}, /* BE */
  608. {0, 0xBF, {"movsx", "Gv", "Ew", 0}}, /* BF */
  609. {0xF3, 0xB8, {"popcnt", "Gv", "Ev", 0}}, /* B8 */
  610. {0xF3, 0xBD, {"lzcnt", "Gv", "Ev", 0}}, /* BD */
  611. {0, 0xC0, {"xadd", "Eb", "Gb", 0}}, /* C0 */
  612. {0, 0xC1, {"xadd", "Ev", "Gv", 0}}, /* C1 */
  613. {0, 0xC7, {"GRP9", "", "", 9}}, /* C7 */ /* Group 9 */
  614. {0, 0xC8, {"bswap", "!leax", "", 0}}, /* C8 */
  615. {0, 0xC9, {"bswap", "!lecx", "", 0}}, /* C9 */
  616. {0, 0xCA, {"bswap", "!ledx", "", 0}}, /* CA */
  617. {0, 0xCB, {"bswap", "!lebx", "", 0}}, /* CB */
  618. {0, 0xCC, {"bswap", "!lesp", "", 0}}, /* CC */
  619. {0, 0xCD, {"bswap", "!lebp", "", 0}}, /* CD */
  620. {0, 0xCE, {"bswap", "!lesi", "", 0}}, /* CE */
  621. {0, 0xCF, {"bswap", "!ledi", "", 0}}, /* CF */
  622. {0, 0xFF, {"ud", "", "", 0}}, /* FF */
  623. {0x66, 0xFF, {"ud", "", "", 0}}, /* FF */
  624. {0, 0x0, {"", "", "", 0}}, /* 00 */
  625. {0, 0x0, {"", "", "", 0}}, /* 00 */
  626. {0, 0x0, {"", "", "", 0}}, /* 00 */
  627. {0, 0x0, {"", "", "", 0}}, /* 00 */
  628. {0, 0x0, {"", "", "", 0}}, /* 00 */
  629. {0, 0x0, {"", "", "", 0}}, /* 00 */
  630. {0, 0x0, {"", "", "", 0}}, /* 00 */
  631. {0, 0x0, {"", "", "", 0}}, /* 00 */
  632. };
  633. X86_INSTRUCTION_DEFINITION DbgX86Group1Instructions[8] = {
  634. {"add", "", "", 0}, /* 00 */
  635. {"or ", "", "", 0}, /* 01 */
  636. {"adc", "", "", 0}, /* 02 */
  637. {"sbb", "", "", 0}, /* 03 */
  638. {"and", "", "", 0}, /* 04 */
  639. {"sub", "", "", 0}, /* 05 */
  640. {"xor", "", "", 0}, /* 06 */
  641. {"cmp", "", "", 0}, /* 07 */
  642. };
  643. X86_INSTRUCTION_DEFINITION DbgX86Group2Instructions[8] = {
  644. {"rol", "", "", 0}, /* 00 */
  645. {"ror", "", "", 0}, /* 01 */
  646. {"rcl", "", "", 0}, /* 02 */
  647. {"rcr", "", "", 0}, /* 03 */
  648. {"shl", "", "", 0}, /* 04 */
  649. {"shr", "", "", 0}, /* 05 */
  650. {"sal", "", "", 0}, /* 06 */
  651. {"sar", "", "", 0}, /* 07 */
  652. };
  653. X86_INSTRUCTION_DEFINITION DbgX86Group3Instructions[8] = {
  654. {"test", "Ev", "Ib", 0}, /* 00 */
  655. {"test", "Ev", "Ib", 0}, /* 01 */
  656. {"not", "", "", 0}, /* 02 */
  657. {"neg", "", "", 0}, /* 03 */
  658. {"mul", "", "!rax", 0}, /* 04 */
  659. {"mul", "", "!rax", 0}, /* 05 */
  660. {"div", "", "!rax", 0}, /* 06 */
  661. {"div", "", "!rax", 0}, /* 07 */
  662. };
  663. X86_INSTRUCTION_DEFINITION DbgX86Group3AInstructions[8] = {
  664. {"test", "Ev", "Iz", 0}, /* 00 */
  665. {"test", "Ev", "Iz", 0}, /* 01 */
  666. {"not", "", "", 0}, /* 02 */
  667. {"neg", "", "", 0}, /* 03 */
  668. {"mul", "", "!rax", 0}, /* 04 */
  669. {"mul", "", "!rax", 0}, /* 05 */
  670. {"div", "", "!rax", 0}, /* 06 */
  671. {"div", "", "!rax", 0}, /* 07 */
  672. };
  673. X86_INSTRUCTION_DEFINITION
  674. DbgX86Group4Instructions[X86_GROUP_4_INSTRUCTION_COUNT] = {
  675. {"inc", "Eb", "", 0}, /* 00 */
  676. {"dec", "Eb", "", 0}, /* 01 */
  677. };
  678. X86_INSTRUCTION_DEFINITION
  679. DbgX86Group5Instructions[X86_GROUP_5_INSTRUCTION_COUNT] = {
  680. {"inc", "Ev", "", 0}, /* 00 */
  681. {"dec", "Ev", "", 0}, /* 01 */
  682. {"call", "Ev", "", 0}, /* 02 */
  683. {"call", "Mp", "", 0}, /* 03 */
  684. {"jmp", "Ev", "", 0}, /* 04 */
  685. {"jmp", "Mp", "", 0}, /* 05 */
  686. {"push", "Ev", "", 0}, /* 06 */
  687. };
  688. X86_INSTRUCTION_DEFINITION
  689. DbgX86Group6Instructions[X86_GROUP_6_INSTRUCTION_COUNT] = {
  690. {"sldt", "Ev", "", 0}, /* 00 */
  691. {"str", "Ev", "", 0}, /* 01 */
  692. {"lldt", "Ev", "", 0}, /* 02 */
  693. {"ltr", "Ev", "", 0}, /* 03 */
  694. {"verr", "Ev", "", 0}, /* 04 */
  695. {"verw", "Ev", 0}, /* 05 */
  696. };
  697. X86_INSTRUCTION_DEFINITION DbgX86Group7Instructions[8] = {
  698. {"sgdt", "Ms", "", 0}, /* 00 */
  699. {"sidt", "Ms", "", 0}, /* 01 */
  700. {"lgdt", "Ms", "", 0}, /* 02 */
  701. {"lidt", "Ms", "", 0}, /* 03 */
  702. {"smsw", "Mw", "", 0}, /* 04 */
  703. {"", "", "", X86_INVALID_GROUP}, /* 05 */
  704. {"lmsw", "Mw", "", 0}, /* 06 */
  705. {"invlpg", "Ml", "", 0}, /* 07 */
  706. };
  707. X86_INSTRUCTION_DEFINITION DbgX86Group8Instructions[8] = {
  708. {"", "", "", X86_INVALID_GROUP}, /* 00 */
  709. {"", "", "", X86_INVALID_GROUP}, /* 01 */
  710. {"", "", "", X86_INVALID_GROUP}, /* 02 */
  711. {"", "", "", X86_INVALID_GROUP}, /* 03 */
  712. {"bt ", "", "", 0}, /* 04 */
  713. {"bts", "", 0}, /* 05 */
  714. {"btr", "", "", 0}, /* 06 */
  715. {"btc", "", "", 0}, /* 07 */
  716. };
  717. X86_INSTRUCTION_DEFINITION DbgX86Group9Instructions[8] = {
  718. {"", "", "", X86_INVALID_GROUP}, /* 00 */
  719. {"cmpxchg", "Mq", "", 0}, /* 01 */
  720. };
  721. X86_INSTRUCTION_DEFINITION DbgX86Group15Instructions[8] = {
  722. {"fxsave", "M", "", 0}, /* 00 */
  723. {"fxrstor", "M", "", 0}, /* 01 */
  724. {"vldmxcsr", "Md", "", 0}, /* 02 */
  725. {"vstmxcsr", "Md", "", 0}, /* 03 */
  726. {"xsave", "M", "", 0}, /* 04 */
  727. {"xrstor", "M", "", 0}, /* 05 */
  728. {"xsaveopt", "M", "", 0}, /* 06 */
  729. {"clflush", "M", "", 0}, /* 07 */
  730. };
  731. X86_SPARSE_INSTRUCTION_DEFINITION DbgX860F01Alternates[] = {
  732. {0, 0xC1, {"vmcall", "", "", 0}},
  733. {0, 0xC2, {"vmlaunch", "", "", 0}},
  734. {0, 0xC3, {"vmresume", "", "", 0}},
  735. {0, 0xC4, {"vmxoff", "", "", 0}},
  736. {0, 0xC8, {"monitor", "", "", 0}},
  737. {0, 0xC9, {"mwait", "", "", 0}},
  738. {0, 0xCA, {"clac", "", "", 0}},
  739. {0, 0xCB, {"stac", "", "", 0}},
  740. {0, 0xCF, {"encls", "", "", 0}},
  741. {0, 0xD0, {"xgetbv", "", "", 0}},
  742. {0, 0xD1, {"xsetbv", "", "", 0}},
  743. {0, 0xD4, {"vmfunc", "", "", 0}},
  744. {0, 0xD5, {"xend", "", "", 0}},
  745. {0, 0xD6, {"xtest", "", "", 0}},
  746. {0, 0xD7, {"enclu", "", "", 0}},
  747. {0, 0xD8, {"vmrun", "", "", 0}},
  748. {0, 0xD9, {"vmmcall", "", "", 0}},
  749. {0, 0xDA, {"vmload", "", "", 0}},
  750. {0, 0xDB, {"vmsave", "", "", 0}},
  751. {0, 0xDC, {"stgi", "", "", 0}},
  752. {0, 0xDD, {"clgi", "", "", 0}},
  753. {0, 0xDE, {"skinit", "", "", 0}},
  754. {0, 0xDF, {"invlpga", "", "", 0}},
  755. {0, 0xEE, {"rdpkru", "", "", 0}},
  756. {0, 0xEF, {"wrpkru", "", "", 0}},
  757. {0, 0xF8, {"swapgs", "", "", 0}},
  758. {0, 0xF9, {"rdtscp", "", "", 0}},
  759. {0, 0xFA, {"monitorx", "", "", 0}},
  760. {0, 0xFB, {"mwaitx", "", "", 0}},
  761. {0, 0xFC, {"clzero", "", "", 0}},
  762. };
  763. //
  764. // Define the various x87 floating point mnemonics. The first index is the
  765. // first opcode (offset from 0xD8), and the second index is the reg2 portion
  766. // of the ModR/M byte. These are only valid if the mod portion of ModR/M
  767. // does not specify a register. If it specifies a register, then there are
  768. // different arrays used for decoding.
  769. //
  770. PSTR DbgX87Instructions[8][8] = {
  771. {
  772. "fadd",
  773. "fmul",
  774. "fcom",
  775. "fcomp",
  776. "fsub",
  777. "fsubr",
  778. "fdiv",
  779. "fdivr"
  780. },
  781. {
  782. "fld",
  783. NULL,
  784. "fst",
  785. "fstp",
  786. "fldenv",
  787. "fldcw",
  788. "fstenv",
  789. "fstcw"
  790. },
  791. {
  792. "fiadd",
  793. "fimul",
  794. "ficom",
  795. "ficomp",
  796. "fisub",
  797. "fisubr",
  798. "fidiv",
  799. "fidivr"
  800. },
  801. {
  802. "fild",
  803. "fisttp",
  804. "fist",
  805. "fistp",
  806. NULL,
  807. "fld",
  808. NULL,
  809. "fstp"
  810. },
  811. {
  812. "fadd",
  813. "fmul",
  814. "fcom",
  815. "fcomp",
  816. "fsub",
  817. "fsubr",
  818. "fdiv",
  819. "fdivr"
  820. },
  821. {
  822. "fld",
  823. "fisttp",
  824. "fst",
  825. "fstp",
  826. "frstor",
  827. NULL,
  828. "fsave",
  829. "fstsw"
  830. },
  831. {
  832. "fiadd",
  833. "fimul",
  834. "ficom",
  835. "ficomp",
  836. "fisub",
  837. "fisubr",
  838. "fidiv",
  839. "fidivr"
  840. },
  841. {
  842. "fild",
  843. "fisttp",
  844. "fist",
  845. "fistp",
  846. "fbld",
  847. "fild",
  848. "fbstp",
  849. "fistp"
  850. }
  851. };
  852. PSTR DbgX87D9E0Instructions[32] = {
  853. "fchs",
  854. "fabs",
  855. NULL,
  856. NULL,
  857. "ftst",
  858. "fxam",
  859. "ftstp",
  860. NULL,
  861. "fld1",
  862. "fldl2t",
  863. "fldl2e",
  864. "fldpi",
  865. "fldlg2",
  866. "fldln2",
  867. "fldz",
  868. NULL,
  869. "f2xm1",
  870. "fyl2x",
  871. "fptan",
  872. "fpatan",
  873. "fxtract",
  874. "fprem1",
  875. "fdecstp",
  876. "fincstp",
  877. "fprem",
  878. "fyl2xp1",
  879. "fsqrt",
  880. "fsincos",
  881. "frndint",
  882. "fscale",
  883. "fsin",
  884. "fcos",
  885. };
  886. PSTR DbgX87DAC0Instructions[8] = {
  887. "fcmovb",
  888. "fcmove",
  889. "fcmovbe",
  890. "fcmovu",
  891. NULL,
  892. NULL,
  893. NULL,
  894. NULL
  895. };
  896. PSTR DbgX87DBC0Instructions[8] = {
  897. "fcmovnb",
  898. "fcmovne",
  899. "fcmovnbe",
  900. "fcmovnu",
  901. NULL,
  902. "fucomi",
  903. "fcomi",
  904. NULL
  905. };
  906. PSTR DbgX87DBE0Instructions[8] = {
  907. "feni",
  908. "fdisi",
  909. "fclex",
  910. "finit",
  911. "fsetpm",
  912. "frstpm",
  913. NULL,
  914. NULL
  915. };
  916. PSTR DbgX87DCC0Instructions[8] = {
  917. "fadd",
  918. "fmul",
  919. "fcom",
  920. "fcomp",
  921. "fsubr",
  922. "fsub",
  923. "fdivr",
  924. "fdiv",
  925. };
  926. PSTR DbgX87DDC0Instructions[8] = {
  927. "ffree",
  928. "fxch",
  929. "fst",
  930. "fstp",
  931. "fucom",
  932. "fucomp",
  933. NULL,
  934. NULL,
  935. };
  936. PSTR DbgX87DEC0Instructions[8] = {
  937. "faddp",
  938. "fmulp",
  939. "fcomp",
  940. NULL,
  941. "fsubrp",
  942. "fsubp",
  943. "fdivrp",
  944. "fdivp",
  945. };
  946. PSTR DbgX87DFC0Instructions[8] = {
  947. "freep",
  948. "fxch",
  949. "fstp",
  950. "fstp",
  951. NULL,
  952. "fucomip",
  953. "fcomip",
  954. NULL,
  955. };
  956. PSTR DbgX87DFE0Instructions[X87_DF_E0_COUNT] = {
  957. "fstsw",
  958. "fstdw",
  959. "fstsg",
  960. };
  961. //
  962. // Define the register name constants.
  963. //
  964. PSTR DbgX86DebugRegisterNames[X86_DEBUG_REGISTER_COUNT] = {
  965. "dr0",
  966. "dr1",
  967. "dr2",
  968. "dr3",
  969. "dr4",
  970. "dr5",
  971. "dr6",
  972. "dr7"
  973. };
  974. PSTR DbgX86SegmentRegisterNames[X86_SEGMENT_REGISTER_COUNT] = {
  975. "es",
  976. "cs",
  977. "ss",
  978. "ds",
  979. "fs",
  980. "gs"
  981. };
  982. PSTR DbgX86RegisterNames8Bit[X86_REGISTER_NAME_COUNT] = {
  983. "al",
  984. "cl",
  985. "dl",
  986. "bl",
  987. "ah",
  988. "ch",
  989. "dh",
  990. "bh",
  991. };
  992. PSTR DbgX86RegisterNames16Bit[X86_REGISTER_NAME_COUNT] = {
  993. "ax",
  994. "cx",
  995. "dx",
  996. "bx",
  997. "sp",
  998. "bp",
  999. "si",
  1000. "di"
  1001. };
  1002. PSTR DbgX86RegisterNames32Bit[X86_REGISTER_NAME_COUNT] = {
  1003. "eax",
  1004. "ecx",
  1005. "edx",
  1006. "ebx",
  1007. "esp",
  1008. "ebp",
  1009. "esi",
  1010. "edi"
  1011. };
  1012. PSTR DbgX87RegisterNames[X86_REGISTER_NAME_COUNT] = {
  1013. "st(0)",
  1014. "st(1)",
  1015. "st(2)",
  1016. "st(3)",
  1017. "st(4)",
  1018. "st(5)",
  1019. "st(6)",
  1020. "st(7)",
  1021. };
  1022. //
  1023. // ----------------------------------------------- Internal Function Prototypes
  1024. //
  1025. BOOL
  1026. DbgpX86PrintOperand (
  1027. ULONGLONG InstructionPointer,
  1028. PX86_INSTRUCTION Instruction,
  1029. PSTR OperandFormat,
  1030. PSTR Operand,
  1031. ULONG BufferLength,
  1032. PULONGLONG Address,
  1033. PBOOL AddressValid
  1034. );
  1035. PSTR
  1036. DbgpX86PrintMnemonic (
  1037. PX86_INSTRUCTION Instruction
  1038. );
  1039. BOOL
  1040. DbgpX86GetInstructionComponents (
  1041. PBYTE InstructionStream,
  1042. PX86_INSTRUCTION Instruction
  1043. );
  1044. BOOL
  1045. DbgpX86GetInstructionParameters (
  1046. PBYTE InstructionStream,
  1047. PX86_INSTRUCTION Instruction,
  1048. PBOOL ModRmExists,
  1049. PBOOL SibExists,
  1050. PULONG DisplacementSize,
  1051. PULONG ImmediateSize
  1052. );
  1053. PSTR
  1054. DbgpX86GetControlRegister (
  1055. BYTE ModRm
  1056. );
  1057. PSTR
  1058. DbgpX86GetDebugRegister (
  1059. BYTE ModRm
  1060. );
  1061. PSTR
  1062. DbgpX86GetSegmentRegister (
  1063. BYTE ModRm
  1064. );
  1065. PSTR
  1066. DbgpX86GetGenericRegister (
  1067. X86_REGISTER_VALUE RegisterNumber,
  1068. CHAR Type
  1069. );
  1070. VOID
  1071. DbgpX86GetDisplacement (
  1072. PX86_INSTRUCTION Instruction,
  1073. PSTR Buffer,
  1074. PLONGLONG DisplacementValue
  1075. );
  1076. PX86_INSTRUCTION_DEFINITION
  1077. DbgpX86GetTwoByteInstruction (
  1078. PX86_INSTRUCTION Instruction
  1079. );
  1080. BOOL
  1081. DbgpX86DecodeFloatingPointInstruction (
  1082. PX86_INSTRUCTION Instruction
  1083. );
  1084. //
  1085. // ------------------------------------------------------------------ Functions
  1086. //
  1087. BOOL
  1088. DbgpX86Disassemble (
  1089. ULONGLONG InstructionPointer,
  1090. PBYTE InstructionStream,
  1091. PSTR Buffer,
  1092. ULONG BufferLength,
  1093. PDISASSEMBLED_INSTRUCTION Disassembly
  1094. )
  1095. /*++
  1096. Routine Description:
  1097. This routine decodes one instruction from an IA-32 binary instruction
  1098. stream into a human readable form.
  1099. Arguments:
  1100. InstructionPointer - Supplies the instruction pointer for the start of the
  1101. instruction stream.
  1102. InstructionStream - Supplies a pointer to the binary instruction stream.
  1103. Buffer - Supplies a pointer to the buffer where the human
  1104. readable strings will be printed. This buffer must be allocated by the
  1105. caller.
  1106. BufferLength - Supplies the length of the supplied buffer.
  1107. Disassembly - Supplies a pointer to the structure that will receive
  1108. information about the instruction.
  1109. Return Value:
  1110. TRUE on success.
  1111. FALSE if the instruction was unknown.
  1112. --*/
  1113. {
  1114. ULONGLONG Address;
  1115. BOOL AddressValid;
  1116. X86_INSTRUCTION Instruction;
  1117. PSTR Mnemonic;
  1118. BOOL Result;
  1119. PSTR ThirdOperandFormat;
  1120. if ((Disassembly == NULL) || (Buffer == NULL)) {
  1121. return FALSE;
  1122. }
  1123. memset(Buffer, 0, BufferLength);
  1124. memset(Disassembly, 0, sizeof(DISASSEMBLED_INSTRUCTION));
  1125. //
  1126. // Dissect the instruction into more managable components.
  1127. //
  1128. Result = DbgpX86GetInstructionComponents(InstructionStream, &Instruction);
  1129. if (Result == FALSE) {
  1130. goto DisassembleEnd;
  1131. }
  1132. Disassembly->BinaryLength = Instruction.Length;
  1133. //
  1134. // Print the mnemonic.
  1135. //
  1136. Mnemonic = DbgpX86PrintMnemonic(&Instruction);
  1137. if ((Mnemonic == NULL) || (strlen(Mnemonic) >= BufferLength)) {
  1138. Result = FALSE;
  1139. goto DisassembleEnd;
  1140. }
  1141. //
  1142. // Copy the mnemonic into the buffer, and advance the buffer to the next
  1143. // free spot.
  1144. //
  1145. Disassembly->Mnemonic = Buffer;
  1146. strcpy(Disassembly->Mnemonic, Mnemonic);
  1147. Buffer += strlen(Mnemonic) + 1;
  1148. BufferLength -= (strlen(Mnemonic) + 1);
  1149. //
  1150. // Get the destination operand.
  1151. //
  1152. Result = DbgpX86PrintOperand(InstructionPointer,
  1153. &Instruction,
  1154. Instruction.Definition.Target,
  1155. DbgX86DisassemblyBuffer,
  1156. X86_WORKING_BUFFER_SIZE,
  1157. &Address,
  1158. &AddressValid);
  1159. if ((Result == FALSE) ||
  1160. (strlen(DbgX86DisassemblyBuffer) >= BufferLength)) {
  1161. Result = FALSE;
  1162. goto DisassembleEnd;
  1163. }
  1164. //
  1165. // If an address came out of that, plug it into the result.
  1166. //
  1167. if (AddressValid != FALSE) {
  1168. Disassembly->OperandAddress = Address;
  1169. Disassembly->AddressIsValid = TRUE;
  1170. Disassembly->AddressIsDestination = TRUE;
  1171. }
  1172. //
  1173. // Copy the operand into the buffer, and advance the buffer.
  1174. //
  1175. Disassembly->DestinationOperand = Buffer;
  1176. strcpy(Disassembly->DestinationOperand, DbgX86DisassemblyBuffer);
  1177. Buffer += strlen(DbgX86DisassemblyBuffer) + 1;
  1178. BufferLength -= (strlen(DbgX86DisassemblyBuffer) + 1);
  1179. //
  1180. // Get the source operand.
  1181. //
  1182. Result = DbgpX86PrintOperand(InstructionPointer,
  1183. &Instruction,
  1184. Instruction.Definition.Source,
  1185. DbgX86DisassemblyBuffer,
  1186. X86_WORKING_BUFFER_SIZE,
  1187. &Address,
  1188. &AddressValid);
  1189. if ((Result == FALSE) ||
  1190. (strlen(DbgX86DisassemblyBuffer) >= BufferLength)) {
  1191. Result = FALSE;
  1192. goto DisassembleEnd;
  1193. }
  1194. //
  1195. // If an address came out of the operand, plug it into the result.
  1196. //
  1197. if (AddressValid != FALSE) {
  1198. Disassembly->OperandAddress = Address;
  1199. Disassembly->AddressIsValid = TRUE;
  1200. Disassembly->AddressIsDestination = FALSE;
  1201. }
  1202. //
  1203. // Copy the operand into the buffer, and advance the buffer.
  1204. //
  1205. if (strlen(DbgX86DisassemblyBuffer) > 0) {
  1206. Disassembly->SourceOperand = Buffer;
  1207. strcpy(Disassembly->SourceOperand, DbgX86DisassemblyBuffer);
  1208. Buffer += strlen(DbgX86DisassemblyBuffer) + 1;
  1209. BufferLength -= (strlen(DbgX86DisassemblyBuffer) - 1);
  1210. }
  1211. //
  1212. // Handle the MUL, SHLD, and SHRD instructions, which have 3 operands.
  1213. //
  1214. ThirdOperandFormat = NULL;
  1215. if (Instruction.Opcode == X86_OPCODE1_IMUL1) {
  1216. ThirdOperandFormat = "Iz";
  1217. } else if (Instruction.Opcode == X86_OPCODE1_IMUL2) {
  1218. ThirdOperandFormat = "Ib";
  1219. } else if ((Instruction.Opcode == X86_ESCAPE_OPCODE) &&
  1220. ((Instruction.Opcode2 == X86_OPCODE2_SHLD1) ||
  1221. (Instruction.Opcode2 == X86_OPCODE2_SHRD1))) {
  1222. ThirdOperandFormat = "Ib";
  1223. } else if ((Instruction.Opcode == X86_ESCAPE_OPCODE) &&
  1224. ((Instruction.Opcode2 == X86_OPCODE2_SHLD2) ||
  1225. (Instruction.Opcode2 == X86_OPCODE2_SHRD2))) {
  1226. ThirdOperandFormat = "!bcl";
  1227. }
  1228. if (ThirdOperandFormat != NULL) {
  1229. Result = DbgpX86PrintOperand(InstructionPointer,
  1230. &Instruction,
  1231. ThirdOperandFormat,
  1232. DbgX86DisassemblyBuffer,
  1233. X86_WORKING_BUFFER_SIZE,
  1234. &Address,
  1235. &AddressValid);
  1236. if ((Result == FALSE) ||
  1237. (strlen(DbgX86DisassemblyBuffer) > BufferLength)) {
  1238. Result = FALSE;
  1239. goto DisassembleEnd;
  1240. }
  1241. Disassembly->ThirdOperand = Buffer;
  1242. strcpy(Disassembly->ThirdOperand, DbgX86DisassemblyBuffer);
  1243. }
  1244. DisassembleEnd:
  1245. return Result;
  1246. }
  1247. //
  1248. // --------------------------------------------------------- Internal Functions
  1249. //
  1250. BOOL
  1251. DbgpX86PrintOperand (
  1252. ULONGLONG InstructionPointer,
  1253. PX86_INSTRUCTION Instruction,
  1254. PSTR OperandFormat,
  1255. PSTR Operand,
  1256. ULONG BufferLength,
  1257. PULONGLONG Address,
  1258. PBOOL AddressValid
  1259. )
  1260. /*++
  1261. Routine Description:
  1262. This routine prints an operand in an IA instruction stream depending on the
  1263. supplied format.
  1264. Arguments:
  1265. InstructionPointer - Supplies the instruction pointer for the instruction
  1266. being disassembled.
  1267. Instruction - Supplies a pointer to the instruction structure.
  1268. OperandFormat - Supplies the format of the operand in two or more
  1269. characters. These are largely compatible with the Intel Opcode
  1270. Encodings, except for the ! prefix, which indicates an absolute
  1271. register name.
  1272. Operand - Supplies a pointer to the string that will receive the human
  1273. readable operand.
  1274. BufferLength - Supplies the length of the supplied buffer.
  1275. Address - Supplies a pointer that receives the memory address encoded in the
  1276. operand.
  1277. AddressValid - Supplies a pointer that receives whether or not the value
  1278. store in the Address parameter is valid.
  1279. Return Value:
  1280. TRUE on success.
  1281. FALSE on failure.
  1282. --*/
  1283. {
  1284. PSTR Base;
  1285. BYTE BaseValue;
  1286. PSTR Index;
  1287. BYTE IndexValue;
  1288. X86_MOD_VALUE Mod;
  1289. X86_REGISTER_VALUE Register;
  1290. PSTR RegisterString;
  1291. X86_REGISTER_VALUE Rm;
  1292. ULONG Scale;
  1293. CHAR Type;
  1294. CHAR Width;
  1295. Base = NULL;
  1296. Index = NULL;
  1297. IndexValue = 0xFF;
  1298. Scale = 0;
  1299. RegisterString = NULL;
  1300. //
  1301. // Start by doing some parameter checking.
  1302. //
  1303. if ((Operand == NULL) || BufferLength == 0) {
  1304. return FALSE;
  1305. }
  1306. strcpy(Operand, "");
  1307. strcpy(DbgX86OperandBuffer, "");
  1308. *Address = 0ULL;
  1309. *AddressValid = FALSE;
  1310. if (strlen(OperandFormat) < 2) {
  1311. return TRUE;
  1312. }
  1313. Type = OperandFormat[0];
  1314. Width = OperandFormat[1];
  1315. //
  1316. // 'd' means dword, which gets translated to long here for simplicity.
  1317. //
  1318. if (Width == 'd') {
  1319. Width = X86_WIDTH_LONG;
  1320. }
  1321. //
  1322. // If the width is variable, it is probably a dword unless an override is
  1323. // specified.
  1324. //
  1325. if ((Width == 'v') || (Width == 'z')) {
  1326. Width = X86_WIDTH_LONG;
  1327. if ((Instruction->OperandOverride == TRUE) ||
  1328. (Instruction->AddressOverride == TRUE)) {
  1329. Width = X86_WIDTH_WORD;
  1330. }
  1331. }
  1332. switch (Type) {
  1333. //
  1334. // The ! encoding indicates that a register is hardcoded. Unless an override
  1335. // is set, append an e to the beginning of the hardcoded register (to make
  1336. // ax into eax).
  1337. //
  1338. case '!':
  1339. if ((Width == 'r') || (Width == 'e')) {
  1340. if ((Instruction->ImmediateSize == 0) &&
  1341. (Instruction->OperandOverride == FALSE)) {
  1342. strcat(Operand, "e");
  1343. } else if (Instruction->ImmediateSize == 4) {
  1344. strcat(Operand, "e");
  1345. }
  1346. }
  1347. strcat(Operand, OperandFormat + 2);
  1348. break;
  1349. //
  1350. // A - Direct address, no mod R/M byte; address of operand is encoded in
  1351. // instruction. No base, index, or scaling can be applied.
  1352. //
  1353. case 'A':
  1354. sprintf(DbgX86OperandBuffer, "[0x%x]", Instruction->Immediate);
  1355. strcat(Operand, DbgX86OperandBuffer);
  1356. *Address = Instruction->Immediate;
  1357. *AddressValid = TRUE;
  1358. break;
  1359. //
  1360. // C - Reg field of mod R/M byte selects a control register.
  1361. //
  1362. case 'C':
  1363. sprintf(DbgX86OperandBuffer,
  1364. "%s",
  1365. DbgpX86GetControlRegister(Instruction->ModRm));
  1366. strcat(Operand, DbgX86OperandBuffer);
  1367. break;
  1368. //
  1369. // D - Reg field of mod R/M byte selects a debug register.
  1370. //
  1371. case 'D':
  1372. sprintf(DbgX86OperandBuffer, "%s",
  1373. DbgpX86GetDebugRegister(Instruction->ModRm));
  1374. strcat(Operand, DbgX86OperandBuffer);
  1375. break;
  1376. //
  1377. // E - Mod R/M bytes follows opcode and specifies operand. Operand is either
  1378. // a general register or a memory address. If it is a memory address, the
  1379. // address is computed from a segment register and any of the following
  1380. // values: a base register, an index register, a scaling factor, and a
  1381. // displacement.
  1382. // M - Mod R/M byte may only refer to memory.
  1383. //
  1384. case 'E':
  1385. case 'M':
  1386. Mod = (Instruction->ModRm & X86_MOD_MASK) >> X86_MOD_SHIFT;
  1387. Rm = (Instruction->ModRm & X86_RM_MASK) >> X86_RM_SHIFT;
  1388. if (Mod == X86ModValueRegister) {
  1389. if (Type == 'M') {
  1390. return FALSE;
  1391. }
  1392. RegisterString = DbgpX86GetGenericRegister(Rm, Width);
  1393. } else {
  1394. //
  1395. // An R/M value of 4 actually indicates an SIB byte is present, not
  1396. // ESP.
  1397. //
  1398. if (Rm == X86RegisterValueEsp) {
  1399. Rm = X86RegisterValueScaleIndexBase;
  1400. BaseValue = (Instruction->Sib & X86_BASE_MASK) >>
  1401. X86_BASE_SHIFT;
  1402. IndexValue = (Instruction->Sib & X86_INDEX_MASK) >>
  1403. X86_INDEX_SHIFT;
  1404. Base = DbgpX86GetGenericRegister(BaseValue, X86_WIDTH_LONG);
  1405. Index = DbgpX86GetGenericRegister(IndexValue, X86_WIDTH_LONG);
  1406. //
  1407. // A base value of 5 (ebp) indicates that the base field is not
  1408. // used, and a displacement is present. The Mod field then
  1409. // specifies the size of the displacement.
  1410. //
  1411. if (BaseValue == X86RegisterValueEbp) {
  1412. Base = "";
  1413. sprintf(DbgX86OperandBuffer,
  1414. "0x%x",
  1415. Instruction->Displacement);
  1416. strcat(Operand, DbgX86OperandBuffer);
  1417. }
  1418. //
  1419. // Raise the scale to 2^(Scale).
  1420. //
  1421. Scale = (Instruction->Sib & X86_SCALE_MASK) >> X86_SCALE_SHIFT;
  1422. if (Scale == 0) {
  1423. Scale = 1;
  1424. } else if (Scale == 1) {
  1425. Scale = 2;
  1426. } else if (Scale == 2) {
  1427. Scale = 4;
  1428. } else if (Scale == 3) {
  1429. Scale = 8;
  1430. }
  1431. } else if ((Mod == X86ModValueNoDisplacement) &&
  1432. (Rm == X86RegisterValueEbp)) {
  1433. Rm = X86RegisterValueDisplacement32;
  1434. } else {
  1435. RegisterString = DbgpX86GetGenericRegister(Rm, X86_WIDTH_LONG);
  1436. }
  1437. }
  1438. //
  1439. // The operand is simply a register.
  1440. //
  1441. if (Mod == X86ModValueRegister) {
  1442. strcat(Operand, RegisterString);
  1443. //
  1444. // The operand is an address with a scale/index/base.
  1445. //
  1446. } else if (Rm == X86RegisterValueScaleIndexBase) {
  1447. sprintf(DbgX86OperandBuffer, "[%s", Base);
  1448. strcat(Operand, DbgX86OperandBuffer);
  1449. //
  1450. // An index of 4 indicates that the index and scale fields are not
  1451. // used.
  1452. //
  1453. if (IndexValue != 4) {
  1454. if (strlen(Base) != 0) {
  1455. strcat(Operand, "+");
  1456. }
  1457. sprintf(DbgX86OperandBuffer, "%s*%d", Index, Scale);
  1458. strcat(Operand, DbgX86OperandBuffer);
  1459. }
  1460. DbgpX86GetDisplacement(Instruction, DbgX86OperandBuffer, NULL);
  1461. strcat(Operand, DbgX86OperandBuffer);
  1462. strcat(Operand, "]");
  1463. //
  1464. // The operand is a 32-bit address.
  1465. //
  1466. } else if (Rm == X86RegisterValueDisplacement32) {
  1467. sprintf(DbgX86OperandBuffer, "[0x%x]", Instruction->Displacement);
  1468. strcat(Operand, DbgX86OperandBuffer);
  1469. *Address = Instruction->Displacement;
  1470. *AddressValid = TRUE;
  1471. //
  1472. // The operand is an address in a register, possibly with some
  1473. // additional displacement.
  1474. //
  1475. } else {
  1476. sprintf(DbgX86OperandBuffer, "[%s", RegisterString);
  1477. strcat(Operand, DbgX86OperandBuffer);
  1478. DbgpX86GetDisplacement(Instruction, DbgX86OperandBuffer, NULL);
  1479. strcat(Operand, DbgX86OperandBuffer);
  1480. strcat(Operand, "]");
  1481. }
  1482. break;
  1483. //
  1484. // F - EFLAGS register.
  1485. //
  1486. case 'F':
  1487. strcat(Operand, "eflags");
  1488. break;
  1489. //
  1490. // G - Reg field of Mod R/M byte selects a general register.
  1491. //
  1492. case 'G':
  1493. Register = (Instruction->ModRm & X86_REG_MASK) >> X86_REG_SHIFT;
  1494. strcat(Operand, DbgpX86GetGenericRegister(Register, Width));
  1495. break;
  1496. //
  1497. // I - Immediate data: value of operand is encoded in Immediate field.
  1498. // O - Direct offset: no ModR/M byte. Offset of operand is encoded in
  1499. // instruction. No Base/Index/Scale can be applied.
  1500. //
  1501. case 'I':
  1502. case 'O':
  1503. sprintf(DbgX86OperandBuffer, "0x%x", Instruction->Immediate);
  1504. strcat(Operand, DbgX86OperandBuffer);
  1505. break;
  1506. //
  1507. // J - Instruction contains a relative offset to be added to the instruction
  1508. // pointer.
  1509. //
  1510. case 'J':
  1511. DbgpX86GetDisplacement(Instruction,
  1512. DbgX86OperandBuffer,
  1513. (PLONGLONG)Address);
  1514. *Address += (InstructionPointer + Instruction->Length);
  1515. sprintf(DbgX86OperandBuffer, "[0x%x]", *Address);
  1516. strcat(Operand, DbgX86OperandBuffer);
  1517. *AddressValid = TRUE;
  1518. break;
  1519. //
  1520. // R - R/M field of modR/M byte selects a general register. Mod field should
  1521. // be set to 11.
  1522. //
  1523. case 'R':
  1524. Mod = (Instruction->ModRm & X86_MOD_MASK) >> X86_MOD_SHIFT;
  1525. Rm = (Instruction->ModRm & X86_RM_MASK) >> X86_RM_SHIFT;
  1526. if (Mod != X86ModValueRegister) {
  1527. return FALSE;
  1528. }
  1529. strcat(Operand, DbgpX86GetGenericRegister(Rm, Width));
  1530. break;
  1531. //
  1532. // S - Reg field of ModR/M byte selects a segment register.
  1533. //
  1534. case 'S':
  1535. strcat(Operand, DbgpX86GetSegmentRegister(Instruction->ModRm));
  1536. break;
  1537. //
  1538. // X - Memory addressed by DS:SI register pair (eg. MOVS CMPS, OUTS, LODS).
  1539. //
  1540. case 'X':
  1541. strcat(Operand, "DS:[esi]");
  1542. break;
  1543. //
  1544. // Y - Memory addressed by ES:DI register pair (eg. MOVS INS, STOS, SCAS).
  1545. //
  1546. case 'Y':
  1547. strcat(Operand, "ES:[edi]");
  1548. break;
  1549. default:
  1550. return FALSE;
  1551. }
  1552. return TRUE;
  1553. }
  1554. PSTR
  1555. DbgpX86PrintMnemonic (
  1556. PX86_INSTRUCTION Instruction
  1557. )
  1558. /*++
  1559. Routine Description:
  1560. This routine prints an instruction mnemonic.
  1561. Arguments:
  1562. Instruction - Supplies a pointer to the instruction structure.
  1563. Return Value:
  1564. A pointer to the mnemonic on success.
  1565. NULL on failure.
  1566. --*/
  1567. {
  1568. BYTE RegByte;
  1569. if (Instruction == NULL) {
  1570. return NULL;
  1571. }
  1572. if (Instruction->Definition.Group == 0) {
  1573. return Instruction->Definition.Mnemonic;
  1574. }
  1575. RegByte = (Instruction->ModRm & X86_REG_MASK) >> X86_REG_SHIFT;
  1576. switch (Instruction->Definition.Group) {
  1577. case 1:
  1578. return DbgX86Group1Instructions[RegByte].Mnemonic;
  1579. case 2:
  1580. return DbgX86Group2Instructions[RegByte].Mnemonic;
  1581. case 3:
  1582. return DbgX86Group3Instructions[RegByte].Mnemonic;
  1583. case 0x3A:
  1584. return DbgX86Group3AInstructions[RegByte].Mnemonic;
  1585. case 4:
  1586. if (RegByte >= X86_GROUP_4_INSTRUCTION_COUNT) {
  1587. return NULL;
  1588. }
  1589. return DbgX86Group4Instructions[RegByte].Mnemonic;
  1590. case 5:
  1591. if (RegByte >= X86_GROUP_5_INSTRUCTION_COUNT) {
  1592. return "(bad)";
  1593. }
  1594. return DbgX86Group5Instructions[RegByte].Mnemonic;
  1595. case 10:
  1596. case 12:
  1597. if (RegByte != 0) {
  1598. return "(bad)";
  1599. }
  1600. return Instruction->Definition.Mnemonic;
  1601. case 15:
  1602. return DbgX86Group15Instructions[RegByte].Mnemonic;
  1603. }
  1604. return NULL;
  1605. }
  1606. BOOL
  1607. DbgpX86GetInstructionComponents (
  1608. PBYTE InstructionStream,
  1609. PX86_INSTRUCTION Instruction
  1610. )
  1611. /*++
  1612. Routine Description:
  1613. This routine reads an instruction stream and decomposes it into its
  1614. respective components.
  1615. Arguments:
  1616. InstructionStream - Supplies a pointer to the raw binary instruction stream.
  1617. Instruction - Supplies a pointer to the structure that will accept the
  1618. instruction decomposition.
  1619. Return Value:
  1620. TRUE on success.
  1621. FALSE otherwise.
  1622. --*/
  1623. {
  1624. ULONG AlternateCount;
  1625. ULONG AlternateIndex;
  1626. ULONG Base;
  1627. PBYTE Beginning;
  1628. PBYTE CurrentPrefix;
  1629. ULONG DisplacementSize;
  1630. ULONG Group;
  1631. ULONG ImmediateSize;
  1632. ULONG Mod;
  1633. BOOL ModRmExists;
  1634. UCHAR Opcode3;
  1635. BYTE RegByte;
  1636. BOOL Result;
  1637. BOOL SibExists;
  1638. PX86_INSTRUCTION_DEFINITION TopLevelDefinition;
  1639. PX86_INSTRUCTION_DEFINITION TwoByteInstruction;
  1640. if (Instruction == NULL) {
  1641. return FALSE;
  1642. }
  1643. CurrentPrefix = &(Instruction->Prefix[0]);
  1644. Beginning = InstructionStream;
  1645. Result = TRUE;
  1646. memset(Instruction, 0, sizeof(X86_INSTRUCTION));
  1647. //
  1648. // Begin by handling any prefixes. The prefixes are: F0 (LOCK), F2 (REP),
  1649. // F3 (REP), 2E (CS), 36 (SS), 3E (DS), 26 (ES), 64 (FS), 65 (GS),
  1650. // 66 (Operand-size override), 67 (Address-size override)).
  1651. //
  1652. while ((*InstructionStream == X86_PREFIX_LOCK) ||
  1653. (*InstructionStream == X86_PREFIX_REP1) ||
  1654. (*InstructionStream == X86_PREFIX_REP2) ||
  1655. ((*InstructionStream & X86_PREFIX_FS_GS_OVERRIDE_MASK) ==
  1656. X86_PREFIX_FS_GS_OVERRIDE_VALUE) ||
  1657. (*InstructionStream == X86_PREFIX_CS) ||
  1658. (*InstructionStream == X86_PREFIX_DS) ||
  1659. (*InstructionStream == X86_PREFIX_ES) ||
  1660. (*InstructionStream == X86_PREFIX_SS)) {
  1661. if (*InstructionStream == X86_OPERAND_OVERRIDE) {
  1662. Instruction->OperandOverride = TRUE;
  1663. } else if (*InstructionStream == X86_ADDRESS_OVERRIDE) {
  1664. Instruction->AddressOverride = TRUE;
  1665. }
  1666. *CurrentPrefix = *InstructionStream;
  1667. CurrentPrefix += 1;
  1668. InstructionStream += 1;
  1669. Instruction->Length += 1;
  1670. //
  1671. // No more than 4 prefixes are allowed in one instruction.
  1672. //
  1673. if (Instruction->Length == X86_MAX_PREFIXES) {
  1674. break;
  1675. }
  1676. }
  1677. Instruction->Opcode = *InstructionStream;
  1678. Instruction->Length += 1;
  1679. InstructionStream += 1;
  1680. //
  1681. // Check for a two byte opcode.
  1682. //
  1683. if (Instruction->Opcode == X86_ESCAPE_OPCODE) {
  1684. Instruction->Opcode2 = *InstructionStream;
  1685. Instruction->Length += 1;
  1686. InstructionStream += 1;
  1687. TwoByteInstruction = DbgpX86GetTwoByteInstruction(Instruction);
  1688. if (TwoByteInstruction == NULL) {
  1689. Result = FALSE;
  1690. goto GetInstructionComponentsEnd;
  1691. }
  1692. TopLevelDefinition = TwoByteInstruction;
  1693. } else {
  1694. TopLevelDefinition = &(DbgX86Instructions[Instruction->Opcode]);
  1695. }
  1696. //
  1697. // Modify the instruction definition for groups. If the opcode is in a
  1698. // group, then it must have a modR/M byte, so cheat a little and get it.
  1699. //
  1700. Instruction->Definition = *TopLevelDefinition;
  1701. Group = Instruction->Definition.Group;
  1702. if ((Group != 0) && (Group != X86_INVALID_GROUP)) {
  1703. RegByte = (*InstructionStream & X86_REG_MASK) >> X86_REG_SHIFT;
  1704. switch (Instruction->Definition.Group) {
  1705. case 1:
  1706. case 2:
  1707. break;
  1708. case 3:
  1709. Instruction->Definition.Source =
  1710. DbgX86Group3Instructions[RegByte].Source;
  1711. break;
  1712. case 0x3A:
  1713. Instruction->Definition.Source =
  1714. DbgX86Group3AInstructions[RegByte].Source;
  1715. break;
  1716. case 4:
  1717. case 5:
  1718. break;
  1719. case 6:
  1720. if (RegByte >= X86_GROUP_6_INSTRUCTION_COUNT) {
  1721. Result = FALSE;
  1722. goto GetInstructionComponentsEnd;
  1723. }
  1724. Instruction->Definition = DbgX86Group6Instructions[RegByte];
  1725. break;
  1726. case 7:
  1727. Instruction->Definition = DbgX86Group7Instructions[RegByte];
  1728. //
  1729. // There are a bunch of alternate encoding instructions hidden
  1730. // behind 0F 01, go look for them.
  1731. //
  1732. if (RegByte == 1) {
  1733. Opcode3 = *InstructionStream;
  1734. AlternateCount = sizeof(DbgX860F01Alternates) /
  1735. sizeof(DbgX860F01Alternates[0]);
  1736. for (AlternateIndex = 0;
  1737. AlternateIndex < AlternateCount;
  1738. AlternateIndex += 1) {
  1739. if (DbgX860F01Alternates[AlternateIndex].Opcode ==
  1740. Opcode3) {
  1741. Instruction->Definition =
  1742. DbgX860F01Alternates[AlternateIndex].Instruction;
  1743. break;
  1744. }
  1745. }
  1746. }
  1747. break;
  1748. case 8:
  1749. if (RegByte < X86_GROUP_8_FIRST_INSTRUCTION) {
  1750. Result = FALSE;
  1751. goto GetInstructionComponentsEnd;
  1752. }
  1753. Instruction->Definition = DbgX86Group8Instructions[RegByte];
  1754. break;
  1755. case 9:
  1756. if (RegByte != X86_GROUP_9_ONLY_VALID_INSTRUCTION) {
  1757. Result = FALSE;
  1758. goto GetInstructionComponentsEnd;
  1759. }
  1760. Instruction->Definition = DbgX86Group9Instructions[RegByte];
  1761. break;
  1762. case 10:
  1763. case 12:
  1764. case 0x87:
  1765. break;
  1766. case 15:
  1767. Instruction->Definition = DbgX86Group15Instructions[RegByte];
  1768. break;
  1769. default:
  1770. assert(FALSE);
  1771. break;
  1772. }
  1773. }
  1774. //
  1775. // Get the structure of the instruction.
  1776. //
  1777. Result = DbgpX86GetInstructionParameters(InstructionStream,
  1778. Instruction,
  1779. &ModRmExists,
  1780. &SibExists,
  1781. &DisplacementSize,
  1782. &ImmediateSize);
  1783. if (Result == FALSE) {
  1784. goto GetInstructionComponentsEnd;
  1785. }
  1786. if (Group != 0) {
  1787. ModRmExists = TRUE;
  1788. }
  1789. //
  1790. // Populate the various pieces of the instruction.
  1791. //
  1792. Instruction->DisplacementSize = DisplacementSize;
  1793. Instruction->ImmediateSize = ImmediateSize;
  1794. if (ModRmExists == TRUE) {
  1795. Instruction->ModRm = *InstructionStream;
  1796. InstructionStream += 1;
  1797. }
  1798. if (SibExists == TRUE) {
  1799. Instruction->Sib = *InstructionStream;
  1800. InstructionStream += 1;
  1801. //
  1802. // Check to see if the SIB byte requires a displacement. EBP is not a
  1803. // valid base, since that can be specified in the Mod bits.
  1804. //
  1805. Base = (Instruction->Sib & X86_BASE_MASK) >> X86_BASE_SHIFT;
  1806. Mod = (Instruction->ModRm & X86_MOD_MASK) >> X86_MOD_SHIFT;
  1807. if (Base == X86RegisterValueEbp) {
  1808. if (Mod == X86ModValueDisplacement8) {
  1809. DisplacementSize = 1;
  1810. } else {
  1811. DisplacementSize = 4;
  1812. }
  1813. }
  1814. }
  1815. //
  1816. // Grab the displacement and immediates from the instruction stream if
  1817. // they're there.
  1818. //
  1819. if (DisplacementSize != 0) {
  1820. memcpy(&(Instruction->Displacement),
  1821. InstructionStream,
  1822. DisplacementSize);
  1823. InstructionStream += DisplacementSize;
  1824. }
  1825. if (ImmediateSize != 0) {
  1826. memcpy(&(Instruction->Immediate), InstructionStream, ImmediateSize);
  1827. InstructionStream += ImmediateSize;
  1828. }
  1829. Instruction->Length = InstructionStream - Beginning;
  1830. //
  1831. // If it's an x87 floating point instruction, decode it now that the
  1832. // ModR/M byte was grabbed.
  1833. //
  1834. if (Group == 0x87) {
  1835. Result = DbgpX86DecodeFloatingPointInstruction(Instruction);
  1836. if (Result == FALSE) {
  1837. goto GetInstructionComponentsEnd;
  1838. }
  1839. }
  1840. GetInstructionComponentsEnd:
  1841. return Result;
  1842. }
  1843. BOOL
  1844. DbgpX86GetInstructionParameters (
  1845. PBYTE InstructionStream,
  1846. PX86_INSTRUCTION Instruction,
  1847. PBOOL ModRmExists,
  1848. PBOOL SibExists,
  1849. PULONG DisplacementSize,
  1850. PULONG ImmediateSize
  1851. )
  1852. /*++
  1853. Routine Description:
  1854. This routine determines the format of the rest of the instruction based on
  1855. the opcode, any prefixes, and possibly the ModRM byte.
  1856. Arguments:
  1857. InstructionStream - Supplies a pointer to the binary instruction stream,
  1858. after the prefixes and opcode.
  1859. Instruction - Supplies a pointer to an instruction. The Prefixes, Opcode,
  1860. and Definition must be filled out.
  1861. ModRmExists - Supplies a pointer where a boolean will be returned
  1862. indicating whether or not a ModRM byte is present.
  1863. SibExists - Supplies a pointer where a boolean will be returned indicating
  1864. whether or not a Scale/Index/Base byte is present in the instruction
  1865. stream.
  1866. DisplacementSize - Supplies a pointer where the size of the Displacement
  1867. value will be returned. 0 indicates there is no displacement in the
  1868. instruction.
  1869. ImmediateSize - Supplies a pointer where the size of the Immediate field
  1870. in the instruction will be returned. 0 indicates there is no Immediate
  1871. field in the instruction.
  1872. Return Value:
  1873. TRUE on success.
  1874. FALSE otherwise.
  1875. --*/
  1876. {
  1877. X86_MOD_VALUE Mod;
  1878. BYTE ModRm;
  1879. ULONG ParseCount;
  1880. BYTE RmValue;
  1881. CHAR Type;
  1882. CHAR Width;
  1883. *ModRmExists = FALSE;
  1884. *SibExists = FALSE;
  1885. *DisplacementSize = 0;
  1886. *ImmediateSize = 0;
  1887. if (Instruction->Definition.Target[0] == '\0') {
  1888. return TRUE;
  1889. }
  1890. Type = Instruction->Definition.Target[0];
  1891. Width = Instruction->Definition.Target[1];
  1892. ParseCount = 0;
  1893. do {
  1894. switch (Type) {
  1895. //
  1896. // A - Direct address. No Mod/RM, Immediate specifies address. No SIB.
  1897. //
  1898. case 'A':
  1899. *ImmediateSize = 4;
  1900. break;
  1901. //
  1902. // C - Control register in ModR/M.
  1903. // D - Debug register in ModR/M.
  1904. // S - Segment register in Reg field of ModR/M.
  1905. // T - Test register in ModR/M.
  1906. // V - SIMD floating point register in ModR/M.
  1907. //
  1908. case 'C':
  1909. case 'D':
  1910. case 'S':
  1911. case 'T':
  1912. case 'V':
  1913. *ModRmExists = TRUE;
  1914. break;
  1915. //
  1916. // E - Mod R/M bytes follows opcode and specifies operand. Operand is
  1917. // either a general register or a memory address. If it is a memory
  1918. // address, the address is computed from a segment register and any of
  1919. // the following values: a base register, an index register, a scaling
  1920. // factor, and a displacement.
  1921. // M - Mod R/M byte may only refer to memory.
  1922. // R - Mod R/M byte may only refer to a general register.
  1923. //
  1924. case 'E':
  1925. case 'M':
  1926. case 'R':
  1927. *ModRmExists = TRUE;
  1928. ModRm = *InstructionStream;
  1929. Mod = (ModRm & X86_MOD_MASK) >> X86_MOD_SHIFT;
  1930. RmValue = (ModRm & X86_RM_MASK) >> X86_RM_SHIFT;
  1931. if (Mod != X86ModValueRegister) {
  1932. //
  1933. // An R/M value of 4 actually indicates an SIB byte is present,
  1934. // not ESP.
  1935. //
  1936. if (RmValue == X86RegisterValueEsp) {
  1937. RmValue = X86RegisterValueScaleIndexBase;
  1938. *SibExists = TRUE;
  1939. }
  1940. //
  1941. // An R/M value of 5 when Mod is 0 means that the address is
  1942. // actually just a 32bit displacment.
  1943. //
  1944. if ((Mod == X86ModValueNoDisplacement) &&
  1945. (RmValue == X86RegisterValueEbp)) {
  1946. RmValue = X86RegisterValueDisplacement32;
  1947. *DisplacementSize = 4;
  1948. }
  1949. }
  1950. //
  1951. // Get any displacements as specified by the MOD bits.
  1952. //
  1953. if (Mod == X86ModValueDisplacement8) {
  1954. *DisplacementSize = 1;
  1955. } else if (Mod == X86ModValueDisplacement32) {
  1956. *DisplacementSize = 4;
  1957. }
  1958. break;
  1959. //
  1960. // F - Flags register. No additional bytes.
  1961. // X - Memory addressed by DS:SI pair.
  1962. // Y - Memory addressed by ES:DI pair.
  1963. // ! - Hardcoded register.
  1964. //
  1965. case 'F':
  1966. case 'X':
  1967. case 'Y':
  1968. case '!':
  1969. break;
  1970. //
  1971. // G - General register specified in Reg field of ModR/M byte.
  1972. //
  1973. case 'G':
  1974. *ModRmExists = TRUE;
  1975. break;
  1976. //
  1977. // I - Immediate data is encoded in subsequent bytes.
  1978. //
  1979. case 'I':
  1980. switch (Width) {
  1981. case X86_WIDTH_BYTE:
  1982. *ImmediateSize = 1;
  1983. break;
  1984. case X86_WIDTH_WORD:
  1985. *ImmediateSize = 2;
  1986. break;
  1987. case X86_WIDTH_LONG:
  1988. *ImmediateSize = 4;
  1989. break;
  1990. case 'v':
  1991. case 'z':
  1992. *ImmediateSize = 4;
  1993. if (Instruction->OperandOverride == TRUE) {
  1994. *ImmediateSize = 2;
  1995. }
  1996. break;
  1997. }
  1998. break;
  1999. //
  2000. // O - Direct Offset. No ModR/M byte, offset of operand is encoded in
  2001. // instruction. No SIB.
  2002. //
  2003. case 'O':
  2004. *ImmediateSize = 4;
  2005. if (Instruction->AddressOverride != FALSE) {
  2006. *ImmediateSize = 2;
  2007. }
  2008. break;
  2009. //
  2010. // J - Instruction contains relative offset.
  2011. //
  2012. case 'J':
  2013. switch (Width) {
  2014. case X86_WIDTH_BYTE:
  2015. *DisplacementSize = 1;
  2016. break;
  2017. case X86_WIDTH_WORD:
  2018. *DisplacementSize = 2;
  2019. break;
  2020. case X86_WIDTH_LONG:
  2021. *DisplacementSize = 4;
  2022. break;
  2023. case 'v':
  2024. case 'z':
  2025. *DisplacementSize = 4;
  2026. if (Instruction->AddressOverride == TRUE) {
  2027. *DisplacementSize = 2;
  2028. }
  2029. break;
  2030. }
  2031. break;
  2032. default:
  2033. return FALSE;
  2034. }
  2035. //
  2036. // Now that the target has been processed, loop again to process the
  2037. // source.
  2038. //
  2039. ParseCount += 1;
  2040. if (Instruction->Definition.Source[0] == '\0') {
  2041. break;
  2042. }
  2043. Type = Instruction->Definition.Source[0];
  2044. Width = Instruction->Definition.Source[1];
  2045. } while (ParseCount < 2);
  2046. //
  2047. // Handle the special instructions that actually have three operands.
  2048. //
  2049. if (Instruction->Opcode == X86_OPCODE1_IMUL1) {
  2050. *ImmediateSize = 4;
  2051. if (Instruction->OperandOverride == TRUE) {
  2052. *ImmediateSize = 2;
  2053. }
  2054. }
  2055. if (Instruction->Opcode == X86_OPCODE1_IMUL2) {
  2056. *ImmediateSize = 1;
  2057. }
  2058. if ((Instruction->Opcode == X86_ESCAPE_OPCODE) &&
  2059. ((Instruction->Opcode2 == X86_OPCODE2_SHLD1) ||
  2060. (Instruction->Opcode2 == X86_OPCODE2_SHRD1))) {
  2061. *ImmediateSize = 1;
  2062. }
  2063. return TRUE;
  2064. }
  2065. PSTR
  2066. DbgpX86GetControlRegister (
  2067. BYTE ModRm
  2068. )
  2069. /*++
  2070. Routine Description:
  2071. This routine reads the REG bits of a ModR/M byte and returns a string
  2072. representing the control register in those bits.
  2073. Arguments:
  2074. ModRm - Supplies the ModR/M byte of the instruction. Only bits 5:3 are used.
  2075. Return Value:
  2076. The control register specifed, in string form.
  2077. --*/
  2078. {
  2079. BYTE RegisterNumber;
  2080. RegisterNumber = (ModRm & X86_REG_MASK) >> X86_REG_SHIFT;
  2081. switch (RegisterNumber) {
  2082. case 0:
  2083. return "cr0";
  2084. break;
  2085. case 2:
  2086. return "cr2";
  2087. break;
  2088. case 3:
  2089. return "cr3";
  2090. break;
  2091. case 4:
  2092. return "cr4";
  2093. break;
  2094. }
  2095. return "ERR";
  2096. }
  2097. PSTR
  2098. DbgpX86GetDebugRegister (
  2099. BYTE ModRm
  2100. )
  2101. /*++
  2102. Routine Description:
  2103. This routine reads the REG bits of a ModR/M byte and returns a string
  2104. representing the debug register in those bits.
  2105. Arguments:
  2106. ModRm - Supplies the ModR/M byte of the instruction. Only bits 5:3 are used.
  2107. Return Value:
  2108. The debug register specifed, in string form.
  2109. --*/
  2110. {
  2111. BYTE RegisterNumber;
  2112. RegisterNumber = (ModRm & X86_REG_MASK) >> X86_REG_SHIFT;
  2113. if (RegisterNumber >= X86_DEBUG_REGISTER_COUNT) {
  2114. return "ERR";
  2115. }
  2116. return DbgX86DebugRegisterNames[RegisterNumber];
  2117. }
  2118. PSTR
  2119. DbgpX86GetSegmentRegister (
  2120. BYTE ModRm
  2121. )
  2122. /*++
  2123. Routine Description:
  2124. This routine reads the REG bits of a ModR/M byte and returns a string
  2125. representing the segment register in those bits.
  2126. Arguments:
  2127. ModRm - Supplies the ModR/M byte of the instruction. Only bits 5:3 are used.
  2128. Return Value:
  2129. The segment register specifed, in string form.
  2130. --*/
  2131. {
  2132. BYTE RegisterNumber;
  2133. RegisterNumber = (ModRm & X86_REG_MASK) >> X86_REG_SHIFT;
  2134. if (RegisterNumber >= X86_SEGMENT_REGISTER_COUNT) {
  2135. return "ER";
  2136. }
  2137. return DbgX86SegmentRegisterNames[RegisterNumber];
  2138. }
  2139. PSTR
  2140. DbgpX86GetGenericRegister (
  2141. X86_REGISTER_VALUE RegisterNumber,
  2142. CHAR Type
  2143. )
  2144. /*++
  2145. Routine Description:
  2146. This routine reads a register number and a width and returns a string
  2147. representing that register. The register number should be in the same format
  2148. as specified in the REG bits of the ModR/M byte.
  2149. Arguments:
  2150. RegisterNumber - Supplies which register to print out, as specified by the
  2151. REG bits of the ModR/M byte.
  2152. Type - Supplies a width or special register format.
  2153. Return Value:
  2154. The register specifed, in string form.
  2155. --*/
  2156. {
  2157. if (RegisterNumber >= X86_REGISTER_NAME_COUNT) {
  2158. return "ERR";
  2159. }
  2160. switch (Type) {
  2161. case X86_WIDTH_BYTE:
  2162. return DbgX86RegisterNames8Bit[RegisterNumber];
  2163. case X86_WIDTH_WORD:
  2164. return DbgX86RegisterNames16Bit[RegisterNumber];
  2165. case X86_WIDTH_LONG:
  2166. return DbgX86RegisterNames32Bit[RegisterNumber];
  2167. case X86_FLOATING_POINT_REGISTER:
  2168. return DbgX87RegisterNames[RegisterNumber];
  2169. default:
  2170. assert(FALSE);
  2171. return "ERR";
  2172. }
  2173. }
  2174. VOID
  2175. DbgpX86GetDisplacement (
  2176. PX86_INSTRUCTION Instruction,
  2177. PSTR Buffer,
  2178. PLONGLONG DisplacementValue
  2179. )
  2180. /*++
  2181. Routine Description:
  2182. This routine prints an address displacement value.
  2183. Arguments:
  2184. Instruction - Supplies a pointer to the instruction containing the
  2185. displacement.
  2186. Buffer - Supplies a pointer to the output buffer the displacement will be
  2187. printed to.
  2188. DisplacementValue - Supplies a pointer to the variable that will receive the
  2189. numerical displacement value. This can be NULL.
  2190. Return Value:
  2191. The instruction displacement field, in string form.
  2192. --*/
  2193. {
  2194. LONG Displacement;
  2195. if ((Buffer == NULL) || (Instruction == NULL)) {
  2196. return;
  2197. }
  2198. strcpy(Buffer, "");
  2199. if (Instruction->Displacement == 0) {
  2200. return;
  2201. }
  2202. switch (Instruction->DisplacementSize) {
  2203. case 1:
  2204. Displacement = (CHAR)Instruction->Displacement;
  2205. break;
  2206. case 2:
  2207. Displacement = (SHORT)Instruction->Displacement;
  2208. break;
  2209. case 4:
  2210. Displacement = (LONG)Instruction->Displacement;
  2211. break;
  2212. default:
  2213. return;
  2214. }
  2215. if (Displacement < 0) {
  2216. sprintf(Buffer, "-0x%x", -Displacement);
  2217. } else {
  2218. sprintf(Buffer, "+0x%x", Displacement);
  2219. }
  2220. if (DisplacementValue != NULL) {
  2221. *DisplacementValue = Displacement;
  2222. }
  2223. }
  2224. PX86_INSTRUCTION_DEFINITION
  2225. DbgpX86GetTwoByteInstruction (
  2226. PX86_INSTRUCTION Instruction
  2227. )
  2228. /*++
  2229. Routine Description:
  2230. This routine finds a two-byte instruction definition corresponding to the
  2231. instruction opcode and prefixes.
  2232. Arguments:
  2233. Instruction - Supplies a pointer to the instruction containing the
  2234. two byte opcode and any prefixes.
  2235. Return Value:
  2236. Returns a pointer to the instruction definition, or NULL if one could not
  2237. be found.
  2238. --*/
  2239. {
  2240. PX86_INSTRUCTION_DEFINITION Definition;
  2241. ULONG InstructionIndex;
  2242. ULONG InstructionLength;
  2243. ULONG PrefixIndex;
  2244. PrefixIndex = 0;
  2245. InstructionLength = sizeof(DbgX86TwoByteInstructions) /
  2246. sizeof(DbgX86TwoByteInstructions[0]);
  2247. //
  2248. // First search through the array looking for a version with the first
  2249. // corresponding prefix.
  2250. //
  2251. while (Instruction->Prefix[PrefixIndex] != 0) {
  2252. InstructionIndex = 0;
  2253. while (InstructionIndex < InstructionLength) {
  2254. if ((DbgX86TwoByteInstructions[InstructionIndex].Prefix ==
  2255. Instruction->Prefix[PrefixIndex]) &&
  2256. (DbgX86TwoByteInstructions[InstructionIndex].Opcode ==
  2257. Instruction->Opcode2)) {
  2258. Definition =
  2259. &(DbgX86TwoByteInstructions[InstructionIndex].Instruction);
  2260. return Definition;
  2261. }
  2262. InstructionIndex += 1;
  2263. }
  2264. PrefixIndex += 1;
  2265. }
  2266. //
  2267. // The search for the specific prefix instruction was not successful, or
  2268. // no prefixes were present. Search for the opcode with a prefix of zero,
  2269. // indicating that the prefix field is not applicable.
  2270. //
  2271. InstructionIndex = 0;
  2272. while (InstructionIndex < InstructionLength) {
  2273. if ((DbgX86TwoByteInstructions[InstructionIndex].Opcode ==
  2274. Instruction->Opcode2) &&
  2275. (DbgX86TwoByteInstructions[InstructionIndex].Prefix == 0)) {
  2276. return &(DbgX86TwoByteInstructions[InstructionIndex].Instruction);
  2277. }
  2278. InstructionIndex += 1;
  2279. }
  2280. //
  2281. // The search yielded no results. Return NULL.
  2282. //
  2283. return NULL;
  2284. }
  2285. BOOL
  2286. DbgpX86DecodeFloatingPointInstruction (
  2287. PX86_INSTRUCTION Instruction
  2288. )
  2289. /*++
  2290. Routine Description:
  2291. This routine decodes the given x87 floating point instruction by
  2292. manipulating the instruction definition.
  2293. Arguments:
  2294. Instruction - Supplies a pointer to the instruction.
  2295. Return Value:
  2296. TRUE on success.
  2297. FALSE if the instruction is invalid. Well, let's be more PC and say that no
  2298. instruction is "invalid", only "executionally challenged".
  2299. --*/
  2300. {
  2301. BYTE Index;
  2302. BYTE Mod;
  2303. BYTE ModRm;
  2304. BYTE Opcode;
  2305. BYTE Opcode2;
  2306. ModRm = Instruction->ModRm;
  2307. Mod = (ModRm & X86_MOD_MASK) >> X86_MOD_SHIFT;
  2308. Opcode = Instruction->Opcode - X87_ESCAPE_OFFSET;
  2309. Opcode2 = (ModRm & X86_REG_MASK) >> X86_REG_SHIFT;
  2310. //
  2311. // Reset the group to 0 so that after this routine tweaks everything it
  2312. // gets treated like a normal instruction.
  2313. //
  2314. Instruction->Definition.Group = 0;
  2315. Instruction->Definition.Mnemonic = NULL;
  2316. //
  2317. // If the ModR/M byte does not specify a register, then use the big
  2318. // table to figure out the mnemonic.
  2319. //
  2320. if (Mod != X86ModValueRegister) {
  2321. Instruction->Definition.Mnemonic = DbgX87Instructions[Opcode][Opcode2];
  2322. if (Instruction->Definition.Mnemonic == NULL) {
  2323. return FALSE;
  2324. }
  2325. return TRUE;
  2326. }
  2327. switch (Opcode) {
  2328. //
  2329. // Handle D8 instructions.
  2330. //
  2331. case 0:
  2332. Instruction->Definition.Mnemonic = DbgX87Instructions[0][Opcode2];
  2333. //
  2334. // The fcom and fcomp instructions take only ST(i). Everything else
  2335. // has two operands, st, and st(i).
  2336. //
  2337. if ((ModRm & X87_FCOM_MASK) == X87_FCOM_OPCODE) {
  2338. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2339. } else {
  2340. Instruction->Definition.Target = X87_ST0_TARGET;
  2341. Instruction->Definition.Source = X87_REGISTER_TARGET;
  2342. }
  2343. break;
  2344. //
  2345. // Handle D9 instructions.
  2346. //
  2347. case 1:
  2348. switch (Opcode2) {
  2349. //
  2350. // C0-C7 is FLD ST(i).
  2351. //
  2352. case 0:
  2353. Instruction->Definition.Mnemonic = X87_FLD_MNEMONIC;
  2354. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2355. break;
  2356. //
  2357. // C8-CF is FXCH ST(i).
  2358. //
  2359. case 1:
  2360. Instruction->Definition.Mnemonic = X87_FXCH_MNEMONIC;
  2361. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2362. break;
  2363. //
  2364. // D0-D7 is just a NOP (really only at D0, but let it slide).
  2365. //
  2366. case 2:
  2367. Instruction->Definition.Mnemonic = X87_NOP_MNEMONIC;
  2368. Instruction->Definition.Target = "";
  2369. break;
  2370. //
  2371. // D8-DF is FSTP1 ST(i).
  2372. //
  2373. case 3:
  2374. Instruction->Definition.Mnemonic = X87_FSTP1_MNEMONIC;
  2375. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2376. break;
  2377. //
  2378. // E0-FF is a grab bag of instructions with no operands.
  2379. //
  2380. default:
  2381. Instruction->Definition.Mnemonic =
  2382. DbgX87D9E0Instructions[ModRm - X87_D9_E0_OFFSET];
  2383. Instruction->Definition.Target = "";
  2384. break;
  2385. }
  2386. break;
  2387. //
  2388. // Handle DA instructions.
  2389. //
  2390. case 2:
  2391. //
  2392. // The fucompp instruction lives off by itself in a wasteland.
  2393. //
  2394. if (ModRm == X87_FUCOMPP_OPCODE) {
  2395. Instruction->Definition.Mnemonic = X87_FUCOMPP_MNEMONIC;
  2396. Instruction->Definition.Target = "";
  2397. } else {
  2398. //
  2399. // There are 8 instructions (4 valid), each of which take the form
  2400. // xxx ST, ST(i). So each instruction takes up 8 bytes.
  2401. //
  2402. Index = (ModRm & X87_DA_C0_MASK) >> X87_DA_CO_SHIFT;
  2403. Instruction->Definition.Mnemonic = DbgX87DAC0Instructions[Index];
  2404. Instruction->Definition.Target = X87_ST0_TARGET;
  2405. Instruction->Definition.Source = X87_REGISTER_TARGET;
  2406. }
  2407. break;
  2408. //
  2409. // Handle DB instructions.
  2410. //
  2411. case 3:
  2412. Index = (ModRm & X87_DB_C0_MASK) >> X87_DB_C0_SHIFT;
  2413. //
  2414. // There's a small rash of inidividual instructions in the E0-E7
  2415. // range.
  2416. //
  2417. if (Index == X87_DB_E0_INDEX) {
  2418. Index = ModRm & X87_DB_E0_MASK;
  2419. Instruction->Definition.Mnemonic = DbgX87DBE0Instructions[Index];
  2420. Instruction->Definition.Target = "";
  2421. //
  2422. // Otherwise there are swaths of instructions that take up 8 bytes
  2423. // each as they take the form xxx ST, ST(i).
  2424. //
  2425. } else {
  2426. Instruction->Definition.Mnemonic = DbgX87DBC0Instructions[Index];
  2427. Instruction->Definition.Target = X87_ST0_TARGET;
  2428. Instruction->Definition.Source = X87_REGISTER_TARGET;
  2429. }
  2430. break;
  2431. //
  2432. // DC is the same as D8, except it handles doubles instead of singles
  2433. // (floats). There's one other annoying detail which is that the FSUB and
  2434. // FSUBR are switched above 0xC0. The same goes for FDIV and FDIVR.
  2435. //
  2436. case 4:
  2437. Instruction->Definition.Mnemonic = DbgX87DCC0Instructions[Opcode2];
  2438. //
  2439. // The fcom and fcomp instructions take only ST(i). Everything else
  2440. // has two operands, st, and st(i).
  2441. //
  2442. if ((ModRm & X87_FCOM_MASK) == X87_FCOM_OPCODE) {
  2443. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2444. } else {
  2445. Instruction->Definition.Target = X87_ST0_TARGET;
  2446. Instruction->Definition.Source = X87_REGISTER_TARGET;
  2447. }
  2448. break;
  2449. //
  2450. // Handle DD instructions.
  2451. //
  2452. case 5:
  2453. Instruction->Definition.Mnemonic = DbgX87DDC0Instructions[Opcode2];
  2454. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2455. break;
  2456. //
  2457. // Handle DE instructions.
  2458. //
  2459. case 6:
  2460. Instruction->Definition.Mnemonic = DbgX87DEC0Instructions[Opcode2];
  2461. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2462. Instruction->Definition.Source = X87_ST0_TARGET;
  2463. break;
  2464. //
  2465. // Handle DF instructions.
  2466. //
  2467. case 7:
  2468. Index = (ModRm & X87_DF_C0_MASK) >> X87_DF_C0_SHIFT;
  2469. //
  2470. // There's a small rash of individual instructions in the E0-E7
  2471. // range. They're pretty old school.
  2472. //
  2473. if (Index == X87_DF_E0_INDEX) {
  2474. Index = ModRm & X87_DF_E0_MASK;
  2475. if (Index < X87_DF_E0_COUNT) {
  2476. Instruction->Definition.Mnemonic =
  2477. DbgX87DFE0Instructions[Index];
  2478. Instruction->Definition.Target = X87_DF_E0_TARGET;
  2479. }
  2480. } else {
  2481. Instruction->Definition.Mnemonic = DbgX87DFC0Instructions[Opcode2];
  2482. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2483. Instruction->Definition.Source = X87_ST0_TARGET;
  2484. }
  2485. break;
  2486. //
  2487. // This function was inappropriately called.
  2488. //
  2489. default:
  2490. assert(FALSE);
  2491. break;
  2492. }
  2493. if (Instruction->Definition.Mnemonic == NULL) {
  2494. return FALSE;
  2495. }
  2496. return TRUE;
  2497. }