1
0

x86dis.c 110 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886
  1. /*++
  2. Copyright (c) 2012 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. x86dis.c
  9. Abstract:
  10. This module contains routines for disassembling x86 binary code.
  11. Author:
  12. Evan Green 21-Jun-2012
  13. Environment:
  14. Debugging client
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/lib/types.h>
  20. #include "disasm.h"
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <assert.h>
  24. //
  25. // --------------------------------------------------------------------- Macros
  26. //
  27. //
  28. // Define macros to get at the pieces of the ModRM byte. This also adds the
  29. // extra bit extended by the REX byte, which if not present is a no-op, as it
  30. // will be zero.
  31. //
  32. #define X86_MODRM_MOD(_ModRm) (((_ModRm) & X86_MOD_MASK) >> X86_MOD_SHIFT)
  33. #define X86_MODRM_REG(_Instruction, _ModRm) \
  34. ((((_ModRm) & X86_REG_MASK) >> X86_REG_SHIFT) | \
  35. (((_Instruction)->Rex & X64_REX_R) << 1))
  36. #define X86_MODRM_RM(_Instruction, _ModRm) \
  37. ((((_ModRm) & X86_RM_MASK) >> X86_RM_SHIFT) | \
  38. (((_Instruction)->Rex & X64_REX_B) << 3))
  39. //
  40. // Define macros to get the fields of the Scale-Index-Base byte, extending
  41. // index and base with the REX bits.
  42. //
  43. #define X86_SIB_BASE(_Instruction) \
  44. ((((_Instruction)->Sib & X86_BASE_MASK) >> X86_BASE_SHIFT) | \
  45. (((_Instruction)->Rex & X64_REX_B) << 3))
  46. #define X86_SIB_INDEX(_Instruction) \
  47. ((((_Instruction)->Sib & X86_INDEX_MASK) >> X86_INDEX_SHIFT) | \
  48. (((_Instruction)->Rex & X64_REX_X) << 2))
  49. #define X86_SIB_SCALE(_Instruction) \
  50. (1 << (((_Instruction)->Sib & X86_SCALE_MASK) >> X86_SCALE_SHIFT))
  51. //
  52. // This macro un-extends a register, just getting the 3-bit value.
  53. //
  54. #define X86_BASIC_REG(_Reg) ((_Reg) & 0x7)
  55. //
  56. // This macro creates a fake REX prefix from a VEX byte.
  57. //
  58. #define X64_VEX_TO_REX(_Vex, _VexMap) \
  59. (X64_REX_VALUE | ((~(_Vex) >> 5) & 0x7) | (((_VexMap) >> 4) & X64_REX_W))
  60. //
  61. // This macro gets the V register out of the VEX byte.
  62. //
  63. #define X64_VEX_V(_Vex) ((~(_Vex) >> 3) & 0x0F)
  64. //
  65. // ---------------------------------------------------------------- Definitions
  66. //
  67. //
  68. // Define the meanings of some of size characters used in the encoding table.
  69. //
  70. #define X86_WIDTH_BYTE 'b'
  71. #define X86_WIDTH_WORD 'w'
  72. #define X86_WIDTH_LONG 'l'
  73. #define X86_WIDTH_LONGLONG 'q'
  74. #define X86_WIDTH_OWORD 'o'
  75. #define X86_WIDTH_YWORD 'y'
  76. #define X86_WIDTH_ZWORD 'z'
  77. #define X86_FLOATING_POINT_REGISTER 'f'
  78. #define X86_CONTROL_REGISTER 'C'
  79. #define X86_DEBUG_REGISTER 'D'
  80. #define X86_SEGMENT_REGISTER 'S'
  81. //
  82. // Define the internal bitfields of the ModR/M and SIB byte.
  83. //
  84. #define X86_MOD_MASK 0xC0
  85. #define X86_REG_MASK 0x38
  86. #define X86_RM_MASK 0x07
  87. #define X86_MOD_SHIFT 6
  88. #define X86_REG_SHIFT 3
  89. #define X86_RM_SHIFT 0
  90. #define X86_SCALE_MASK 0xC0
  91. #define X86_INDEX_MASK 0x38
  92. #define X86_BASE_MASK 0x07
  93. #define X86_SCALE_SHIFT 6
  94. #define X86_INDEX_SHIFT 3
  95. #define X86_BASE_SHIFT 0
  96. //
  97. // Define the X64 REX bits.
  98. //
  99. //
  100. // This bit indicates a 64-bit operand size.
  101. //
  102. #define X64_REX_W 0x08
  103. //
  104. // This bit is an extension to the ModRM reg field.
  105. //
  106. #define X64_REX_R 0x04
  107. //
  108. // This bit is an extension to the SIB index field.
  109. //
  110. #define X64_REX_X 0x02
  111. //
  112. // This bit is an extension to the ModRM rm field, or SIB base field.
  113. //
  114. #define X64_REX_B 0x01
  115. //
  116. // This bit is set to indicate 256 bit registers are in use.
  117. //
  118. #define X64_VEX_L 0x04
  119. //
  120. // This bit is called W/E, and is often the equivalent of the REX W bit.
  121. //
  122. #define X64_VEX_W 0x80
  123. //
  124. // Define some of the prefixes that can come at the beginning of an instruction.
  125. //
  126. #define X86_MAX_PREFIXES 5
  127. #define X86_OPERAND_OVERRIDE 0x66
  128. #define X86_ADDRESS_OVERRIDE 0x67
  129. #define X86_ESCAPE_OPCODE 0x0F
  130. #define X86_PREFIX_LOCK 0xF0
  131. #define X86_PREFIX_REPN 0xF2
  132. #define X86_PREFIX_REP 0xF3
  133. #define X86_PREFIX_CS 0x2E
  134. #define X86_PREFIX_DS 0x3E
  135. #define X86_PREFIX_ES 0x26
  136. #define X86_PREFIX_FS 0x64
  137. #define X86_PREFIX_GS 0x65
  138. #define X86_PREFIX_SS 0x36
  139. #define X64_REX_MASK 0xF0
  140. #define X64_REX_VALUE 0x40
  141. #define X64_XOP 0x8F
  142. #define X64_VEX3 0xC4
  143. #define X64_VEX2 0xC5
  144. #define X64_VEX2_MAP_SELECT 0x61
  145. #define X86_INVALID_GROUP 99
  146. //
  147. // Define the sizes of the register name arrays.
  148. //
  149. #define X86_REGISTER_NAME_COUNT 16
  150. //
  151. // Define the size of the working buffers.
  152. //
  153. #define X86_WORKING_BUFFER_SIZE 100
  154. //
  155. // Define some x87 floating point support definitions, constants used in
  156. // decoding an x87 coprocessor instruction.
  157. //
  158. #define X87_ESCAPE_OFFSET 0xD8
  159. #define X87_FCOM_MASK 0xF8
  160. #define X87_FCOM_OPCODE 0xD0
  161. #define X87_D9_E0_OFFSET 0xE0
  162. #define X87_DA_C0_MASK 0x38
  163. #define X87_DA_CO_SHIFT 3
  164. #define X87_FUCOMPP_OPCODE 0xE9
  165. #define X87_DB_C0_MASK 0x38
  166. #define X87_DB_C0_SHIFT 3
  167. #define X87_DB_E0_INDEX 4
  168. #define X87_DB_E0_MASK 0x7
  169. #define X87_DF_C0_MASK 0x38
  170. #define X87_DF_C0_SHIFT 3
  171. #define X87_DF_E0_INDEX 4
  172. #define X87_DF_E0_MASK 0x07
  173. #define X87_DF_E0_COUNT 3
  174. #define X87_REGISTER_TARGET "Rf"
  175. #define X87_ST0_TARGET "!est"
  176. #define X87_FLD_MNEMONIC "fld"
  177. #define X87_FXCH_MNEMONIC "fxch"
  178. #define X87_NOP_MNEMONIC "fnop"
  179. #define X87_FSTP1_MNEMONIC "fstp1"
  180. #define X87_FUCOMPP_MNEMONIC "fucompp"
  181. #define X87_DF_E0_TARGET "!eax"
  182. //
  183. // ------------------------------------------------------ Data Type Definitions
  184. //
  185. /*++
  186. Structure Description:
  187. This structure provides basic information about an instruction, including
  188. its mnemonic name, operand encodings, and additional parsing information.
  189. Members:
  190. Mnemonic - Stores a pointer to the string containing the opcode's mnemonic.
  191. Target - Stores a pointer to a string describing the destination operand's
  192. encoding.
  193. Source - Stores a pointer to a string describing the source operand's
  194. encoding.
  195. Third - Stores a pointer to a string describing the third operand.
  196. Group - Stores the opcode group number. Some instructions require furthur
  197. decoding, the group number indicates that.
  198. --*/
  199. typedef struct _X86_INSTRUCTION_DEFINITION {
  200. PSTR Mnemonic;
  201. PSTR Target;
  202. PSTR Source;
  203. PSTR Third;
  204. INT Group;
  205. } X86_INSTRUCTION_DEFINITION, *PX86_INSTRUCTION_DEFINITION;
  206. /*++
  207. Structure Description:
  208. This structure provides the mnemonic switch for an opcode group.
  209. Members:
  210. Group - Stores the group number.
  211. Mnemonics - Stores the mnemonics for each opcode in the group.
  212. --*/
  213. typedef struct _X86_OPCODE_GROUP {
  214. INT Group;
  215. PSTR Mnemonics[8];
  216. } X86_OPCODE_GROUP, *PX86_OPCODE_GROUP;
  217. /*++
  218. Structure Description:
  219. This structure stores information about an instructions mnemonics and
  220. encoding when an array index is wasteful for describing the actual opcode
  221. number.
  222. Members:
  223. Prefix - Stores the specfic prefix value for which this instruction is
  224. valid.
  225. Opcode - Stores the opcode this definition defines.
  226. Instruction - Stores an array describing the mnemonics and encoding of the
  227. instruction.
  228. --*/
  229. typedef struct _X86_SPARSE_INSTRUCTION_DEFINITION {
  230. BYTE Prefix;
  231. BYTE Opcode;
  232. X86_INSTRUCTION_DEFINITION Instruction;
  233. } X86_SPARSE_INSTRUCTION_DEFINITION, *PX86_SPARSE_INSTRUCTION_DEFINITION;
  234. /*++
  235. Structure Description:
  236. This structure stores all binary information about a decoded instruction.
  237. Members:
  238. Language - Stores the machine language type being decoded. Valid values are
  239. x86 and x64.
  240. InstructionPointer - Stores the current instruction pointer, used for
  241. computing the operand address of RIP-relative addresses.
  242. Prefix - Stores up to 4 prefix bytes, which is the maximum number of
  243. allowed prefixes in x86 instructions.
  244. Opcode - Stores the first (and many times only) opcode byte.
  245. Opcode2 - Stores the second opcode byte, if necessary (as determined by the
  246. first opcode byte).
  247. ModRm - Stores the ModR/M byte of the instruction, if one exists. Bits 6-7
  248. describe the Mod part of the instruction, which can describe what sort
  249. of addressing/displacement is encoded in the instruction. Bits 5-3 hold
  250. the Reg data, which stores either a register number or additional
  251. decoding information for instruction groups. Bits 2-0 store the R/M
  252. byte, which either stores another register value or describes how the
  253. memory information is encoded.
  254. Sib - Stores the Scale/Index/Base byte of the opcode, if one exists.
  255. Addressing with an sib byte usually looks like (Base + index * 2^Scale),
  256. where Base and Index are both general registers. Bits 6-7 describe the
  257. scale, which is raised to the power of two (and can therefore describe a
  258. scale of 1, 2, 4, or 8). Bits 5-3 describe the index register, and bits
  259. 2-0 describe the base register, both of which are encoded like the Reg
  260. field for general registers.
  261. Rex - Stores the REX byte for 64-bit register extension.
  262. Vex - Stores the VEX byte (the last byte of the VEX prefix) if there is one.
  263. VexMap - Stores the second to last byte of the VEX prefix, which includes
  264. the map select and ~RXB bits. For a two-byte VEX prefix, a specific
  265. value is inferred, which is set here.
  266. Displacement - Stores the displacement of the instruction operand.
  267. Immediate - Stores the immediate value that may or may not be encoded in the
  268. instruction.
  269. Length - Stores the total size of this instruction encoding in bytes.
  270. DisplacementSize - Stores the size in bytes of the displacement value. Once
  271. the Displacement field is populated, this field is not too useful.
  272. ImmediateSize - Stores the size in bytes of the immediate value. Once the
  273. Immediate field is populated, this field is not too useful.
  274. OperandOverride - Stores a flag indicating whether or not the operand
  275. override prefix was on this instruction.
  276. AddressOverrride - Stores a flag indicating whether or not the address
  277. override prefix was specified on this instruction.
  278. Definition - Stores a the instruction decoding information,
  279. including the instruction mnemonic.
  280. Lock - Stores a lock string or an empty string, depending on whether or not
  281. the lock prefix was supplied.
  282. Rep - Stores a rep string or an empty string depending on whether or not
  283. the rep prefix was supplied.
  284. SegmentPrefix - Stores the segment prefix string, or an empty string if
  285. there is no segment prefix.
  286. --*/
  287. typedef struct _X86_INSTRUCTION {
  288. MACHINE_LANGUAGE Language;
  289. ULONGLONG InstructionPointer;
  290. BYTE Prefix[X86_MAX_PREFIXES];
  291. BYTE Opcode;
  292. BYTE Opcode2;
  293. BYTE ModRm;
  294. BYTE Sib;
  295. BYTE Rex;
  296. BYTE Vex;
  297. BYTE VexMap;
  298. ULONGLONG Displacement;
  299. ULONGLONG Immediate;
  300. ULONG Length;
  301. ULONG DisplacementSize;
  302. ULONG ImmediateSize;
  303. BOOL OperandOverride;
  304. BOOL AddressOverride;
  305. X86_INSTRUCTION_DEFINITION Definition;
  306. PCSTR Lock;
  307. PCSTR Rep;
  308. PCSTR SegmentPrefix;
  309. } X86_INSTRUCTION, *PX86_INSTRUCTION;
  310. typedef enum _X86_REGISTER_VALUE {
  311. X86RegisterValueAx,
  312. X86RegisterValueCx,
  313. X86RegisterValueDx,
  314. X86RegisterValueBx,
  315. X86RegisterValueSp,
  316. X86RegisterValueBp,
  317. X86RegisterValueSi,
  318. X86RegisterValueDi,
  319. X86RegisterValueR8,
  320. X86RegisterValueR9,
  321. X86RegisterValueR10,
  322. X86RegisterValueR11,
  323. X86RegisterValueR12,
  324. X86RegisterValueR13,
  325. X86RegisterValueR14,
  326. X86RegisterValueR15,
  327. X86RegisterValueScaleIndexBase,
  328. X86RegisterValueDisplacement32,
  329. X86RegisterValueRipRelative
  330. } X86_REGISTER_VALUE, *PX86_REGISTER_VALUE;
  331. typedef enum _X86_MOD_VALUE {
  332. X86ModValueNoDisplacement,
  333. X86ModValueDisplacement8,
  334. X86ModValueDisplacement32,
  335. X86ModValueRegister
  336. } X86_MOD_VALUE, *PX86_MOD_VALUE;
  337. //
  338. // -------------------------------------------------------------------- Globals
  339. //
  340. //
  341. // Define the x86 instruction encodings. A 6 after the width character of the
  342. // opcode format indicates that the default operand size is 64 bits in long
  343. // mode.
  344. //
  345. X86_INSTRUCTION_DEFINITION DbgX86Instructions[256] = {
  346. {"add", "Eb", "Gb", "", 0}, /* 00 */
  347. {"add", "Ev", "Gv", "", 0}, /* 01 */
  348. {"add", "Gb", "Eb", "", 0}, /* 02 */
  349. {"add", "Gv", "Ev", "", 0}, /* 03 */
  350. {"add", "!bal", "Ib", "", 0}, /* 04 */
  351. {"add", "!r0", "Iz", "", 0}, /* 05 */
  352. {"push", "!wes", "", "", 0}, /* 06 */
  353. {"pop", "!wes", "", "", 0}, /* 07 */
  354. {"or", "Eb", "Gb", "", 0}, /* 08 */
  355. {"or", "Ev", "Gv", "", 0}, /* 09 */
  356. {"or", "Gb", "Eb", "", 0}, /* 0A */
  357. {"or", "Gv", "Ev", "", 0}, /* 0B */
  358. {"or", "!bal", "Ib", "", 0}, /* 0C */
  359. {"or", "!r0", "Iz", "", 0}, /* 0D */
  360. {"push", "!wcs", "", "", 0}, /* 0E */
  361. {"2BYTE", "", "", "", X86_INVALID_GROUP}, /* 0F */ /* Two Byte Opcodes */
  362. {"adc", "Eb", "Gb", "", 0}, /* 10 */
  363. {"adc", "Ev", "Gv", "", 0}, /* 11 */
  364. {"adc", "Gb", "Eb", "", 0}, /* 12 */
  365. {"adc", "Gv", "Ev", "", 0}, /* 13 */
  366. {"adc", "!bal", "Ib", "", 0}, /* 14 */
  367. {"adc", "!r0", "Iz", "", 0}, /* 15 */
  368. {"push", "!wss", "", "", 0}, /* 16 */
  369. {"pop", "!wss", "", "", 0}, /* 17 */
  370. {"sbb", "Eb", "Gb", "", 0}, /* 18 */
  371. {"sbb", "Ev", "Gv", "", 0}, /* 19 */
  372. {"sbb", "Gb", "Eb", "", 0}, /* 1A */
  373. {"sbb", "Gv", "Ev", "", 0}, /* 1B */
  374. {"sbb", "!bal", "Ib", "", 0}, /* 1C */
  375. {"sbb", "!r0", "Iz", "", 0}, /* 1D */
  376. {"push", "!wds", "", "", 0}, /* 1E */
  377. {"pop", "!wds", "", "", 0}, /* 1F */
  378. {"and", "Eb", "Gb", "", 0}, /* 20 */
  379. {"and", "Ev", "Gv", "", 0}, /* 21 */
  380. {"and", "Gb", "Eb", "", 0}, /* 22 */
  381. {"and", "Gv", "Ev", "", 0}, /* 23 */
  382. {"and", "!bal", "Ib", "", 0}, /* 24 */
  383. {"and", "!r0", "Iz", "", 0}, /* 25 */
  384. {"ES:", "", "", "", X86_INVALID_GROUP}, /* 26 */ /* ES prefix */
  385. {"daa", "", "", "", 0}, /* 27 */
  386. {"sub", "Eb", "Gb", "", 0}, /* 28 */
  387. {"sub", "Ev", "Gv", "", 0}, /* 29 */
  388. {"sub", "Gb", "Eb", "", 0}, /* 2A */
  389. {"sub", "Gv", "Ev", "", 0}, /* 2B */
  390. {"sub", "!bal", "Ib", "", 0}, /* 2C */
  391. {"sub", "!r0", "Iz", "", 0}, /* 2D */
  392. {"CS:", "", "", "", X86_INVALID_GROUP}, /* 2E */ /* CS prefix */
  393. {"das", "", "", "", 0}, /* 2F */
  394. {"xor", "Eb", "Gb", "", 0}, /* 30 */
  395. {"xor", "Ev", "Gv", "", 0}, /* 31 */
  396. {"xor", "Gb", "Eb", "", 0}, /* 32 */
  397. {"xor", "Gv", "Ev", "", 0}, /* 33 */
  398. {"xor", "!bal", "Ib", "", 0}, /* 34 */
  399. {"xor", "!r0", "Iz", "", 0}, /* 35 */
  400. {"SS:", "", "", "", X86_INVALID_GROUP}, /* 36 */ /* SS prefix */
  401. {"aaa", "", "", "", 0}, /* 37 */
  402. {"cmp", "Eb", "Gb", "", 0}, /* 38 */
  403. {"cmp", "Ev", "Gv", "", 0}, /* 39 */
  404. {"cmp", "Gb", "Eb", "", 0}, /* 3A */
  405. {"cmp", "Gv", "Ev", "", 0}, /* 3B */
  406. {"cmp", "!bal", "Ib", "", 0}, /* 3C */
  407. {"cmp", "!r0", "Iz", "", 0}, /* 3D */
  408. {"DS:", "", "", "", X86_INVALID_GROUP}, /* 3E */ /* DS prefix */
  409. {"aas", "", "", "", 0}, /* 3F */
  410. {"inc", "!r0", "", "", 0}, /* 40 */
  411. {"inc", "!r1", "", "", 0}, /* 41 */
  412. {"inc", "!r2", "", "", 0}, /* 42 */
  413. {"inc", "!r3", "", "", 0}, /* 43 */
  414. {"inc", "!r4", "", "", 0}, /* 44 */
  415. {"inc", "!r5", "", "", 0}, /* 45 */
  416. {"inc", "!r6", "", "", 0}, /* 46 */
  417. {"inc", "!r7", "", "", 0}, /* 47 */
  418. {"dec", "!r0", "", "", 0}, /* 48 */
  419. {"dec", "!r1", "", "", 0}, /* 49 */
  420. {"dec", "!r2", "", "", 0}, /* 4A */
  421. {"dec", "!r3", "", "", 0}, /* 4B */
  422. {"dec", "!r4", "", "", 0}, /* 4C */
  423. {"dec", "!r5", "", "", 0}, /* 4D */
  424. {"dec", "!r6", "", "", 0}, /* 4E */
  425. {"dec", "!r7", "", "", 0}, /* 4F */
  426. {"push", "!r06", "", "", 0}, /* 50 */
  427. {"push", "!r16", "", "", 0}, /* 51 */
  428. {"push", "!r26", "", "", 0}, /* 52 */
  429. {"push", "!r36", "", "", 0}, /* 53 */
  430. {"push", "!r46", "", "", 0}, /* 54 */
  431. {"push", "!r56", "", "", 0}, /* 55 */
  432. {"push", "!r66", "", "", 0}, /* 56 */
  433. {"push", "!r76", "", "", 0}, /* 57 */
  434. {"pop", "!r06", "", "", 0}, /* 58 */
  435. {"pop", "!r16", "", "", 0}, /* 59 */
  436. {"pop", "!r26", "", "", 0}, /* 5A */
  437. {"pop", "!r36", "", "", 0}, /* 5B */
  438. {"pop", "!r46", "", "", 0}, /* 5C */
  439. {"pop", "!r56", "", "", 0}, /* 5D */
  440. {"pop", "!r66", "", "", 0}, /* 5E */
  441. {"pop", "!r76", "", "", 0}, /* 5F */
  442. {"pushad", "", "", "", 0}, /* 60 */
  443. {"popad", "", "", "", 0}, /* 61 */
  444. {"bound", "Gv", "Ma", "", 0}, /* 62 */
  445. {"movsxd", "Gv", "Ed", "", 0}, /* 63 */ /* Was arpl in 286+ */
  446. {"FS:", "", "", "", X86_INVALID_GROUP}, /* 64 */ /* FS prefix */
  447. {"GS:", "", "", "", X86_INVALID_GROUP}, /* 65 */ /* GS prefix */
  448. {"OPSIZE:", "", "", "", X86_INVALID_GROUP}, /* 66 */ /* Operand override */
  449. {"ADSIZE:", "", "", "", X86_INVALID_GROUP}, /* 67 */ /* Address override */
  450. {"push", "Iz", "", "", 0}, /* 68 */
  451. {"imul", "Gv", "Ev", "Iz", 0}, /* 69 */
  452. {"push", "Ib", "", "", 0}, /* 6A */
  453. {"imul", "Gv", "Ev", "Ib", 0}, /* 6B */
  454. {"ins", "Yb", "!wdx", "", 0}, /* 6C */
  455. {"ins", "Yz", "!wdx", "", 0}, /* 6D */
  456. {"outs", "!wdx", "Xb", "", 0}, /* 6E */
  457. {"outs", "!wdx", "Xz", "", 0}, /* 6F */
  458. {"jo ", "Jb", "", "", 0}, /* 70 */
  459. {"jno", "Jb", "", "", 0}, /* 71 */
  460. {"jb ", "Jb", "", "", 0}, /* 72 */
  461. {"jnb", "Jb", "", "", 0}, /* 73 */
  462. {"jz ", "Jb", "", "", 0}, /* 74 */
  463. {"jnz", "Jb", "", "", 0}, /* 75 */
  464. {"jbe", "Jb", "", "", 0}, /* 76 */
  465. {"jnbe", "Jb", "", "", 0}, /* 77 */
  466. {"js ", "Jb", "", "", 0}, /* 78 */
  467. {"jns", "Jb", "", "", 0}, /* 79 */
  468. {"jp ", "Jb", "", "", 0}, /* 7A */
  469. {"jnp", "Jb", "", "", 0}, /* 7B */
  470. {"jl ", "Jb", "", "", 0}, /* 7C */
  471. {"jnl", "Jb", "", "", 0}, /* 7D */
  472. {"jle", "Jb", "", "", 0}, /* 7E */
  473. {"jnle", "Jb", "", "", 0}, /* 7F */
  474. {"GRP1", "Eb", "Ib", "", 1}, /* 80 */ /* Group 1 opcodes. */
  475. {"GRP1", "Ev", "Iz", "", 1}, /* 81 */ /* Reg of ModR/M */
  476. {"GRP1", "Eb", "Ib", "", 1}, /* 82 */ /* extends opcode.*/
  477. {"GRP1", "Ev", "Ib", "", 1}, /* 83 */
  478. {"test", "Eb", "Gb", "", 0}, /* 84 */
  479. {"test", "Ev", "Gv", "", 0}, /* 85 */
  480. {"xchg", "Eb", "Eb", "", 0}, /* 86 */
  481. {"xchg", "Ev", "Gv", "", 0}, /* 87 */
  482. {"mov", "Eb", "Gb", "", 0}, /* 88 */
  483. {"mov", "Ev", "Gv", "", 0}, /* 89 */
  484. {"mov", "Gb", "Eb", "", 0}, /* 8A */
  485. {"mov", "Gv", "Ev", "", 0}, /* 8B */
  486. {"mov", "Ev", "Sw", "", 0}, /* 8C */
  487. {"lea", "Gv", "M", "", 0}, /* 8D */
  488. {"mov", "Sw", "Ev", "", 0}, /* 8E */
  489. {"pop", "Ev6", "", "", 0}, /* 8F */
  490. {"nop", "", "", "", 0}, /* 90 */
  491. {"xchg", "!r1", "!r0", "", 0}, /* 91 */
  492. {"xchg", "!r2", "!r0", "", 0}, /* 92 */
  493. {"xchg", "!r3", "!r0", "", 0}, /* 93 */
  494. {"xchg", "!r4", "!r0", "", 0}, /* 94 */
  495. {"xchg", "!r5", "!r0", "", 0}, /* 95 */
  496. {"xchg", "!r6", "!r0", "", 0}, /* 96 */
  497. {"xchg", "!r7", "!r0", "", 0}, /* 97 */
  498. {"cwde", "", "", "", 0}, /* 98 */
  499. {"cdq", "", "", "", 0}, /* 99 */
  500. {"call", "Ap", "", "", 0}, /* 9A */
  501. {"fwait", "", "", "", 0}, /* 9B */
  502. {"pushf", "", "", "", 0}, /* 9C */ /* arg1 = Fv */
  503. {"popf", "", "", "", 0}, /* 9D */ /* arg1 = Fv */
  504. {"sahf", "", "", "", 0}, /* 9E */
  505. {"lafh", "", "", "", 0}, /* 9F */
  506. {"mov", "!bal", "Ob", "", 0}, /* A0 */
  507. {"mov", "!r0", "Ov", "", 0}, /* A1 */
  508. {"mov", "Ob", "!bal", "", 0}, /* A2 */
  509. {"mov", "Ov", "!r0", "", 0}, /* A3 */
  510. {"movs", "Yb", "Xb", "", 0}, /* A4 */
  511. {"movs", "Yv", "Xv", "", 0}, /* A5 */
  512. {"cmps", "Yb", "Xb", "", 0}, /* A6 */
  513. {"cmps", "Yv", "Xv", "", 0}, /* A7 */
  514. {"test", "!bal", "Ib", "", 0}, /* A8 */
  515. {"test", "!r0", "Iz", "", 0}, /* A9 */
  516. {"stos", "Yb", "!bal", "", 0}, /* AA */
  517. {"stos", "Yv", "!r0", "", 0}, /* AB */
  518. {"lods", "!bal", "Xb", "", 0}, /* AC */
  519. {"lods", "!r0", "Xv", "", 0}, /* AD */
  520. {"scas", "Yb", "!bal", "", 0}, /* AE */
  521. {"scas", "Yv", "!r0", "", 0}, /* AF */
  522. {"mov", "!b0", "Ib", "", 0}, /* B0 */
  523. {"mov", "!b1", "Ib", "", 0}, /* B1 */
  524. {"mov", "!b2", "Ib", "", 0}, /* B2 */
  525. {"mov", "!b3", "Ib", "", 0}, /* B3 */
  526. {"mov", "!b4", "Ib", "", 0}, /* B4 */
  527. {"mov", "!b5", "Ib", "", 0}, /* B5 */
  528. {"mov", "!b6", "Ib", "", 0}, /* B6 */
  529. {"mov", "!b7", "Ib", "", 0}, /* B7 */
  530. {"mov", "!r0", "Iv", "", 0}, /* B8 */
  531. {"mov", "!r1", "Iv", "", 0}, /* B9 */
  532. {"mov", "!r2", "Iv", "", 0}, /* BA */
  533. {"mov", "!r3", "Iv", "", 0}, /* BB */
  534. {"mov", "!r4", "Iv", "", 0}, /* BC */
  535. {"mov", "!r5", "Iv", "", 0}, /* BD */
  536. {"mov", "!r6", "Iv", "", 0}, /* BE */
  537. {"mov", "!r7", "Iv", "", 0}, /* BF */
  538. {"GRP2", "Eb", "Ib", "", 2}, /* C0 */ /* Group 2 */
  539. {"GRP2", "Ev", "Ib", "", 2}, /* C1 */ /* Group 2 */
  540. {"ret", "Iw", "", "", 0}, /* C2 */
  541. {"ret", "", "", "", 0}, /* C3 */
  542. {"les", "Gz", "Mp", "", 0}, /* C4 */
  543. {"lds", "Gz", "Mp", "", 0}, /* C5 */
  544. {"mov", "Eb", "Ib", "", 11}, /* C6 */ /* Group 11 */
  545. {"mov", "Ev", "Iz", "", 11}, /* C7 */ /* Group 11 */
  546. {"enter", "Iw", "Ib", "", 0}, /* C8 */
  547. {"leave", "", "", "", 0}, /* C9 */
  548. {"retf", "Iw", "", "", 0}, /* CA */
  549. {"retf", "", "", "", 0}, /* CB */
  550. {"int", "!e3", "", "", 0}, /* CC */
  551. {"int", "Ib", "", "", 0}, /* CD */
  552. {"into", "", "", "", 0}, /* CE */
  553. {"iret", "", "", "", 0}, /* CF */
  554. {"GRP2", "Eb", "!e1", "", 2}, /* D0 */ /* Group 2, arg2 = 1 */
  555. {"GRP2", "Ev", "!e1", "", 2}, /* D1 */ /* Group 2, arg2 = 1 */
  556. {"GRP2", "Eb", "!bcl", "", 2}, /* D2 */ /* Group 2 */
  557. {"GRP2", "Ev", "!bcl", "", 2}, /* D3 */ /* Group 2 */
  558. {"aam", "Ib", "", "", 0}, /* D4 */
  559. {"aad", "Ib", "", "", 0}, /* D5 */
  560. {"setalc", "", "", "", 0}, /* D6 */
  561. {"xlat", "", "", "", 0}, /* D7 */
  562. {"ESC0", "Ev", "", "", 0x87}, /* D8 */ /* x87 Floating Pt */
  563. {"ESC1", "Ev", "", "", 0x87}, /* D9 */
  564. {"ESC2", "Ev", "", "", 0x87}, /* DA */
  565. {"ESC3", "Ev", "", "", 0x87}, /* DB */
  566. {"ESC4", "Ev", "", "", 0x87}, /* DC */
  567. {"ESC5", "Ev", "", "", 0x87}, /* DD */
  568. {"ESC6", "Ev", "", "", 0x87}, /* DE */
  569. {"ESC7", "Ev", "", "", 0x87}, /* DF */
  570. {"loopnz", "Jb", "", "", 0}, /* E0 */
  571. {"loopz", "Jb", "", "", 0}, /* E1 */
  572. {"loop", "Jb", "", "", 0}, /* E2 */
  573. {"jcxz", "Jb", "", "", 0}, /* E3 */
  574. {"in ", "!bal", "Ib", "", 0}, /* E4 */
  575. {"in ", "!eeax", "Iv", "", 0}, /* E5 */
  576. {"out", "Ib", "!bal", "", 0}, /* E6 */
  577. {"out", "Ib", "!eeax", "", 0}, /* E7 */
  578. {"call", "Jz6", "", "", 0}, /* E8 */
  579. {"jmp", "Jz6", "", "", 0}, /* E9 */
  580. {"jmp", "Ap", "", "", 0}, /* EA */
  581. {"jmp", "Jb", "", "", 0}, /* EB */
  582. {"in ", "!bal", "!wdx", "", 0}, /* EC */
  583. {"in ", "!eeax", "!wdx", "", 0}, /* ED */
  584. {"out", "!wdx", "!bal", "", 0}, /* EE */
  585. {"out", "!wdx", "!eeax", "", 0}, /* EF */
  586. {"LOCK:", "", "", "", 0}, /* F0 */ /* Lock prefix */
  587. {"int", "!e1", "", "", 0}, /* F1 */ /* Int 1 */
  588. {"REPNE:", "", "", "", 0}, /* F2 */ /* Repne prefix */
  589. {"REP:", "", "", "", 0}, /* F3 */ /* Rep prefix */
  590. {"hlt", "", "", "", 0}, /* F4 */
  591. {"cmc", "", "", "", 0}, /* F5 */
  592. {"GRP3", "Eb", "", "", 3}, /* F6 */ /* Group 3 */
  593. {"GRP3", "Ev", "", "", 3}, /* F7 */ /* Group 3 */
  594. {"clc", "", "", "", 0}, /* F8 */
  595. {"stc", "", "", "", 0}, /* F9 */
  596. {"cli", "", "", "", 0}, /* FA */
  597. {"sti", "", "", "", 0}, /* FB */
  598. {"cld", "", "", "", 0}, /* FC */
  599. {"std", "", "", "", 0}, /* FD */
  600. {"GRP4", "Eb", "", "", 4}, /* FE */ /* Group 4 */
  601. {"GRP5", "Ev", "", "", 5}, /* FF */ /* Group 5 */
  602. };
  603. X86_SPARSE_INSTRUCTION_DEFINITION DbgX86TwoByteInstructions[] = {
  604. {0, 0x0, {"GRP6", "Ev", "", "", 6}}, /* Group 6 */
  605. {0, 0x1, {"GRP7", "Ev", "", "", 7}}, /* Group 7 */
  606. {0, 0x2, {"lar", "Gv", "Ew", "", 0}},
  607. {0, 0x3, {"lsl", "Gv", "Ew", "", 0}},
  608. {0, 0x5, {"syscall", "", "", "", 0}},
  609. {0, 0x6, {"clts", "", "", "", 0}},
  610. {0, 0x7, {"sysret", "", "", "", 0}},
  611. {0, 0x8, {"invd", "", "", "", 0}},
  612. {0, 0x9, {"wbinvd", "", "", "", 0}},
  613. {0, 0xA, {"cl1invmb", "", "", "", 0}},
  614. {0, 0xB, {"ud1", "", "", "", 0}},
  615. {0, 0x10, {"movups", "Vx", "Wx", "", 0}},
  616. {0, 0x11, {"movups", "Wx", "Vx", "", 0}},
  617. {0, 0x12, {"movlps", "Vo", "Ho", "Mo.q", 0}},
  618. {0, 0x13, {"movlps", "Mo.q", "Vo", "", 0}},
  619. {0, 0x14, {"unpcklps", "Vx", "Hx", "Wx", 0}},
  620. {0, 0x15, {"unpckhps", "Vx", "Hx", "Wx", 0}},
  621. {0, 0x16, {"movhps", "Vo", "Ho", "Uo", 0}},
  622. {0, 0x17, {"movhps", "Mo.q", "Vo", "", 0}},
  623. {0, 0x18, {"GRP16", "M", "", "", 16}}, /* Group 16 */
  624. {0, 0x19, {"GRP16", "M", "", "", 16}},
  625. {0, 0x1A, {"GRP16", "M", "", "", 16}},
  626. {0, 0x1B, {"GRP16", "M", "", "", 16}},
  627. {0, 0x1C, {"GRP16", "M", "", "", 16}},
  628. {0, 0x1D, {"GRP16", "M", "", "", 16}},
  629. {0, 0x1E, {"GRP16", "M", "", "", 16}},
  630. {0, 0x1F, {"GRP16", "M", "", "", 16}},
  631. {0x66, 0x10, {"movupd", "Vx", "Wx", "", 0}},
  632. {0x66, 0x11, {"movupd", "Wx", "Vx", "", 0}},
  633. {0x66, 0x12, {"movlpd", "Vo", "Ho", "Mo.q", 0}},
  634. {0x66, 0x13, {"movlpd", "Mo.q", "Vo", "", 0}},
  635. {0x66, 0x14, {"unpcklpd", "Vx", "Hx", "Wx", 0}},
  636. {0x66, 0x15, {"unpckhpd", "Vx", "Hx", "Wx", 0}},
  637. {0x66, 0x16, {"movhpd", "Vo", "Ho", "Mo.q", 0}},
  638. {0x66, 0x17, {"movhpd", "Mo.q", "Vo", "", 0}},
  639. {0x66, 0x18, {"GRP16", "M", "", "", 16}},
  640. {0x66, 0x19, {"GRP16", "M", "", "", 16}},
  641. {0x66, 0x1A, {"GRP16", "M", "", "", 16}},
  642. {0x66, 0x1B, {"GRP16", "M", "", "", 16}},
  643. {0x66, 0x1C, {"GRP16", "M", "", "", 16}},
  644. {0x66, 0x1D, {"GRP16", "M", "", "", 16}},
  645. {0x66, 0x1E, {"GRP16", "M", "", "", 16}},
  646. {0x66, 0x1F, {"GRP16", "M", "", "", 16}},
  647. {0xF3, 0x10, {"movss", "Vo", "Mo.d", "", 0}},
  648. {0xF3, 0x11, {"movss", "Mo.d", "Vo", "", 0}},
  649. {0xF3, 0x12, {"movsldup", "Vx", "Wx", "", 0}},
  650. {0xF3, 0x16, {"movshdup", "Vx", "Wx", "", 0}},
  651. {0xF3, 0x18, {"GRP16", "M", "", "", 16}},
  652. {0xF3, 0x19, {"GRP16", "M", "", "", 16}},
  653. {0xF3, 0x1A, {"GRP16", "M", "", "", 16}},
  654. {0xF3, 0x1B, {"GRP16", "M", "", "", 16}},
  655. {0xF3, 0x1C, {"GRP16", "M", "", "", 16}},
  656. {0xF3, 0x1D, {"GRP16", "M", "", "", 16}},
  657. {0xF3, 0x1E, {"GRP16", "M", "", "", 16}},
  658. {0xF3, 0x1F, {"GRP16", "M", "", "", 16}},
  659. {0xF2, 0x10, {"movsd", "Vo", "Mo.d", "", 0}},
  660. {0xF2, 0x11, {"movsd", "Mo.d", "Vo", "", 0}},
  661. {0xF2, 0x12, {"movddup", "Vx", "Wx", "", 0}},
  662. {0xF2, 0x18, {"GRP16", "M", "", "", 16}},
  663. {0xF2, 0x19, {"GRP16", "M", "", "", 16}},
  664. {0xF2, 0x1A, {"GRP16", "M", "", "", 16}},
  665. {0xF2, 0x1B, {"GRP16", "M", "", "", 16}},
  666. {0xF2, 0x1C, {"GRP16", "M", "", "", 16}},
  667. {0xF2, 0x1D, {"GRP16", "M", "", "", 16}},
  668. {0xF2, 0x1E, {"GRP16", "M", "", "", 16}},
  669. {0xF2, 0x1F, {"GRP16", "M", "", "", 16}},
  670. {0, 0x20, {"mov", "Ry6", "Cy", "", 0}},
  671. {0, 0x21, {"mov", "Ry6", "Dy", "", 0}},
  672. {0, 0x22, {"mov", "Cy", "Ry6", "", 0}},
  673. {0, 0x23, {"mov", "Dy", "Ry6", "", 0}},
  674. {0, 0x24, {"mov", "Ry6", "Ty", "", 0}},
  675. {0, 0x26, {"mov", "Ty", "Ry6", "", 0}},
  676. {0, 0x28, {"movaps", "Vx", "Wx", "", 0}},
  677. {0, 0x29, {"movaps", "Wx", "Vx", "", 0}},
  678. {0, 0x2A, {"cvtpi2ps", "Vo", "Mq", "", 0}},
  679. {0, 0x2B, {"movntps", "Mx", "Vx", "", 0}},
  680. {0, 0x2C, {"cvttps2pi", "Pq", "Wo.q", "", 0}},
  681. {0, 0x2D, {"cvtps2pi", "Pq", "Wo.q", "", 0}},
  682. {0, 0x2E, {"ucomiss", "Vo", "Wo.d", "", 0}},
  683. {0, 0x2F, {"comiss", "Vo", "Wo.d", "", 0}},
  684. {0xF0, 0x20, {"mov", "Rd", "!ecr8", "", 0}},
  685. {0xF0, 0x22, {"mov", "!ecr8", "Rd", "", 0}},
  686. {0x66, 0x28, {"movapd", "Vx", "Wx", "", 0}},
  687. {0x66, 0x29, {"movapd", "Wx", "Vx", "", 0}},
  688. {0x66, 0x2A, {"cvtpi2pd", "Vo", "Mq", "", 0}},
  689. {0x66, 0x2B, {"movntpd", "Mx", "Vx", "", 0}},
  690. {0x66, 0x2C, {"cvttpd2pi", "Pq", "Wo", "", 0}},
  691. {0x66, 0x2D, {"cvtpd2pi", "Pq", "Wo", "", 0}},
  692. {0x66, 0x2E, {"ucomisd", "Vo", "Wo.q", "", 0}},
  693. {0x66, 0x2F, {"comisd", "Vo", "Wo.q", "", 0}},
  694. {0xF3, 0x2A, {"cvtsi2ss", "Vo", "Ho", "Ey", 0}},
  695. {0xF3, 0x2B, {"movntss", "Md", "Vo", "", 0}},
  696. {0xF3, 0x2C, {"cvttss2si", "Gy", "Wo.d", "", 0}},
  697. {0xF3, 0x2D, {"cvtss2si", "Gy", "Wo.d", "", 0}},
  698. {0xF2, 0x2A, {"cvtsi2sd", "Vo", "Ho", "Ey", 0}},
  699. {0xF2, 0x2B, {"movntsd", "Md", "Vo", "", 0}},
  700. {0xF2, 0x2C, {"cvttsd2si", "Gy", "Wo.q", "", 0}},
  701. {0xF2, 0x2D, {"cvtsd2si", "Gy", "Wo.q", "", 0}},
  702. {0, 0x30, {"wrmsr", "", "", "", 0}},
  703. {0, 0x31, {"rdtsc", "", "", "", 0}},
  704. {0, 0x32, {"rdmsr", "", "", "", 0}},
  705. {0, 0x33, {"rdpmc", "", "", "", 0}},
  706. {0, 0x34, {"sysenter", "", "", "", 0}},
  707. {0, 0x35, {"sysexit", "", "", "", 0}},
  708. {0, 0x37, {"getsec", "", "", "", 0}},
  709. {0, 0x40, {"cmovo", "Gv", "Ev", "", 0}},
  710. {0, 0x41, {"cmovno", "Gv", "Ev", "", 0}},
  711. {0, 0x42, {"cmovb", "Gv", "Ev", "", 0}},
  712. {0, 0x43, {"cmovnb", "Gv", "Ev", "", 0}},
  713. {0, 0x44, {"cmovz", "Gv", "Ev", "", 0}},
  714. {0, 0x45, {"cmovnz", "Gv", "Ev", "", 0}},
  715. {0, 0x46, {"cmovbe", "Gv", "Ev", "", 0}},
  716. {0, 0x47, {"cmovnbe", "Gv", "Ev", "", 0}},
  717. {0, 0x48, {"cmovs", "Gv", "Ev", "", 0}},
  718. {0, 0x49, {"cmovns", "Gv", "Ev", "", 0}},
  719. {0, 0x4A, {"cmovp", "Gv", "Ev", "", 0}},
  720. {0, 0x4B, {"cmovnp", "Gv", "Ev", "", 0}},
  721. {0, 0x4C, {"cmovl", "Gv", "Ev", "", 0}},
  722. {0, 0x4D, {"cmovnl", "Gv", "Ev", "", 0}},
  723. {0, 0x4E, {"cmovle", "Gv", "Ev", "", 0}},
  724. {0, 0x4F, {"cmovnle", "Gv", "Ev", "", 0}},
  725. {0, 0x50, {"movmskps", "Gy", "Ux", "", 0}},
  726. {0, 0x51, {"sqrtps", "Vx", "Wx", "", 0}},
  727. {0, 0x52, {"rsqrtps", "Vx", "Wx", "", 0}},
  728. {0, 0x53, {"rcpps", "Vx", "Wx", "", 0}},
  729. {0, 0x54, {"andps", "Vx", "Hx", "Wx", 0}},
  730. {0, 0x55, {"andnps", "Vx", "Hx", "Wx", 0}},
  731. {0, 0x56, {"orps", "Vx", "Hx", "Wx", 0}},
  732. {0, 0x57, {"xorps", "Vx", "Hx", "Wx", 0}},
  733. {0, 0x58, {"addps", "Vx", "Hx", "Wx", 0}},
  734. {0, 0x59, {"mulps", "Vx", "Hx", "Wx", 0}},
  735. {0, 0x5A, {"cvtps2pd", "Vo", "Wo.q", "", 0}},
  736. {0, 0x5B, {"cvtdq2ps", "Vx", "Wx", "", 0}},
  737. {0, 0x5C, {"subps", "Vx", "Hx", "Wx", 0}},
  738. {0, 0x5D, {"minps", "Vx", "Hx", "Wx", 0}},
  739. {0, 0x5E, {"divps", "Vx", "Hx", "Wx", 0}},
  740. {0, 0x5F, {"maxps", "Vx", "Hx", "Wx", 0}},
  741. {0x66, 0x50, {"movmskpd", "Gy", "Ux", "", 0}},
  742. {0x66, 0x51, {"sqrtpd", "Vx", "Wx", "", 0}},
  743. {0x66, 0x54, {"andpd", "Vx", "Hx", "Wx", 0}},
  744. {0x66, 0x55, {"andnpd", "Vx", "Hx", "Wx", 0}},
  745. {0x66, 0x56, {"orpd", "Vx", "Hx", "Wx", 0}},
  746. {0x66, 0x57, {"xorpd", "Vx", "Hx", "Wx", 0}},
  747. {0x66, 0x58, {"addpd", "Vx", "Hx", "Wx", 0}},
  748. {0x66, 0x59, {"mulpd", "Vx", "Hx", "Wx", 0}},
  749. {0x66, 0x5A, {"cvtpd2ps", "Vo", "Wo", "", 0}},
  750. {0x66, 0x5B, {"cvtps2dq", "Vx", "Wx", "", 0}},
  751. {0x66, 0x5C, {"subpd", "Vx", "Hx", "Wx", 0}},
  752. {0x66, 0x5D, {"minpd", "Vx", "Hx", "Wx", 0}},
  753. {0x66, 0x5E, {"divpd", "Vx", "Hx", "Wx", 0}},
  754. {0x66, 0x5F, {"maxpd", "Vx", "Hx", "Wx", 0}},
  755. {0xF3, 0x51, {"sqrtss", "Vo", "Ho", "Wo.d", 0}},
  756. {0xF3, 0x52, {"rsqrtss", "Vo", "Ho", "Wo.d", 0}},
  757. {0xF3, 0x53, {"rcpss", "Vo", "Ho", "Wo.d", 0}},
  758. {0xF3, 0x58, {"addss", "Vo", "Ho", "Wo.d", 0}},
  759. {0xF3, 0x59, {"mulss", "Vo", "Ho", "Wo.d", 0}},
  760. {0xF3, 0x5A, {"cvtss2sd", "Vo", "Ho", "Wo.d", 0}},
  761. {0xF3, 0x5B, {"cvttps2dq", "Vx", "Wx", "", 0}},
  762. {0xF3, 0x5C, {"subss", "Vo", "Ho", "Wo.d", 0}},
  763. {0xF3, 0x5D, {"minss", "Vo", "Ho", "Wo.d", 0}},
  764. {0xF3, 0x5E, {"divss", "Vo", "Ho", "Wo.d", 0}},
  765. {0xF3, 0x5F, {"maxss", "Vo", "Ho", "Wo.d", 0}},
  766. {0xF2, 0x51, {"sqrtsd", "Vo", "Ho", "Wo.q", 0}},
  767. {0xF2, 0x58, {"addsd", "Vo", "Ho", "Wo.q", 0}},
  768. {0xF2, 0x59, {"mulsd", "Vo", "Ho", "Wo.q", 0}},
  769. {0xF2, 0x5A, {"cvtsd2ss", "Vo", "Ho", "Wo.q", 0}},
  770. {0xF2, 0x5C, {"subsd", "Vo", "Ho", "Wo.q", 0}},
  771. {0xF2, 0x5D, {"minsd", "Vo", "Ho", "Wo.q", 0}},
  772. {0xF2, 0x5E, {"divsd", "Vo", "Ho", "Wo.q", 0}},
  773. {0xF2, 0x5F, {"maxsd", "Vo", "Ho", "Wo.q", 0}},
  774. {0, 0x60, {"punpcklbw", "Pq", "Qd", "", 0}},
  775. {0, 0x61, {"punpcklwd", "Pq", "Qd", "", 0}},
  776. {0, 0x62, {"punpckldq", "Pq", "Qd", "", 0}},
  777. {0, 0x63, {"packsswb", "Pq", "Qq", "", 0}},
  778. {0, 0x64, {"pcmpgtb", "Pq", "Qq", "", 0}},
  779. {0, 0x65, {"pcmpgtw", "Pq", "Qq", "", 0}},
  780. {0, 0x66, {"pcmpgtd", "Pq", "Qq", "", 0}},
  781. {0, 0x67, {"packuswb", "Pq", "Qq", "", 0}},
  782. {0, 0x68, {"punpckhbw", "Pq", "Qq", "", 0}},
  783. {0, 0x69, {"punpckhwd", "Pq", "Qq", "", 0}},
  784. {0, 0x6A, {"punpckhdq", "Pq", "Qq", "", 0}},
  785. {0, 0x6B, {"packssdw", "Pq", "Qq", "", 0}},
  786. {0, 0x6E, {"movd", "Pq", "Ey", "", 0}},
  787. {0, 0x6F, {"movq", "Pq", "Qq", "", 0}},
  788. {0x66, 0x60, {"unpcklbw", "Vx", "Hx", "Wx", 0}},
  789. {0x66, 0x61, {"punpcklwd", "Vx", "Hx", "Wx", 0}},
  790. {0x66, 0x62, {"punpckldq", "Vx", "Hx", "Wx", 0}},
  791. {0x66, 0x63, {"packsswb", "Vx", "Hx", "Wx", 0}},
  792. {0x66, 0x64, {"pcmpgtb", "Vx", "Hx", "Wx", 0}},
  793. {0x66, 0x65, {"pcmpgtw", "Vx", "Hx", "Wx", 0}},
  794. {0x66, 0x66, {"pcmpgtd", "Vx", "Hx", "Wx", 0}},
  795. {0x66, 0x67, {"packuswb", "Vx", "Hx", "Wx", 0}},
  796. {0x66, 0x68, {"punpckhbw", "Vx", "Hx", "Wx", 0}},
  797. {0x66, 0x69, {"punpckhwd", "Vx", "Hx", "Wx", 0}},
  798. {0x66, 0x6A, {"punpckhdq", "Vx", "Hx", "Wx", 0}},
  799. {0x66, 0x6B, {"packssdw", "Vx", "Hx", "Wx", 0}},
  800. {0x66, 0x6C, {"punpckl-qdq", "Vx", "Hx", "Wx", 0}},
  801. {0x66, 0x6D, {"punpckh-qdq", "Vx", "Hx", "Wx", 0}},
  802. {0x66, 0x6E, {"movd", "Vo", "Ey", "", 0}},
  803. {0x66, 0x6F, {"movdqa", "Vx", "Wx", "", 0}},
  804. {0xF3, 0x6F, {"movdqu", "Vx", "Wx", "", 0}},
  805. {0, 0x70, {"pshufw", "Pq", "Qq", "Ib", 0}},
  806. {0, 0x71, {"GRP12", "Nb", "Iq", "", 12}},
  807. {0, 0x72, {"GRP13", "Nb", "Iq", "", 13}},
  808. {0, 0x73, {"GRP14", "Nb", "Iq", "", 14}},
  809. {0, 0x74, {"pcmpeqb", "Pq", "Qq", "", 0}},
  810. {0, 0x75, {"pcmpeqw", "Pq", "Qq", "", 0}},
  811. {0, 0x76, {"pcmpeqd", "Pq", "Qq", "", 0}},
  812. {0, 0x77, {"emms", "", "", "", 0}},
  813. {0, 0x78, {"vmread", "Ey", "Gy", "", 0}},
  814. {0, 0x79, {"vmwrite", "Gy", "Ey", "", 0}},
  815. {0, 0x7E, {"movd", "Ey", "Pq", "", 0}},
  816. {0, 0x7F, {"movq", "Qq", "Pq", "", 0}},
  817. {0x66, 0x70, {"pshufd", "Vx", "Wx", "Ib", 0}},
  818. {0x66, 0x71, {"GRP12", "Nb", "Iq", "", 12}},
  819. {0x66, 0x72, {"GRP13", "Nb", "Iq", "", 13}},
  820. {0x66, 0x73, {"GRP14", "Nb", "Iq", "", 14}},
  821. {0x66, 0x74, {"pcmpeqb", "Vx", "Hx", "Wx", 0}},
  822. {0x66, 0x75, {"pcmpeqw", "Vx", "Hx", "Wx", 0}},
  823. {0x66, 0x76, {"pcmpeqd", "Vx", "Hx", "Wx", 0}},
  824. {0x66, 0x7C, {"haddpd", "Vx", "Hx", "Wx", 0}},
  825. {0x66, 0x7D, {"hsubpd", "Vx", "Hx", "Wx", 0}},
  826. {0x66, 0x7E, {"movd", "Ey", "Vo", "", 0}},
  827. {0x66, 0x7F, {"movdqa", "Wx", "Vx", "", 0}},
  828. {0xF3, 0x70, {"pshufhw", "Vx", "Wx", "Ib", 0}},
  829. {0xF3, 0x71, {"GRP12", "Nb", "Iq", "", 12}},
  830. {0xF3, 0x72, {"GRP13", "Nb", "Iq", "", 13}},
  831. {0xF3, 0x73, {"GRP14", "Nb", "Iq", "", 14}},
  832. {0xF3, 0x7E, {"movq", "Vo", "Wo.q", "", 0}},
  833. {0xF3, 0x7F, {"movdqu", "Wx", "Vx", "", 0}},
  834. {0xF2, 0x70, {"pshuflw", "Vx", "Wx", "Ib", 0}},
  835. {0xF2, 0x71, {"GRP12", "Nb", "Iq", "", 12}},
  836. {0xF2, 0x72, {"GRP13", "Nb", "Iq", "", 13}},
  837. {0xF2, 0x73, {"GRP14", "Nb", "Iq", "", 14}},
  838. {0xF2, 0x7C, {"haddps", "Vx", "Hx", "Wx", 0}},
  839. {0xF2, 0x7D, {"hsubps", "Vx", "Hx", "Wx", 0}},
  840. {0, 0x80, {"jo ", "Jz", "", "", 0}},
  841. {0, 0x81, {"jno", "Jz", "", "", 0}},
  842. {0, 0x82, {"jb ", "Jz", "", "", 0}},
  843. {0, 0x83, {"jnb", "Jz", "", "", 0}},
  844. {0, 0x84, {"jz ", "Jz", "", "", 0}},
  845. {0, 0x85, {"jnz", "Jz", "", "", 0}},
  846. {0, 0x86, {"jbe", "Jz", "", "", 0}},
  847. {0, 0x87, {"jnbe", "Jz", "", "", 0}},
  848. {0, 0x88, {"js ", "Jz", "", "", 0}},
  849. {0, 0x89, {"jns", "Jz", "", "", 0}},
  850. {0, 0x8A, {"jp", "Jz", "", "", 0}},
  851. {0, 0x8B, {"jnp", "Jz", "", "", 0}},
  852. {0, 0x8C, {"jl ", "Jz", "", "", 0}},
  853. {0, 0x8D, {"jnl", "Jz", "", "", 0}},
  854. {0, 0x8E, {"jle", "Jz", "", "", 0}},
  855. {0, 0x8F, {"jnle", "Jz", "", "", 0}},
  856. {0, 0x90, {"seto", "Eb", "", "", 0}},
  857. {0, 0x91, {"setno", "Eb", "", "", 0}},
  858. {0, 0x92, {"setb", "Eb", "", "", 0}},
  859. {0, 0x93, {"setnb", "Eb", "", "", 0}},
  860. {0, 0x94, {"setz", "Eb", "", "", 0}},
  861. {0, 0x95, {"setnz", "Eb", "", "", 0}},
  862. {0, 0x96, {"setbe", "Eb", "", "", 0}},
  863. {0, 0x97, {"setnbe", "Eb", "", "", 0}},
  864. {0, 0x98, {"sets", "Eb", "", "", 0}},
  865. {0, 0x99, {"setns", "Eb", "", "", 0}},
  866. {0, 0x9A, {"setp", "Eb", "", "", 0}},
  867. {0, 0x9B, {"setnp", "Eb", "", "", 0}},
  868. {0, 0x9C, {"setl", "Eb", "", "", 0}},
  869. {0, 0x9D, {"setnl", "Eb", "", "", 0}},
  870. {0, 0x9E, {"setle", "Eb", "", "", 0}},
  871. {0, 0x9F, {"setnle", "Eb", "", "", 0}},
  872. {0, 0xA0, {"push", "!wfs", "", "", 0}},
  873. {0, 0xA1, {"pop", "!wfs", "", "", 0}},
  874. {0, 0xA2, {"cpuid", "", "", "", 0}},
  875. {0, 0xA3, {"bt ", "Ev", "Gv", "", 0}},
  876. {0, 0xA4, {"shld", "Ev", "Gv", "Ib", 0}},
  877. {0, 0xA5, {"shld", "Ev", "Gv", "!b1", 0}},
  878. {0, 0xA6, {"cmpxchg", "", "", "", 0}},
  879. {0, 0xA7, {"cmpxchg", "", "", "", 0}},
  880. {0, 0xA8, {"push", "!wgs", "", "", 0}},
  881. {0, 0xA9, {"pop", "!gs", "", "", 0}},
  882. {0, 0xAA, {"rsm", "", "", "", 0}},
  883. {0, 0xAB, {"bts", "Ev", "Gv", "", 0}},
  884. {0, 0xAC, {"shrd", "Ev", "Gv", "Ib", 0}},
  885. {0, 0xAD, {"shrd", "Ev", "Gv", "!b1", 0}},
  886. {0, 0xAE, {"GRP15", "M", "", "", 15}}, /* Group 15 */
  887. {0, 0xAF, {"imul", "Gv", "Ev", "", 0}},
  888. {0xF3, 0xAE, {"GRP15A", "Ry", "", "", 0x15A}}, /* Group 15A */
  889. {0, 0xB0, {"cmpxchg", "Eb", "Gb", "", 0}},
  890. {0, 0xB1, {"cmpxchg", "Ev", "Gv", "", 0}},
  891. {0, 0xB2, {"lss", "Gz", "Mp", "", 0}},
  892. {0, 0xB3, {"btr", "Ev", "Gv", "", 0}},
  893. {0, 0xB4, {"lfs", "Gz", "Mp", "", 0}},
  894. {0, 0xB5, {"lgs", "Gz", "Mp", "", 0}},
  895. {0, 0xB6, {"movzx", "Gv", "Eb", "", 0}},
  896. {0, 0xB7, {"movxz", "Gv", "Ew", "", 0}},
  897. {0, 0xB8, {"jmpe", "Jz", "", "", 0}},
  898. {0, 0xB9, {"ud2", "", "", "", 0}}, /* Group 10 */
  899. {0, 0xBA, {"GRP8", "Ev", "Ib", "", 8}}, /* Group 8 */
  900. {0, 0xBB, {"btc", "Ev", "Gv", "", 0}},
  901. {0, 0xBC, {"bsf", "Gv", "Ev", "", 0}},
  902. {0, 0xBD, {"bsr", "Gv", "Ev", "", 0}},
  903. {0, 0xBE, {"movsx", "Gv", "Eb", "", 0}},
  904. {0, 0xBF, {"movsx", "Gv", "Ew", "", 0}},
  905. {0xF3, 0xB8, {"popcnt", "Gv", "Ev", "", 0}},
  906. {0xF3, 0xBD, {"lzcnt", "Gv", "Ev", "", 0}},
  907. {0, 0xC0, {"xadd", "Eb", "Gb", "", 0}},
  908. {0, 0xC1, {"xadd", "Ev", "Gv", "", 0}},
  909. {0, 0xC2, {"cmpccps", "Vx", "Hx", "Wx", 0}},/* Also has Ib */
  910. {0, 0xC3, {"movnti", "My", "Gy", "", 0}},
  911. {0, 0xC4, {"pinsrw", "Pq", "Mw", "Ib", 0}},
  912. {0, 0xC5, {"pextrw", "Gy", "Nq", "Ib", 0}},
  913. {0, 0xC6, {"shufps", "Vx", "Hx", "Wx", 0}}, /* Also has Ib */
  914. {0, 0xC7, {"GRP9", "M", "", "", 9}}, /* Group 9 */
  915. {0, 0xC8, {"bswap", "!r0", "", "", 0}},
  916. {0, 0xC9, {"bswap", "!r1", "", "", 0}},
  917. {0, 0xCA, {"bswap", "!r2", "", "", 0}},
  918. {0, 0xCB, {"bswap", "!r3", "", "", 0}},
  919. {0, 0xCC, {"bswap", "!r4", "", "", 0}},
  920. {0, 0xCD, {"bswap", "!r5", "", "", 0}},
  921. {0, 0xCE, {"bswap", "!r6", "", "", 0}},
  922. {0, 0xCF, {"bswap", "!r7", "", "", 0}},
  923. {0x66, 0xC0, {"xadd", "Eb", "Gb", "", 0}},
  924. {0x66, 0xC1, {"xadd", "Ev", "Gv", "", 0}},
  925. {0x66, 0xC2, {"cmpccpd", "Vx", "Hx", "Wx", 0}}, /* Also has Ib */
  926. {0x66, 0xC4, {"pinsrw", "Vo", "Ho", "Mw", 0}}, /* Also has Ib */
  927. {0x66, 0xC5, {"pextrw", "Gy", "Uo", "Ib", 0}},
  928. {0x66, 0xC6, {"shufpd", "Vx", "Hx", "Wx", 0}}, /* Also has Ib */
  929. {0x66, 0xC7, {"GRP9", "M", "", "", 9}}, /* Group 9 */
  930. {0xF3, 0xC0, {"xadd", "Eb", "Gb", "", 0}},
  931. {0xF3, 0xC1, {"xadd", "Ev", "Gv", "", 0}},
  932. {0xF3, 0xC2, {"cmpccss", "Vo", "Ho", "Wo.d", 0}}, /* Also has Ib */
  933. {0xF3, 0xC7, {"GRP9", "M", "", "", 9}}, /* Group 9 */
  934. {0xF2, 0xC0, {"xadd", "Eb", "Gb", "", 0}},
  935. {0xF2, 0xC1, {"xadd", "Ev", "Gv", "", 0}},
  936. {0xF2, 0xC2, {"cmpccss", "Vo", "Ho", "Wo.d", 0}}, /* Also has Ib */
  937. {0xF2, 0xC7, {"GRP9", "M", "", "", 9}}, /* Group 9 */
  938. {0, 0xD1, {"psrlw", "Pq", "Qq", "", 0}},
  939. {0, 0xD2, {"psrld", "Pq", "Qq", "", 0}},
  940. {0, 0xD3, {"psrlq", "Pq", "Qq", "", 0}},
  941. {0, 0xD4, {"paddq", "Pq", "Qq", "", 0}},
  942. {0, 0xD5, {"pmullw", "Pq", "Qq", "", 0}},
  943. {0, 0xD7, {"pmovmskb", "Gy", "Nq", "", 0}},
  944. {0, 0xD8, {"psubusb", "Pq", "Qq", "", 0}},
  945. {0, 0xD9, {"psubusw", "Pq", "Qq", "", 0}},
  946. {0, 0xDA, {"pminub", "Pq", "Qq", "", 0}},
  947. {0, 0xDB, {"pand", "Pq", "Qq", "", 0}},
  948. {0, 0xDC, {"paddusb", "Pq", "Qq", "", 0}},
  949. {0, 0xDD, {"paddusw", "Pq", "Qq", "", 0}},
  950. {0, 0xDE, {"pmaxub", "Pq", "Qq", "", 0}},
  951. {0, 0xDF, {"pandn", "Pq", "Qq", "", 0}},
  952. {0x66, 0xD0, {"addsubpd", "Vx", "Hx", "Wx", 0}},
  953. {0x66, 0xD1, {"psrlw", "Vx", "Hx", "Wx", 0}},
  954. {0x66, 0xD2, {"psrld", "Vx", "Hx", "Wx", 0}},
  955. {0x66, 0xD3, {"psrlq", "Vx", "Hx", "Wx", 0}},
  956. {0x66, 0xD4, {"paddq", "Vx", "Hx", "Wx", 0}},
  957. {0x66, 0xD5, {"pmullw", "Vx", "Hx", "Wx", 0}},
  958. {0x66, 0xD6, {"pmovq", "Wo.q", "Vo", "", 0}},
  959. {0x66, 0xD7, {"pmovmskb", "Gy", "Ux", "", 0}},
  960. {0x66, 0xD8, {"psubusb", "Vx", "Hx", "Wx", 0}},
  961. {0x66, 0xD9, {"psubusw", "Vx", "Hx", "Wx", 0}},
  962. {0x66, 0xDA, {"pminub", "Vx", "Hx", "Wx", 0}},
  963. {0x66, 0xDB, {"pand", "Vx", "Hx", "Wx", 0}},
  964. {0x66, 0xDC, {"paddusb", "Vx", "Hx", "Wx", 0}},
  965. {0x66, 0xDD, {"paddusw", "Vx", "Hx", "Wx", 0}},
  966. {0x66, 0xDE, {"pmaxub", "Vx", "Hx", "Wx", 0}},
  967. {0x66, 0xDF, {"pandn", "Vx", "Hx", "Wx", 0}},
  968. {0xF3, 0xD6, {"movq2dq", "Vo", "Nq", "", 0}},
  969. {0xF2, 0xD0, {"addsubps", "Vx", "Hx", "Wx", 0}},
  970. {0xF2, 0xD6, {"movdq2q", "Pq", "Uq", "", 0}},
  971. {0, 0xE0, {"pavgb", "Pq", "Qq", "", 0}},
  972. {0, 0xE1, {"psraw", "Pq", "Qq", "", 0}},
  973. {0, 0xE2, {"psrad", "Pq", "Qq", "", 0}},
  974. {0, 0xE3, {"pavgw", "Pq", "Qq", "", 0}},
  975. {0, 0xE4, {"pmulhuw", "Pq", "Qq", "", 0}},
  976. {0, 0xE5, {"pmulhw", "Pq", "Qq", "", 0}},
  977. {0, 0xE7, {"movntq", "Mq", "Pq", "", 0}},
  978. {0, 0xE8, {"psubsb", "Pq", "Qq", "", 0}},
  979. {0, 0xE9, {"psubsw", "Pq", "Qq", "", 0}},
  980. {0, 0xEA, {"pminsw", "Pq", "Qq", "", 0}},
  981. {0, 0xEB, {"por", "Pq", "Qq", "", 0}},
  982. {0, 0xEC, {"paddsb", "Pq", "Qq", "", 0}},
  983. {0, 0xED, {"paddsw", "Pq", "Qq", "", 0}},
  984. {0, 0xEE, {"pmaxsw", "Mq", "Pq", "", 0}},
  985. {0, 0xEF, {"pxor", "Mq", "Pq", "", 0}},
  986. {0x66, 0xE0, {"pavgb", "Vx", "Hx", "Wx", 0}},
  987. {0x66, 0xE1, {"psraw", "Vx", "Hx", "Wx", 0}},
  988. {0x66, 0xE2, {"psrad", "Vx", "Hx", "Wx", 0}},
  989. {0x66, 0xE3, {"pavgw", "Vx", "Hx", "Wx", 0}},
  990. {0x66, 0xE4, {"pmulhuw", "Vx", "Hx", "Wx", 0}},
  991. {0x66, 0xE5, {"pmulhw", "Vx", "Hx", "Wx", 0}},
  992. {0x66, 0xE6, {"cvttpd2dq", "Vo", "Wx", "", 0}},
  993. {0x66, 0xE7, {"movntdq", "Mx", "Vx", "", 0}},
  994. {0x66, 0xE8, {"psubsb", "Vx", "Hx", "Wx", 0}},
  995. {0x66, 0xE9, {"psubsw", "Vx", "Hx", "Wx", 0}},
  996. {0x66, 0xEA, {"pminsw", "Vx", "Hx", "Wx", 0}},
  997. {0x66, 0xEB, {"por", "Vx", "Hx", "Wx", 0}},
  998. {0x66, 0xEC, {"paddsb", "Vx", "Hx", "Wx", 0}},
  999. {0x66, 0xED, {"paddsw", "Vx", "Hx", "Wx", 0}},
  1000. {0x66, 0xEE, {"pmaxsw", "Vx", "Hx", "Wx", 0}},
  1001. {0x66, 0xEF, {"pxor", "Vx", "Hx", "Wx", 0}},
  1002. {0xF3, 0xE6, {"cvtdq2pd", "Vo", "Wo.q", "", 0}},
  1003. {0xF2, 0xE6, {"cvtpd2dq", "Vo", "Wx", "", 0}},
  1004. {0, 0xF1, {"psllw", "Pq", "Qq", "", 0}},
  1005. {0, 0xF2, {"pslld", "Pq", "Qq", "", 0}},
  1006. {0, 0xF3, {"psllq", "Pq", "Qq", "", 0}},
  1007. {0, 0xF4, {"pmuludq", "Pq", "Qq", "", 0}},
  1008. {0, 0xF5, {"pmaddwd", "Pq", "Qq", "", 0}},
  1009. {0, 0xF6, {"psadbw", "Pq", "Qq", "", 0}},
  1010. {0, 0xF7, {"maskmovq", "Pq", "Nq", "", 0}},
  1011. {0, 0xF8, {"psubb", "Pq", "Qq", "", 0}},
  1012. {0, 0xF9, {"psubw", "Pq", "Qq", "", 0}},
  1013. {0, 0xFA, {"psubd", "Pq", "Qq", "", 0}},
  1014. {0, 0xFB, {"psubq", "Pq", "Qq", "", 0}},
  1015. {0, 0xFC, {"paddb", "Pq", "Qq", "", 0}},
  1016. {0, 0xFD, {"paddw", "Pq", "Qq", "", 0}},
  1017. {0, 0xFE, {"paddd", "Pq", "Qq", "", 0}},
  1018. {0, 0xFF, {"ud", "", "", "", 0}},
  1019. {0x66, 0xF1, {"psllw", "Vx", "Hx", "Wx", 0}},
  1020. {0x66, 0xF2, {"pslld", "Vx", "Hx", "Wx", 0}},
  1021. {0x66, 0xF3, {"psllq", "Vx", "Hx", "Wx", 0}},
  1022. {0x66, 0xF4, {"pmuludq", "Vx", "Hx", "Wx", 0}},
  1023. {0x66, 0xF5, {"pmaddwd", "Vx", "Hx", "Wx", 0}},
  1024. {0x66, 0xF6, {"psadbw", "Vx", "Hx", "Wx", 0}},
  1025. {0x66, 0xF7, {"maskmovdqq", "Vo", "Uo", "", 0}},
  1026. {0x66, 0xF8, {"psubb", "Vx", "Hx", "Wx", 0}},
  1027. {0x66, 0xF9, {"psubw", "Vx", "Hx", "Wx", 0}},
  1028. {0x66, 0xFA, {"psubd", "Vx", "Hx", "Wx", 0}},
  1029. {0x66, 0xFB, {"psubq", "Vx", "Hx", "Wx", 0}},
  1030. {0x66, 0xFC, {"paddb", "Vx", "Hx", "Wx", 0}},
  1031. {0x66, 0xFD, {"paddw", "Vx", "Hx", "Wx", 0}},
  1032. {0x66, 0xFE, {"paddd", "Vx", "Hx", "Wx", 0}},
  1033. {0x66, 0xFF, {"ud", "", "", "", 0}},
  1034. {0xF2, 0xF0, {"lddqu", "Vx", "Mx", "", 0}},
  1035. {0, 0x0, {"", "", "", "", 0}},
  1036. };
  1037. //
  1038. // Define the opcode groups, terminated by group zero.
  1039. //
  1040. X86_OPCODE_GROUP DbgX86OpcodeGroups[] = {
  1041. {1, {"add", "or ", "adc", "sbb", "and", "sub", "xor", "cmp"}},
  1042. {2, {"rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar"}},
  1043. {3, {"test", "test", "not", "neg", "mul", "imul", "div", "idiv"}},
  1044. {4, {"inc", "dec", "(bad)", "(bad)", "(bad)", "(bad)", "(bad)", "(bad)"}},
  1045. {5, {"inc", "dec", "call", "call", "jmp", "jmp", "push", "(bad)"}},
  1046. {6, {"sldt", "str", "lldt", "ltr", "verr", "verw", "jmpe", "(bad)"}},
  1047. {7, {"sgdt", "sidt", "lgdt", "lidt", "smsw", "rstorssp", "lmsw", "invlpg"}},
  1048. {8, {"(bad)", "(bad)", "(bad)", "(bad)", "bt", "bts", "btr", "btc"}},
  1049. {9, {"(bad)", "cmpxchg8b", "xrstors", "xsavec",
  1050. "xsaves", "(bad)", "vmptrld", "vmptrst"}},
  1051. {10, {"ud2", "ud2", "ud2", "ud2", "ud2", "ud2", "ud2", "ud2"}},
  1052. {11, {"mov", "(bad)", "(bad)", "(bad)",
  1053. "(bad)", "(bad)", "(bad)", "xabort"}},
  1054. {12, {"(bad)", "(bad)", "psrlw", "(bad)",
  1055. "psraw", "(bad)", "psllw", "(bad)"}},
  1056. {13, {"(bad)", "(bad)", "psrld", "(bad)",
  1057. "psrad", "(bad)", "pslld", "(bad)"}},
  1058. {14, {"(bad)", "(bad)", "psrlq", "psrldq",
  1059. "(bad)", "(bad)", "psllq", "pslldq"}},
  1060. {15, {"fxsave", "fxrstor", "ldmxcsr", "stmxcsr",
  1061. "xsave", "xrstor", "xsaveopt", "clflush"}},
  1062. {0x15A, {"rdfsbase", "rdgsbase", "wrfsbase", "wrgsbase",
  1063. "ptwrite", "(bad)", "(bad)", "(bad)"}},
  1064. {16, {"prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2",
  1065. "hint", "hint", "hint", "hint"}},
  1066. {17, {"(bad)", "blsr", "blsmsk", "blsi",
  1067. "(bad)", "(bad)", "(bad)", "(bad)"}},
  1068. {0}
  1069. };
  1070. X86_SPARSE_INSTRUCTION_DEFINITION DbgX860F01Alternates[] = {
  1071. {0, 0xC1, {"vmcall", "", "", "", 0}},
  1072. {0, 0xC2, {"vmlaunch", "", "", "", 0}},
  1073. {0, 0xC3, {"vmresume", "", "", "", 0}},
  1074. {0, 0xC4, {"vmxoff", "", "", "", 0}},
  1075. {0, 0xC8, {"monitor", "", "", "", 0}},
  1076. {0, 0xC9, {"mwait", "", "", "", 0}},
  1077. {0, 0xCA, {"clac", "", "", "", 0}},
  1078. {0, 0xCB, {"stac", "", "", "", 0}},
  1079. {0, 0xCF, {"encls", "", "", "", 0}},
  1080. {0, 0xD0, {"xgetbv", "", "", "", 0}},
  1081. {0, 0xD1, {"xsetbv", "", "", "", 0}},
  1082. {0, 0xD4, {"vmfunc", "", "", "", 0}},
  1083. {0, 0xD5, {"xend", "", "", "", 0}},
  1084. {0, 0xD6, {"xtest", "", "", "", 0}},
  1085. {0, 0xD7, {"enclu", "", "", "", 0}},
  1086. {0, 0xD8, {"vmrun", "", "", "", 0}},
  1087. {0, 0xD9, {"vmmcall", "", "", "", 0}},
  1088. {0, 0xDA, {"vmload", "", "", "", 0}},
  1089. {0, 0xDB, {"vmsave", "", "", "", 0}},
  1090. {0, 0xDC, {"stgi", "", "", "", 0}},
  1091. {0, 0xDD, {"clgi", "", "", "", 0}},
  1092. {0, 0xDE, {"skinit", "", "", "", 0}},
  1093. {0, 0xDF, {"invlpga", "", "", "", 0}},
  1094. {0, 0xEE, {"rdpkru", "", "", "", 0}},
  1095. {0, 0xEF, {"wrpkru", "", "", "", 0}},
  1096. {0, 0xF8, {"swapgs", "", "", "", 0}},
  1097. {0, 0xF9, {"rdtscp", "", "", "", 0}},
  1098. {0, 0xFA, {"monitorx", "", "", "", 0}},
  1099. {0, 0xFB, {"mwaitx", "", "", "", 0}},
  1100. {0, 0xFC, {"clzero", "", "", "", 0}},
  1101. };
  1102. //
  1103. // Define the various x87 floating point mnemonics. The first index is the
  1104. // first opcode (offset from 0xD8), and the second index is the reg2 portion
  1105. // of the ModR/M byte. These are only valid if the mod portion of ModR/M
  1106. // does not specify a register. If it specifies a register, then there are
  1107. // different arrays used for decoding.
  1108. //
  1109. PSTR DbgX87Instructions[8][8] = {
  1110. {
  1111. "fadd",
  1112. "fmul",
  1113. "fcom",
  1114. "fcomp",
  1115. "fsub",
  1116. "fsubr",
  1117. "fdiv",
  1118. "fdivr"
  1119. },
  1120. {
  1121. "fld",
  1122. NULL,
  1123. "fst",
  1124. "fstp",
  1125. "fldenv",
  1126. "fldcw",
  1127. "fstenv",
  1128. "fstcw"
  1129. },
  1130. {
  1131. "fiadd",
  1132. "fimul",
  1133. "ficom",
  1134. "ficomp",
  1135. "fisub",
  1136. "fisubr",
  1137. "fidiv",
  1138. "fidivr"
  1139. },
  1140. {
  1141. "fild",
  1142. "fisttp",
  1143. "fist",
  1144. "fistp",
  1145. NULL,
  1146. "fld",
  1147. NULL,
  1148. "fstp"
  1149. },
  1150. {
  1151. "fadd",
  1152. "fmul",
  1153. "fcom",
  1154. "fcomp",
  1155. "fsub",
  1156. "fsubr",
  1157. "fdiv",
  1158. "fdivr"
  1159. },
  1160. {
  1161. "fld",
  1162. "fisttp",
  1163. "fst",
  1164. "fstp",
  1165. "frstor",
  1166. NULL,
  1167. "fsave",
  1168. "fstsw"
  1169. },
  1170. {
  1171. "fiadd",
  1172. "fimul",
  1173. "ficom",
  1174. "ficomp",
  1175. "fisub",
  1176. "fisubr",
  1177. "fidiv",
  1178. "fidivr"
  1179. },
  1180. {
  1181. "fild",
  1182. "fisttp",
  1183. "fist",
  1184. "fistp",
  1185. "fbld",
  1186. "fild",
  1187. "fbstp",
  1188. "fistp"
  1189. }
  1190. };
  1191. PSTR DbgX87D9E0Instructions[32] = {
  1192. "fchs",
  1193. "fabs",
  1194. NULL,
  1195. NULL,
  1196. "ftst",
  1197. "fxam",
  1198. "ftstp",
  1199. NULL,
  1200. "fld1",
  1201. "fldl2t",
  1202. "fldl2e",
  1203. "fldpi",
  1204. "fldlg2",
  1205. "fldln2",
  1206. "fldz",
  1207. NULL,
  1208. "f2xm1",
  1209. "fyl2x",
  1210. "fptan",
  1211. "fpatan",
  1212. "fxtract",
  1213. "fprem1",
  1214. "fdecstp",
  1215. "fincstp",
  1216. "fprem",
  1217. "fyl2xp1",
  1218. "fsqrt",
  1219. "fsincos",
  1220. "frndint",
  1221. "fscale",
  1222. "fsin",
  1223. "fcos",
  1224. };
  1225. PSTR DbgX87DAC0Instructions[8] = {
  1226. "fcmovb",
  1227. "fcmove",
  1228. "fcmovbe",
  1229. "fcmovu",
  1230. NULL,
  1231. NULL,
  1232. NULL,
  1233. NULL
  1234. };
  1235. PSTR DbgX87DBC0Instructions[8] = {
  1236. "fcmovnb",
  1237. "fcmovne",
  1238. "fcmovnbe",
  1239. "fcmovnu",
  1240. NULL,
  1241. "fucomi",
  1242. "fcomi",
  1243. NULL
  1244. };
  1245. PSTR DbgX87DBE0Instructions[8] = {
  1246. "feni",
  1247. "fdisi",
  1248. "fclex",
  1249. "finit",
  1250. "fsetpm",
  1251. "frstpm",
  1252. NULL,
  1253. NULL
  1254. };
  1255. PSTR DbgX87DCC0Instructions[8] = {
  1256. "fadd",
  1257. "fmul",
  1258. "fcom",
  1259. "fcomp",
  1260. "fsubr",
  1261. "fsub",
  1262. "fdivr",
  1263. "fdiv",
  1264. };
  1265. PSTR DbgX87DDC0Instructions[8] = {
  1266. "ffree",
  1267. "fxch",
  1268. "fst",
  1269. "fstp",
  1270. "fucom",
  1271. "fucomp",
  1272. NULL,
  1273. NULL,
  1274. };
  1275. PSTR DbgX87DEC0Instructions[8] = {
  1276. "faddp",
  1277. "fmulp",
  1278. "fcomp",
  1279. NULL,
  1280. "fsubrp",
  1281. "fsubp",
  1282. "fdivrp",
  1283. "fdivp",
  1284. };
  1285. PSTR DbgX87DFC0Instructions[8] = {
  1286. "freep",
  1287. "fxch",
  1288. "fstp",
  1289. "fstp",
  1290. NULL,
  1291. "fucomip",
  1292. "fcomip",
  1293. NULL,
  1294. };
  1295. PSTR DbgX87DFE0Instructions[X87_DF_E0_COUNT] = {
  1296. "fstsw",
  1297. "fstdw",
  1298. "fstsg",
  1299. };
  1300. //
  1301. // Define the register name constants.
  1302. //
  1303. PSTR DbgX86ControlRegisterNames[X86_REGISTER_NAME_COUNT] = {
  1304. "cr0",
  1305. "cr1",
  1306. "cr2",
  1307. "cr3",
  1308. "cr4",
  1309. "cr5",
  1310. "cr6",
  1311. "cr7",
  1312. "cr8",
  1313. "cr9",
  1314. "cr10",
  1315. "cr11",
  1316. "cr12",
  1317. "cr13",
  1318. "cr14",
  1319. "cr15"
  1320. };
  1321. PSTR DbgX86DebugRegisterNames[X86_REGISTER_NAME_COUNT] = {
  1322. "dr0",
  1323. "dr1",
  1324. "dr2",
  1325. "dr3",
  1326. "dr4",
  1327. "dr5",
  1328. "dr6",
  1329. "dr7",
  1330. "dr8",
  1331. "dr9",
  1332. "dr10",
  1333. "dr11",
  1334. "dr12",
  1335. "dr13",
  1336. "dr14",
  1337. "dr15"
  1338. };
  1339. PSTR DbgX86SegmentRegisterNames[X86_REGISTER_NAME_COUNT] = {
  1340. "es",
  1341. "cs",
  1342. "ss",
  1343. "ds",
  1344. "fs",
  1345. "gs",
  1346. "ERR",
  1347. "ERR",
  1348. "es",
  1349. "cs",
  1350. "ss",
  1351. "ds",
  1352. "fs",
  1353. "gs",
  1354. "ERR",
  1355. "ERR"
  1356. };
  1357. //
  1358. // The 8 bit registers have different names in long mode. The first array here
  1359. // is for 32-bit mode, the second is for long mode.
  1360. //
  1361. PSTR DbgX86RegisterNames8Bit[2][X86_REGISTER_NAME_COUNT] = {
  1362. {
  1363. "al",
  1364. "cl",
  1365. "dl",
  1366. "bl",
  1367. "ah",
  1368. "ch",
  1369. "dh",
  1370. "bh",
  1371. "r8b",
  1372. "r9b",
  1373. "r10b",
  1374. "r11b",
  1375. "r12b",
  1376. "r13b",
  1377. "r14b",
  1378. "r15b"
  1379. },
  1380. {
  1381. "al",
  1382. "cl",
  1383. "dl",
  1384. "bl",
  1385. "spl",
  1386. "bpl",
  1387. "sil",
  1388. "dil",
  1389. "r8b",
  1390. "r9b",
  1391. "r10b",
  1392. "r11b",
  1393. "r12b",
  1394. "r13b",
  1395. "r14b",
  1396. "r15b"
  1397. }
  1398. };
  1399. PSTR DbgX86RegisterNames16Bit[X86_REGISTER_NAME_COUNT] = {
  1400. "ax",
  1401. "cx",
  1402. "dx",
  1403. "bx",
  1404. "sp",
  1405. "bp",
  1406. "si",
  1407. "di",
  1408. "r8w",
  1409. "r9w",
  1410. "r10w",
  1411. "r11w",
  1412. "r12w",
  1413. "r13w",
  1414. "r14w",
  1415. "r15w"
  1416. };
  1417. PSTR DbgX86RegisterNames32Bit[X86_REGISTER_NAME_COUNT] = {
  1418. "eax",
  1419. "ecx",
  1420. "edx",
  1421. "ebx",
  1422. "esp",
  1423. "ebp",
  1424. "esi",
  1425. "edi",
  1426. "r8d",
  1427. "r9d",
  1428. "r10d",
  1429. "r11d",
  1430. "r12d",
  1431. "r13d",
  1432. "r14d",
  1433. "r15d"
  1434. };
  1435. PSTR DbgX86RegisterNames64Bit[X86_REGISTER_NAME_COUNT] = {
  1436. "rax",
  1437. "rcx",
  1438. "rdx",
  1439. "rbx",
  1440. "rsp",
  1441. "rbp",
  1442. "rsi",
  1443. "rdi",
  1444. "r8",
  1445. "r9",
  1446. "r10",
  1447. "r11",
  1448. "r12",
  1449. "r13",
  1450. "r14",
  1451. "r15"
  1452. };
  1453. PSTR DbgX87RegisterNames[X86_REGISTER_NAME_COUNT] = {
  1454. "st(0)",
  1455. "st(1)",
  1456. "st(2)",
  1457. "st(3)",
  1458. "st(4)",
  1459. "st(5)",
  1460. "st(6)",
  1461. "st(7)",
  1462. "ERR",
  1463. "ERR",
  1464. "ERR",
  1465. "ERR",
  1466. "ERR",
  1467. "ERR",
  1468. "ERR",
  1469. "ERR"
  1470. };
  1471. PSTR DbgX86MmxRegisterNames[X86_REGISTER_NAME_COUNT] = {
  1472. "mmx0",
  1473. "mmx1",
  1474. "mmx2",
  1475. "mmx3",
  1476. "mmx4",
  1477. "mmx5",
  1478. "mmx6",
  1479. "mmx7",
  1480. "mmx8",
  1481. "mmx9",
  1482. "mmx10",
  1483. "mmx11",
  1484. "mmx12",
  1485. "mmx13",
  1486. "mmx14",
  1487. "mmx15"
  1488. };
  1489. PSTR DbgX86XmmRegisterNames[X86_REGISTER_NAME_COUNT] = {
  1490. "xmm0",
  1491. "xmm1",
  1492. "xmm2",
  1493. "xmm3",
  1494. "xmm4",
  1495. "xmm5",
  1496. "xmm6",
  1497. "xmm7",
  1498. "xmm8",
  1499. "xmm9",
  1500. "xmm10",
  1501. "xmm11",
  1502. "xmm12",
  1503. "xmm13",
  1504. "xmm14",
  1505. "xmm15"
  1506. };
  1507. PSTR DbgX86YmmRegisterNames[X86_REGISTER_NAME_COUNT] = {
  1508. "ymm0",
  1509. "ymm1",
  1510. "ymm2",
  1511. "ymm3",
  1512. "ymm4",
  1513. "ymm5",
  1514. "ymm6",
  1515. "ymm7",
  1516. "ymm8",
  1517. "ymm9",
  1518. "ymm10",
  1519. "ymm11",
  1520. "ymm12",
  1521. "ymm13",
  1522. "ymm14",
  1523. "ymm15"
  1524. };
  1525. //
  1526. // ----------------------------------------------- Internal Function Prototypes
  1527. //
  1528. BOOL
  1529. DbgpX86PrintOperand (
  1530. ULONGLONG InstructionPointer,
  1531. PX86_INSTRUCTION Instruction,
  1532. PSTR OperandFormat,
  1533. PSTR Operand,
  1534. ULONG BufferLength,
  1535. PULONGLONG Address,
  1536. PBOOL AddressValid
  1537. );
  1538. PSTR
  1539. DbgpX86PrintMnemonic (
  1540. PX86_INSTRUCTION Instruction
  1541. );
  1542. BOOL
  1543. DbgpX86GetInstructionComponents (
  1544. PBYTE InstructionStream,
  1545. PX86_INSTRUCTION Instruction
  1546. );
  1547. BOOL
  1548. DbgpX86GetInstructionParameters (
  1549. PBYTE InstructionStream,
  1550. PX86_INSTRUCTION Instruction,
  1551. PBOOL ModRmExists,
  1552. PBOOL SibExists,
  1553. PULONG DisplacementSize,
  1554. PULONG ImmediateSize
  1555. );
  1556. PSTR
  1557. DbgpX86RegisterName (
  1558. PX86_INSTRUCTION Instruction,
  1559. X86_REGISTER_VALUE RegisterNumber,
  1560. CHAR Type
  1561. );
  1562. INT
  1563. DbgpX86GetDisplacement (
  1564. PX86_INSTRUCTION Instruction,
  1565. PSTR Buffer,
  1566. ULONG BufferLength,
  1567. PLONGLONG DisplacementValue
  1568. );
  1569. PX86_INSTRUCTION_DEFINITION
  1570. DbgpX86GetTwoByteInstruction (
  1571. PX86_INSTRUCTION Instruction
  1572. );
  1573. BOOL
  1574. DbgpX86DecodeFloatingPointInstruction (
  1575. PX86_INSTRUCTION Instruction
  1576. );
  1577. //
  1578. // ------------------------------------------------------------------ Functions
  1579. //
  1580. BOOL
  1581. DbgpX86Disassemble (
  1582. ULONGLONG InstructionPointer,
  1583. PBYTE InstructionStream,
  1584. PSTR Buffer,
  1585. ULONG BufferLength,
  1586. PDISASSEMBLED_INSTRUCTION Disassembly,
  1587. MACHINE_LANGUAGE Language
  1588. )
  1589. /*++
  1590. Routine Description:
  1591. This routine decodes one instruction from an IA-32 binary instruction
  1592. stream into a human readable form.
  1593. Arguments:
  1594. InstructionPointer - Supplies the instruction pointer for the start of the
  1595. instruction stream.
  1596. InstructionStream - Supplies a pointer to the binary instruction stream.
  1597. Buffer - Supplies a pointer to the buffer where the human
  1598. readable strings will be printed. This buffer must be allocated by the
  1599. caller.
  1600. BufferLength - Supplies the length of the supplied buffer.
  1601. Disassembly - Supplies a pointer to the structure that will receive
  1602. information about the instruction.
  1603. Language - Supplies the type of machine langage being decoded.
  1604. Return Value:
  1605. TRUE on success.
  1606. FALSE if the instruction was unknown.
  1607. --*/
  1608. {
  1609. ULONGLONG Address;
  1610. BOOL AddressValid;
  1611. X86_INSTRUCTION Instruction;
  1612. INT Length;
  1613. PSTR Mnemonic;
  1614. BOOL Result;
  1615. PSTR ThirdOperandFormat;
  1616. CHAR WorkingBuffer[X86_WORKING_BUFFER_SIZE];
  1617. if ((Disassembly == NULL) || (Buffer == NULL)) {
  1618. return FALSE;
  1619. }
  1620. memset(Buffer, 0, BufferLength);
  1621. memset(Disassembly, 0, sizeof(DISASSEMBLED_INSTRUCTION));
  1622. memset(&Instruction, 0, sizeof(X86_INSTRUCTION));
  1623. Instruction.Language = Language;
  1624. Instruction.InstructionPointer = InstructionPointer;
  1625. //
  1626. // Dissect the instruction into more managable components.
  1627. //
  1628. Result = DbgpX86GetInstructionComponents(InstructionStream, &Instruction);
  1629. if (Result == FALSE) {
  1630. goto DisassembleEnd;
  1631. }
  1632. Disassembly->BinaryLength = Instruction.Length;
  1633. //
  1634. // Print the mnemonic.
  1635. //
  1636. Mnemonic = DbgpX86PrintMnemonic(&Instruction);
  1637. if ((Mnemonic == NULL) || (strlen(Mnemonic) >= BufferLength)) {
  1638. Result = FALSE;
  1639. goto DisassembleEnd;
  1640. }
  1641. //
  1642. // Copy the mnemonic into the buffer, and advance the buffer to the next
  1643. // free spot.
  1644. //
  1645. Length = snprintf(Buffer,
  1646. BufferLength,
  1647. "%s%s%s",
  1648. Instruction.Lock,
  1649. Instruction.Rep,
  1650. Mnemonic);
  1651. if (Length < 0) {
  1652. Result = FALSE;
  1653. goto DisassembleEnd;
  1654. }
  1655. Disassembly->Mnemonic = Buffer;
  1656. Buffer += Length + 1;
  1657. BufferLength -= Length + 1;
  1658. //
  1659. // Get the destination operand.
  1660. //
  1661. WorkingBuffer[0] = '\0';
  1662. Result = DbgpX86PrintOperand(InstructionPointer,
  1663. &Instruction,
  1664. Instruction.Definition.Target,
  1665. WorkingBuffer,
  1666. sizeof(WorkingBuffer),
  1667. &Address,
  1668. &AddressValid);
  1669. if ((Result == FALSE) ||
  1670. (strlen(WorkingBuffer) >= BufferLength)) {
  1671. Result = FALSE;
  1672. goto DisassembleEnd;
  1673. }
  1674. //
  1675. // If an address came out of that, plug it into the result.
  1676. //
  1677. if (AddressValid != FALSE) {
  1678. Disassembly->OperandAddress = Address;
  1679. Disassembly->AddressIsValid = TRUE;
  1680. Disassembly->AddressIsDestination = TRUE;
  1681. }
  1682. //
  1683. // Copy the operand into the buffer, and advance the buffer.
  1684. //
  1685. Disassembly->DestinationOperand = Buffer;
  1686. strncpy(Disassembly->DestinationOperand, WorkingBuffer, BufferLength);
  1687. Buffer += strlen(WorkingBuffer) + 1;
  1688. BufferLength -= strlen(WorkingBuffer) + 1;
  1689. //
  1690. // Get the source operand.
  1691. //
  1692. WorkingBuffer[0] = '\0';
  1693. Result = DbgpX86PrintOperand(InstructionPointer,
  1694. &Instruction,
  1695. Instruction.Definition.Source,
  1696. WorkingBuffer,
  1697. sizeof(WorkingBuffer),
  1698. &Address,
  1699. &AddressValid);
  1700. if ((Result == FALSE) || (strlen(WorkingBuffer) >= BufferLength)) {
  1701. Result = FALSE;
  1702. goto DisassembleEnd;
  1703. }
  1704. //
  1705. // If an address came out of the operand, plug it into the result.
  1706. //
  1707. if (AddressValid != FALSE) {
  1708. Disassembly->OperandAddress = Address;
  1709. Disassembly->AddressIsValid = TRUE;
  1710. Disassembly->AddressIsDestination = FALSE;
  1711. }
  1712. //
  1713. // Copy the operand into the buffer, and advance the buffer.
  1714. //
  1715. if (WorkingBuffer[0] != '\0') {
  1716. Disassembly->SourceOperand = Buffer;
  1717. strncpy(Disassembly->SourceOperand, WorkingBuffer, BufferLength);
  1718. Buffer += strlen(WorkingBuffer) + 1;
  1719. BufferLength -= strlen(WorkingBuffer) + 1;
  1720. }
  1721. //
  1722. // Handle the third operand.
  1723. //
  1724. ThirdOperandFormat = Instruction.Definition.Third;
  1725. if ((ThirdOperandFormat != NULL) && (*ThirdOperandFormat != '\0')) {
  1726. WorkingBuffer[0] = '\0';
  1727. Result = DbgpX86PrintOperand(InstructionPointer,
  1728. &Instruction,
  1729. ThirdOperandFormat,
  1730. WorkingBuffer,
  1731. sizeof(WorkingBuffer),
  1732. &Address,
  1733. &AddressValid);
  1734. if ((Result == FALSE) || (strlen(WorkingBuffer) > BufferLength)) {
  1735. Result = FALSE;
  1736. goto DisassembleEnd;
  1737. }
  1738. //
  1739. // If the second operand is empty, take over its slot.
  1740. //
  1741. if (Disassembly->SourceOperand == NULL) {
  1742. Disassembly->SourceOperand = Buffer;
  1743. } else {
  1744. Disassembly->ThirdOperand = Buffer;
  1745. }
  1746. strncpy(Buffer, WorkingBuffer, BufferLength);
  1747. }
  1748. DisassembleEnd:
  1749. return Result;
  1750. }
  1751. //
  1752. // --------------------------------------------------------- Internal Functions
  1753. //
  1754. BOOL
  1755. DbgpX86PrintOperand (
  1756. ULONGLONG InstructionPointer,
  1757. PX86_INSTRUCTION Instruction,
  1758. PSTR OperandFormat,
  1759. PSTR Operand,
  1760. ULONG BufferLength,
  1761. PULONGLONG Address,
  1762. PBOOL AddressValid
  1763. )
  1764. /*++
  1765. Routine Description:
  1766. This routine prints an operand in an IA instruction stream depending on the
  1767. supplied format.
  1768. Arguments:
  1769. InstructionPointer - Supplies the instruction pointer for the instruction
  1770. being disassembled.
  1771. Instruction - Supplies a pointer to the instruction structure.
  1772. OperandFormat - Supplies the format of the operand in two or more
  1773. characters. These are largely compatible with the Intel Opcode
  1774. Encodings, except for the ! prefix, which indicates an absolute
  1775. register name.
  1776. Operand - Supplies a pointer to the string that will receive the human
  1777. readable operand.
  1778. BufferLength - Supplies the length of the supplied buffer.
  1779. Address - Supplies a pointer that receives the memory address encoded in the
  1780. operand.
  1781. AddressValid - Supplies a pointer that receives whether or not the value
  1782. store in the Address parameter is valid.
  1783. Return Value:
  1784. TRUE on success.
  1785. FALSE on failure.
  1786. --*/
  1787. {
  1788. PSTR Base;
  1789. BYTE BaseValue;
  1790. PSTR Index;
  1791. BYTE IndexValue;
  1792. INT Length;
  1793. X86_MOD_VALUE Mod;
  1794. PSTR RegisterString;
  1795. UCHAR Rm;
  1796. ULONG Scale;
  1797. CHAR Type;
  1798. CHAR Width;
  1799. Base = NULL;
  1800. Index = NULL;
  1801. IndexValue = 0xFF;
  1802. Scale = 0;
  1803. RegisterString = NULL;
  1804. //
  1805. // Start by doing some parameter checking.
  1806. //
  1807. if ((Operand == NULL) || (BufferLength == 0)) {
  1808. return FALSE;
  1809. }
  1810. Operand[0] = '\0';
  1811. *Address = 0ULL;
  1812. *AddressValid = FALSE;
  1813. if (*OperandFormat == '\0') {
  1814. return TRUE;
  1815. }
  1816. Type = OperandFormat[0];
  1817. Width = OperandFormat[1];
  1818. //
  1819. // 'd' means dword, which gets translated to long here for simplicity.
  1820. //
  1821. switch (Width) {
  1822. case 'd':
  1823. Width = X86_WIDTH_LONG;
  1824. break;
  1825. case '\0':
  1826. case 's':
  1827. case 'p':
  1828. Width = X86_WIDTH_LONG;
  1829. if (Instruction->Language == MachineLanguageX64) {
  1830. Width = X86_WIDTH_LONGLONG;
  1831. }
  1832. break;
  1833. case 'y':
  1834. Width = X86_WIDTH_LONG;
  1835. if ((Instruction->Rex & X64_REX_W) != 0) {
  1836. Width = X86_WIDTH_LONGLONG;
  1837. }
  1838. break;
  1839. //
  1840. // If the width is variable, it is probably a dword unless an override is
  1841. // specified.
  1842. //
  1843. case 'v':
  1844. case 'z':
  1845. //
  1846. // A few instructions default to 64-bits in long mode.
  1847. //
  1848. if ((Instruction->Language == MachineLanguageX64) &&
  1849. (OperandFormat[2] == '6')) {
  1850. Width = X86_WIDTH_LONGLONG;
  1851. if (Instruction->OperandOverride != FALSE) {
  1852. Width = X86_WIDTH_WORD;
  1853. }
  1854. } else if ((Instruction->Rex & X64_REX_W) != 0) {
  1855. if (Width == 'v') {
  1856. Width = X86_WIDTH_LONGLONG;
  1857. } else {
  1858. Width = X86_WIDTH_LONG;
  1859. }
  1860. } else {
  1861. Width = X86_WIDTH_LONG;
  1862. if ((Instruction->OperandOverride == TRUE) ||
  1863. (Instruction->AddressOverride == TRUE)) {
  1864. Width = X86_WIDTH_WORD;
  1865. }
  1866. }
  1867. break;
  1868. case 'u':
  1869. Width = X86_WIDTH_YWORD;
  1870. if (Instruction->OperandOverride != FALSE) {
  1871. Width = X86_WIDTH_ZWORD;
  1872. }
  1873. break;
  1874. case 'x':
  1875. Width = X86_WIDTH_OWORD;
  1876. if ((Instruction->Vex & X64_VEX_L) != 0) {
  1877. Width = X86_WIDTH_YWORD;
  1878. }
  1879. break;
  1880. //
  1881. // An unknown width specifier.
  1882. //
  1883. default:
  1884. break;
  1885. }
  1886. switch (Type) {
  1887. //
  1888. // The ! encoding indicates that a register is hardcoded.
  1889. //
  1890. case '!':
  1891. //
  1892. // If the width is 'e', then it's a hardcoded string.
  1893. //
  1894. if (Width == 'e') {
  1895. strncpy(Operand, OperandFormat + 2, BufferLength);
  1896. //
  1897. // An r indicates a register corresponding to the current mode. These
  1898. // encode a register number as an ASCII number.
  1899. //
  1900. } else if ((OperandFormat[2] >= '0') && (OperandFormat[2] <= '7')) {
  1901. if (Width == 'r') {
  1902. if (Instruction->OperandOverride != FALSE) {
  1903. Width = X86_WIDTH_WORD;
  1904. } else if ((Instruction->Language == MachineLanguageX64) &&
  1905. (OperandFormat[3] == '6')) {
  1906. Width = X86_WIDTH_LONGLONG;
  1907. } else {
  1908. Width = X86_WIDTH_LONG;
  1909. if ((Instruction->Rex & X64_REX_W) != 0) {
  1910. Width = X86_WIDTH_LONGLONG;
  1911. }
  1912. }
  1913. }
  1914. Rm = OperandFormat[2] - '0';
  1915. Rm = X86_MODRM_RM(Instruction, Rm);
  1916. strncpy(Operand,
  1917. DbgpX86RegisterName(Instruction, Rm, Width),
  1918. BufferLength);
  1919. //
  1920. // Otherwise it's something like wcs or bal, with a width and register.
  1921. //
  1922. } else {
  1923. strncpy(Operand, OperandFormat + 2, BufferLength);
  1924. }
  1925. break;
  1926. //
  1927. // A - Direct address, no mod R/M byte; address of operand is encoded in
  1928. // instruction. No base, index, or scaling can be applied.
  1929. //
  1930. case 'A':
  1931. snprintf(Operand,
  1932. BufferLength,
  1933. "%s[0x%llx]",
  1934. Instruction->SegmentPrefix,
  1935. Instruction->Immediate);
  1936. *Address = Instruction->Immediate;
  1937. *AddressValid = TRUE;
  1938. break;
  1939. //
  1940. // C - Reg field of mod R/M byte selects a control register.
  1941. // D - Reg field of mod R/M byte selects a debug register.
  1942. // S - Reg field of ModR/M byte selects a segment register.
  1943. //
  1944. case 'C':
  1945. case 'D':
  1946. case 'S':
  1947. RegisterString = DbgpX86RegisterName(
  1948. Instruction,
  1949. X86_MODRM_REG(Instruction, Instruction->ModRm),
  1950. Type);
  1951. strncpy(Operand, RegisterString, BufferLength);
  1952. break;
  1953. //
  1954. // V - XMM/YMM register specified by ModRM.reg.
  1955. //
  1956. case 'V':
  1957. RegisterString = DbgpX86RegisterName(
  1958. Instruction,
  1959. X86_MODRM_REG(Instruction, Instruction->ModRm),
  1960. Width);
  1961. strncpy(Operand, RegisterString, BufferLength);
  1962. break;
  1963. //
  1964. // H - XMM/YMM register specified by VEX/VOP.vvvv field, if one is present.
  1965. //
  1966. case 'H':
  1967. if (Instruction->VexMap != 0) {
  1968. Rm = X64_VEX_V(Instruction->Vex);
  1969. RegisterString = DbgpX86RegisterName(Instruction, Rm, Width);
  1970. strncpy(Operand, RegisterString, BufferLength);
  1971. }
  1972. break;
  1973. //
  1974. // E - Mod R/M bytes follows opcode and specifies operand. Operand is either
  1975. // a general register or a memory address. If it is a memory address, the
  1976. // address is computed from a segment register and any of the following
  1977. // values: a base register, an index register, a scaling factor, and a
  1978. // displacement.
  1979. // M - Mod R/M byte may only refer to memory.
  1980. // W - XMM/YMM register or memory operand.
  1981. //
  1982. case 'E':
  1983. case 'M':
  1984. case 'W':
  1985. Mod = X86_MODRM_MOD(Instruction->ModRm);
  1986. Rm = X86_MODRM_RM(Instruction, Instruction->ModRm);
  1987. if (Mod == X86ModValueRegister) {
  1988. if (Type == 'M') {
  1989. return FALSE;
  1990. }
  1991. RegisterString = DbgpX86RegisterName(Instruction, Rm, Width);
  1992. } else {
  1993. //
  1994. // Memory accesses only happen via general registers. Convert larger
  1995. // memory references into native ones.
  1996. //
  1997. if ((Width == X86_WIDTH_OWORD) || (Width == X86_WIDTH_YWORD) ||
  1998. (Width == X86_WIDTH_ZWORD)) {
  1999. Width = X86_WIDTH_LONG;
  2000. if (Instruction->Language == MachineLanguageX64) {
  2001. Width = X86_WIDTH_LONGLONG;
  2002. }
  2003. }
  2004. //
  2005. // An R/M value of 4 actually indicates an SIB byte is present, not
  2006. // ESP. The REX extension bit doesn't matter here.
  2007. //
  2008. if (X86_BASIC_REG(Rm) == X86RegisterValueSp) {
  2009. Rm = X86RegisterValueScaleIndexBase;
  2010. BaseValue = X86_SIB_BASE(Instruction);
  2011. IndexValue = X86_SIB_INDEX(Instruction);
  2012. Scale = X86_SIB_SCALE(Instruction);
  2013. Base = DbgpX86RegisterName(Instruction, BaseValue, Width);
  2014. Index = DbgpX86RegisterName(Instruction, IndexValue, Width);
  2015. //
  2016. // A base value of 5 (ebp) indicates that the base field is not
  2017. // used, and a displacement is present. The Mod field then
  2018. // specifies the size of the displacement.
  2019. //
  2020. if (X86_BASIC_REG(BaseValue) == X86RegisterValueBp) {
  2021. Base = "";
  2022. Length = snprintf(Operand,
  2023. BufferLength,
  2024. "0x%llx",
  2025. Instruction->Displacement);
  2026. if (Length <= 0) {
  2027. return FALSE;
  2028. }
  2029. Operand += Length;
  2030. BufferLength -= Length;
  2031. }
  2032. } else if ((Mod == X86ModValueNoDisplacement) &&
  2033. (X86_BASIC_REG(Rm) == X86RegisterValueBp)) {
  2034. Rm = X86RegisterValueDisplacement32;
  2035. if (Instruction->Language == MachineLanguageX64) {
  2036. Rm = X86RegisterValueRipRelative;
  2037. }
  2038. } else {
  2039. RegisterString = DbgpX86RegisterName(Instruction, Rm, Width);
  2040. }
  2041. }
  2042. //
  2043. // The operand is simply a register.
  2044. //
  2045. if (Mod == X86ModValueRegister) {
  2046. strncpy(Operand, RegisterString, BufferLength);
  2047. //
  2048. // The operand is an address with a scale/index/base.
  2049. //
  2050. } else if (Rm == X86RegisterValueScaleIndexBase) {
  2051. Length = snprintf(Operand,
  2052. BufferLength,
  2053. "%s[%s",
  2054. Instruction->SegmentPrefix,
  2055. Base);
  2056. if ((Length <= 0) || (BufferLength - Length <= 3)) {
  2057. return FALSE;
  2058. }
  2059. Operand += Length;
  2060. BufferLength -= Length;
  2061. //
  2062. // An index of 4 indicates that the index and scale fields are not
  2063. // used.
  2064. //
  2065. if (IndexValue != 4) {
  2066. if (*Base != '\0') {
  2067. *Operand = '+';
  2068. Operand += 1;
  2069. BufferLength -= 1;
  2070. }
  2071. Length = snprintf(Operand, BufferLength, "%s*%d", Index, Scale);
  2072. if (Length <= 0) {
  2073. return FALSE;
  2074. }
  2075. Operand += Length;
  2076. BufferLength -= Length;
  2077. }
  2078. Length = DbgpX86GetDisplacement(Instruction,
  2079. Operand,
  2080. BufferLength,
  2081. NULL);
  2082. if ((Length < 0) || (BufferLength - Length <= 2)) {
  2083. return FALSE;
  2084. }
  2085. Operand[Length] = ']';
  2086. Operand += Length + 1;
  2087. BufferLength -= Length + 1;
  2088. *Operand = '\0';
  2089. //
  2090. // The operand is a 32-bit address.
  2091. //
  2092. } else if (Rm == X86RegisterValueDisplacement32) {
  2093. Length = snprintf(Operand,
  2094. BufferLength,
  2095. "%s[0x%llx]",
  2096. Instruction->SegmentPrefix,
  2097. Instruction->Displacement);
  2098. if (Length <= 0) {
  2099. return FALSE;
  2100. }
  2101. *Address = Instruction->Displacement;
  2102. *AddressValid = TRUE;
  2103. //
  2104. // The operand is an address in a register, possibly with some
  2105. // additional displacement.
  2106. //
  2107. } else {
  2108. //
  2109. // The register could be RIP in the long-mode-only RIP-relative
  2110. // addressing.
  2111. //
  2112. if (Rm == X86RegisterValueRipRelative) {
  2113. RegisterString = "rip";
  2114. if (Instruction->AddressOverride != FALSE) {
  2115. RegisterString = "eip";
  2116. }
  2117. *Address = Instruction->InstructionPointer +
  2118. Instruction->Length +
  2119. (LONG)(Instruction->Displacement);
  2120. *AddressValid = TRUE;
  2121. }
  2122. Length = snprintf(Operand,
  2123. BufferLength,
  2124. "%s[%s",
  2125. Instruction->SegmentPrefix,
  2126. RegisterString);
  2127. if (Length <= 0) {
  2128. return FALSE;
  2129. }
  2130. Operand += Length;
  2131. BufferLength -= Length;
  2132. Length = DbgpX86GetDisplacement(Instruction,
  2133. Operand,
  2134. BufferLength,
  2135. NULL);
  2136. if ((Length < 0) || (BufferLength - Length <= 2)) {
  2137. return FALSE;
  2138. }
  2139. Operand[Length] = ']';
  2140. Operand += Length + 1;
  2141. BufferLength -= Length + 1;
  2142. *Operand = '\0';
  2143. }
  2144. break;
  2145. //
  2146. // G - Reg field of Mod R/M byte selects a general register.
  2147. //
  2148. case 'G':
  2149. Rm = X86_MODRM_REG(Instruction, Instruction->ModRm);
  2150. strncpy(Operand,
  2151. DbgpX86RegisterName(Instruction, Rm, Width),
  2152. BufferLength);
  2153. break;
  2154. //
  2155. // I - Immediate data: value of operand is encoded in Immediate field.
  2156. // O - Direct offset: no ModR/M byte. Offset of operand is encoded in
  2157. // instruction. No Base/Index/Scale can be applied.
  2158. //
  2159. case 'I':
  2160. case 'O':
  2161. snprintf(Operand, BufferLength, "0x%llx", Instruction->Immediate);
  2162. break;
  2163. //
  2164. // J - Instruction contains a relative offset to be added to the instruction
  2165. // pointer.
  2166. //
  2167. case 'J':
  2168. DbgpX86GetDisplacement(Instruction,
  2169. Operand,
  2170. BufferLength,
  2171. (PLONGLONG)Address);
  2172. *Address += (InstructionPointer + Instruction->Length);
  2173. snprintf(Operand,
  2174. BufferLength,
  2175. "%s[0x%llx]",
  2176. Instruction->SegmentPrefix,
  2177. *Address);
  2178. *AddressValid = TRUE;
  2179. break;
  2180. //
  2181. // R - R/M field of modR/M byte selects a general register. Mod field should
  2182. // be set to 11.
  2183. // U - XMM/YMM register specified by ModRM.rm with mod set to 11.
  2184. //
  2185. case 'R':
  2186. case 'U':
  2187. Mod = X86_MODRM_MOD(Instruction->ModRm);
  2188. Rm = X86_MODRM_RM(Instruction, Instruction->ModRm);
  2189. if (Mod != X86ModValueRegister) {
  2190. return FALSE;
  2191. }
  2192. strncpy(Operand,
  2193. DbgpX86RegisterName(Instruction, Rm, Width),
  2194. BufferLength);
  2195. break;
  2196. //
  2197. // X - Memory addressed by DS:SI register pair (eg. MOVS CMPS, OUTS, LODS).
  2198. //
  2199. case 'X':
  2200. RegisterString = DbgpX86RegisterName(Instruction,
  2201. X86RegisterValueSi,
  2202. X86_WIDTH_LONG);
  2203. snprintf(Operand, BufferLength, "ds:[%s]", RegisterString);
  2204. break;
  2205. //
  2206. // Y - Memory addressed by ES:DI register pair (eg. MOVS INS, STOS, SCAS).
  2207. //
  2208. case 'Y':
  2209. RegisterString = DbgpX86RegisterName(Instruction,
  2210. X86RegisterValueDi,
  2211. X86_WIDTH_LONG);
  2212. snprintf(Operand, BufferLength, "ds:[%s]", RegisterString);
  2213. break;
  2214. default:
  2215. return FALSE;
  2216. }
  2217. return TRUE;
  2218. }
  2219. PSTR
  2220. DbgpX86PrintMnemonic (
  2221. PX86_INSTRUCTION Instruction
  2222. )
  2223. /*++
  2224. Routine Description:
  2225. This routine prints an instruction mnemonic.
  2226. Arguments:
  2227. Instruction - Supplies a pointer to the instruction structure.
  2228. Return Value:
  2229. A pointer to the mnemonic on success.
  2230. NULL on failure.
  2231. --*/
  2232. {
  2233. PX86_OPCODE_GROUP OpcodeGroup;
  2234. BYTE RegByte;
  2235. if (Instruction == NULL) {
  2236. return NULL;
  2237. }
  2238. if (Instruction->Definition.Group == 0) {
  2239. return Instruction->Definition.Mnemonic;
  2240. }
  2241. assert(Instruction->Definition.Group != X86_INVALID_GROUP);
  2242. RegByte = (Instruction->ModRm & X86_REG_MASK) >> X86_REG_SHIFT;
  2243. OpcodeGroup = &(DbgX86OpcodeGroups[0]);
  2244. while (OpcodeGroup->Group != 0) {
  2245. if (OpcodeGroup->Group == Instruction->Definition.Group) {
  2246. return OpcodeGroup->Mnemonics[RegByte];
  2247. }
  2248. OpcodeGroup += 1;
  2249. }
  2250. assert(FALSE);
  2251. return NULL;
  2252. }
  2253. BOOL
  2254. DbgpX86GetInstructionComponents (
  2255. PBYTE InstructionStream,
  2256. PX86_INSTRUCTION Instruction
  2257. )
  2258. /*++
  2259. Routine Description:
  2260. This routine reads an instruction stream and decomposes it into its
  2261. respective components.
  2262. Arguments:
  2263. InstructionStream - Supplies a pointer to the raw binary instruction stream.
  2264. Instruction - Supplies a pointer to the structure that will accept the
  2265. instruction decomposition.
  2266. Return Value:
  2267. TRUE on success.
  2268. FALSE otherwise.
  2269. --*/
  2270. {
  2271. ULONG AlternateCount;
  2272. ULONG AlternateIndex;
  2273. ULONG Base;
  2274. PBYTE Beginning;
  2275. ULONG DisplacementSize;
  2276. ULONG Group;
  2277. ULONG ImmediateSize;
  2278. ULONG Mod;
  2279. BOOL ModRmExists;
  2280. UCHAR Opcode3;
  2281. INT PrefixIndex;
  2282. BYTE RegByte;
  2283. BOOL Result;
  2284. BOOL SibExists;
  2285. PX86_INSTRUCTION_DEFINITION TopLevelDefinition;
  2286. PX86_INSTRUCTION_DEFINITION TwoByteInstruction;
  2287. if (Instruction == NULL) {
  2288. return FALSE;
  2289. }
  2290. Beginning = InstructionStream;
  2291. Result = TRUE;
  2292. //
  2293. // Begin by handling any prefixes. The prefixes are: F0 (LOCK), F2 (REP),
  2294. // F3 (REP), 2E (CS), 36 (SS), 3E (DS), 26 (ES), 64 (FS), 65 (GS),
  2295. // 66 (Operand-size override), 67 (Address-size override)).
  2296. //
  2297. Instruction->Lock = "";
  2298. Instruction->Rep = "";
  2299. Instruction->SegmentPrefix = "";
  2300. for (PrefixIndex = 0; PrefixIndex < X86_MAX_PREFIXES; PrefixIndex += 1) {
  2301. switch (*InstructionStream) {
  2302. case X86_PREFIX_LOCK:
  2303. Instruction->Lock = "lock ";
  2304. break;
  2305. case X86_PREFIX_REPN:
  2306. Instruction->Rep = "repne ";
  2307. break;
  2308. case X86_PREFIX_REP:
  2309. Instruction->Rep = "rep ";
  2310. break;
  2311. case X86_PREFIX_CS:
  2312. if (Instruction->Language != MachineLanguageX64) {
  2313. Instruction->SegmentPrefix = "cs:";
  2314. }
  2315. break;
  2316. case X86_PREFIX_DS:
  2317. if (Instruction->Language != MachineLanguageX64) {
  2318. Instruction->SegmentPrefix = "ds:";
  2319. }
  2320. break;
  2321. case X86_PREFIX_ES:
  2322. Instruction->SegmentPrefix = "es:";
  2323. break;
  2324. case X86_PREFIX_FS:
  2325. Instruction->SegmentPrefix = "fs:";
  2326. break;
  2327. case X86_PREFIX_GS:
  2328. Instruction->SegmentPrefix = "gs:";
  2329. break;
  2330. case X86_PREFIX_SS:
  2331. Instruction->SegmentPrefix = "ss:";
  2332. break;
  2333. case X86_OPERAND_OVERRIDE:
  2334. Instruction->OperandOverride = TRUE;
  2335. break;
  2336. case X86_ADDRESS_OVERRIDE:
  2337. Instruction->AddressOverride = TRUE;
  2338. break;
  2339. default:
  2340. PrefixIndex = X86_MAX_PREFIXES;
  2341. break;
  2342. }
  2343. if (PrefixIndex == X86_MAX_PREFIXES) {
  2344. break;
  2345. }
  2346. Instruction->Prefix[PrefixIndex] = *InstructionStream;
  2347. InstructionStream += 1;
  2348. Instruction->Length += 1;
  2349. }
  2350. //
  2351. // Grab the REX prefix for x64, which has to go right before the
  2352. // instruction opcode.
  2353. //
  2354. if (Instruction->Language == MachineLanguageX64) {
  2355. if ((*InstructionStream & X64_REX_MASK) == X64_REX_VALUE) {
  2356. Instruction->Rex = *InstructionStream;
  2357. InstructionStream += 1;
  2358. Instruction->Length += 1;
  2359. //
  2360. // Look for the 2-byte VEX prefix. Convert it to a 3 byte prefix.
  2361. //
  2362. } else if (*InstructionStream == X64_VEX2) {
  2363. InstructionStream += 1;
  2364. Instruction->Length += 1;
  2365. Instruction->Vex = *InstructionStream;
  2366. Instruction->VexMap = X64_VEX2_MAP_SELECT |
  2367. (Instruction->Vex & 0x80);
  2368. Instruction->Vex &= 0x7F;
  2369. InstructionStream += 1;
  2370. Instruction->Length += 1;
  2371. Instruction->Rex = X64_VEX_TO_REX(Instruction->Vex,
  2372. Instruction->VexMap);
  2373. //
  2374. // Look for the 3 byte VEX/XOP prefix.
  2375. //
  2376. } else if ((*InstructionStream == X64_VEX3) ||
  2377. (*InstructionStream == X64_XOP)) {
  2378. InstructionStream += 1;
  2379. Instruction->Length += 1;
  2380. Instruction->VexMap = *InstructionStream;
  2381. InstructionStream += 1;
  2382. Instruction->Length += 1;
  2383. Instruction->Vex = *InstructionStream;
  2384. InstructionStream += 1;
  2385. Instruction->Length += 1;
  2386. Instruction->Rex = X64_VEX_TO_REX(Instruction->Vex,
  2387. Instruction->VexMap);
  2388. }
  2389. }
  2390. Instruction->Opcode = *InstructionStream;
  2391. Instruction->Length += 1;
  2392. InstructionStream += 1;
  2393. //
  2394. // Check for a two byte opcode.
  2395. //
  2396. if (Instruction->Opcode == X86_ESCAPE_OPCODE) {
  2397. Instruction->Opcode2 = *InstructionStream;
  2398. Instruction->Length += 1;
  2399. InstructionStream += 1;
  2400. TwoByteInstruction = DbgpX86GetTwoByteInstruction(Instruction);
  2401. if (TwoByteInstruction == NULL) {
  2402. Result = FALSE;
  2403. goto GetInstructionComponentsEnd;
  2404. }
  2405. TopLevelDefinition = TwoByteInstruction;
  2406. } else {
  2407. TopLevelDefinition = &(DbgX86Instructions[Instruction->Opcode]);
  2408. }
  2409. //
  2410. // Modify the instruction definition for groups. If the opcode is in a
  2411. // group, then it must have a modR/M byte, so cheat a little and get it.
  2412. //
  2413. Instruction->Definition = *TopLevelDefinition;
  2414. Group = Instruction->Definition.Group;
  2415. if ((Group != 0) && (Group != X86_INVALID_GROUP)) {
  2416. RegByte = (*InstructionStream & X86_REG_MASK) >> X86_REG_SHIFT;
  2417. switch (Group) {
  2418. case 3:
  2419. if (RegByte <= 1) {
  2420. if (Instruction->Opcode == 0xF6) {
  2421. Instruction->Definition.Source = "Ib";
  2422. } else {
  2423. assert(Instruction->Opcode == 0xF7);
  2424. Instruction->Definition.Source = "Iz";
  2425. }
  2426. }
  2427. break;
  2428. case 7:
  2429. //
  2430. // There are a bunch of alternate encoding instructions hidden
  2431. // behind 0F 01, go look for them.
  2432. //
  2433. if (RegByte == 1) {
  2434. Opcode3 = *InstructionStream;
  2435. AlternateCount = sizeof(DbgX860F01Alternates) /
  2436. sizeof(DbgX860F01Alternates[0]);
  2437. for (AlternateIndex = 0;
  2438. AlternateIndex < AlternateCount;
  2439. AlternateIndex += 1) {
  2440. if (DbgX860F01Alternates[AlternateIndex].Opcode ==
  2441. Opcode3) {
  2442. Instruction->Definition =
  2443. DbgX860F01Alternates[AlternateIndex].Instruction;
  2444. break;
  2445. }
  2446. }
  2447. }
  2448. break;
  2449. default:
  2450. break;
  2451. }
  2452. }
  2453. //
  2454. // Get the structure of the instruction.
  2455. //
  2456. Result = DbgpX86GetInstructionParameters(InstructionStream,
  2457. Instruction,
  2458. &ModRmExists,
  2459. &SibExists,
  2460. &DisplacementSize,
  2461. &ImmediateSize);
  2462. if (Result == FALSE) {
  2463. goto GetInstructionComponentsEnd;
  2464. }
  2465. if (Group != 0) {
  2466. ModRmExists = TRUE;
  2467. }
  2468. //
  2469. // Populate the various pieces of the instruction.
  2470. //
  2471. Instruction->DisplacementSize = DisplacementSize;
  2472. Instruction->ImmediateSize = ImmediateSize;
  2473. if (ModRmExists == TRUE) {
  2474. Instruction->ModRm = *InstructionStream;
  2475. InstructionStream += 1;
  2476. }
  2477. if (SibExists == TRUE) {
  2478. Instruction->Sib = *InstructionStream;
  2479. InstructionStream += 1;
  2480. //
  2481. // Check to see if the SIB byte requires a displacement. EBP is not a
  2482. // valid base, since that can be specified in the Mod bits.
  2483. //
  2484. Base = (Instruction->Sib & X86_BASE_MASK) >> X86_BASE_SHIFT;
  2485. Mod = X86_MODRM_MOD(Instruction->ModRm);
  2486. if (Base == X86RegisterValueBp) {
  2487. if (Mod == X86ModValueDisplacement8) {
  2488. DisplacementSize = 1;
  2489. } else {
  2490. DisplacementSize = 4;
  2491. }
  2492. }
  2493. }
  2494. //
  2495. // Grab the displacement and immediates from the instruction stream if
  2496. // they're there.
  2497. //
  2498. if (DisplacementSize != 0) {
  2499. memcpy(&(Instruction->Displacement),
  2500. InstructionStream,
  2501. DisplacementSize);
  2502. InstructionStream += DisplacementSize;
  2503. }
  2504. if (ImmediateSize != 0) {
  2505. memcpy(&(Instruction->Immediate), InstructionStream, ImmediateSize);
  2506. InstructionStream += ImmediateSize;
  2507. }
  2508. Instruction->Length = InstructionStream - Beginning;
  2509. //
  2510. // If it's an x87 floating point instruction, decode it now that the
  2511. // ModR/M byte was grabbed.
  2512. //
  2513. if (Group == 0x87) {
  2514. Result = DbgpX86DecodeFloatingPointInstruction(Instruction);
  2515. if (Result == FALSE) {
  2516. goto GetInstructionComponentsEnd;
  2517. }
  2518. }
  2519. GetInstructionComponentsEnd:
  2520. return Result;
  2521. }
  2522. BOOL
  2523. DbgpX86GetInstructionParameters (
  2524. PBYTE InstructionStream,
  2525. PX86_INSTRUCTION Instruction,
  2526. PBOOL ModRmExists,
  2527. PBOOL SibExists,
  2528. PULONG DisplacementSize,
  2529. PULONG ImmediateSize
  2530. )
  2531. /*++
  2532. Routine Description:
  2533. This routine determines the format of the rest of the instruction based on
  2534. the opcode, any prefixes, and possibly the ModRM byte.
  2535. Arguments:
  2536. InstructionStream - Supplies a pointer to the binary instruction stream,
  2537. after the prefixes and opcode.
  2538. Instruction - Supplies a pointer to an instruction. The Prefixes, Opcode,
  2539. and Definition must be filled out.
  2540. ModRmExists - Supplies a pointer where a boolean will be returned
  2541. indicating whether or not a ModRM byte is present.
  2542. SibExists - Supplies a pointer where a boolean will be returned indicating
  2543. whether or not a Scale/Index/Base byte is present in the instruction
  2544. stream.
  2545. DisplacementSize - Supplies a pointer where the size of the Displacement
  2546. value will be returned. 0 indicates there is no displacement in the
  2547. instruction.
  2548. ImmediateSize - Supplies a pointer where the size of the Immediate field
  2549. in the instruction will be returned. 0 indicates there is no Immediate
  2550. field in the instruction.
  2551. Return Value:
  2552. TRUE on success.
  2553. FALSE otherwise.
  2554. --*/
  2555. {
  2556. X86_MOD_VALUE Mod;
  2557. BYTE ModRm;
  2558. ULONG ParseCount;
  2559. BYTE RmValue;
  2560. CHAR Type;
  2561. CHAR Width;
  2562. *ModRmExists = FALSE;
  2563. *SibExists = FALSE;
  2564. *DisplacementSize = 0;
  2565. *ImmediateSize = 0;
  2566. if (Instruction->Definition.Target[0] == '\0') {
  2567. return TRUE;
  2568. }
  2569. Type = Instruction->Definition.Target[0];
  2570. Width = Instruction->Definition.Target[1];
  2571. ParseCount = 0;
  2572. do {
  2573. switch (Type) {
  2574. //
  2575. // A - Direct address. No Mod/RM, Immediate specifies address. No SIB.
  2576. //
  2577. case 'A':
  2578. *ImmediateSize = 4;
  2579. break;
  2580. //
  2581. // C - Control register in ModR/M.
  2582. // D - Debug register in ModR/M.
  2583. // S - Segment register in Reg field of ModR/M.
  2584. // T - Test register in ModR/M.
  2585. // V - SIMD floating point register in ModR/M.
  2586. //
  2587. case 'C':
  2588. case 'D':
  2589. case 'S':
  2590. case 'T':
  2591. case 'V':
  2592. *ModRmExists = TRUE;
  2593. break;
  2594. //
  2595. // E - Mod R/M bytes follows opcode and specifies operand. Operand is
  2596. // either a general register or a memory address. If it is a memory
  2597. // address, the address is computed from a segment register and any of
  2598. // the following values: a base register, an index register, a scaling
  2599. // factor, and a displacement.
  2600. // M - Mod R/M byte may only refer to memory.
  2601. // R - Mod R/M byte may only refer to a general register.
  2602. // W - XMM/YMM register or memory operand.
  2603. // U - XMM/YMM register specified by ModRM.rm with mod set to 11.
  2604. //
  2605. case 'E':
  2606. case 'M':
  2607. case 'R':
  2608. case 'U':
  2609. case 'W':
  2610. *ModRmExists = TRUE;
  2611. ModRm = *InstructionStream;
  2612. Mod = X86_MODRM_MOD(ModRm);
  2613. RmValue = (ModRm & X86_RM_MASK) >> X86_RM_SHIFT;
  2614. if (Mod != X86ModValueRegister) {
  2615. //
  2616. // An R/M value of 4 actually indicates an SIB byte is present,
  2617. // not ESP.
  2618. //
  2619. if (RmValue == X86RegisterValueSp) {
  2620. RmValue = X86RegisterValueScaleIndexBase;
  2621. *SibExists = TRUE;
  2622. }
  2623. //
  2624. // An R/M value of 5 when Mod is 0 means that the address is
  2625. // actually just a 32bit displacment.
  2626. //
  2627. if ((Mod == X86ModValueNoDisplacement) &&
  2628. (RmValue == X86RegisterValueBp)) {
  2629. RmValue = X86RegisterValueDisplacement32;
  2630. *DisplacementSize = 4;
  2631. }
  2632. }
  2633. //
  2634. // Get any displacements as specified by the MOD bits.
  2635. //
  2636. if (Mod == X86ModValueDisplacement8) {
  2637. *DisplacementSize = 1;
  2638. } else if (Mod == X86ModValueDisplacement32) {
  2639. *DisplacementSize = 4;
  2640. }
  2641. break;
  2642. //
  2643. // F - Flags register. No additional bytes.
  2644. // H - XMM or YMM register encoded in VEX/VOP.vvvv.
  2645. // X - Memory addressed by DS:SI pair.
  2646. // Y - Memory addressed by ES:DI pair.
  2647. // ! - Hardcoded register.
  2648. //
  2649. case 'F':
  2650. case 'H':
  2651. case 'X':
  2652. case 'Y':
  2653. case '!':
  2654. break;
  2655. //
  2656. // G - General register specified in Reg field of ModR/M byte.
  2657. //
  2658. case 'G':
  2659. *ModRmExists = TRUE;
  2660. break;
  2661. //
  2662. // I - Immediate data is encoded in subsequent bytes.
  2663. //
  2664. case 'I':
  2665. switch (Width) {
  2666. case X86_WIDTH_BYTE:
  2667. *ImmediateSize = 1;
  2668. break;
  2669. case X86_WIDTH_WORD:
  2670. *ImmediateSize = 2;
  2671. break;
  2672. case X86_WIDTH_LONG:
  2673. *ImmediateSize = 4;
  2674. break;
  2675. case 'v':
  2676. case 'z':
  2677. if ((Instruction->Rex & X64_REX_W) != 0) {
  2678. if (Width == 'v') {
  2679. *ImmediateSize = 8;
  2680. } else {
  2681. *ImmediateSize = 4;
  2682. }
  2683. } else {
  2684. *ImmediateSize = 4;
  2685. if (Instruction->OperandOverride == TRUE) {
  2686. *ImmediateSize = 2;
  2687. }
  2688. }
  2689. break;
  2690. }
  2691. break;
  2692. //
  2693. // O - Direct Offset. No ModR/M byte, offset of operand is encoded in
  2694. // instruction. No SIB.
  2695. //
  2696. case 'O':
  2697. *ImmediateSize = 4;
  2698. if (Instruction->AddressOverride != FALSE) {
  2699. *ImmediateSize = 2;
  2700. }
  2701. break;
  2702. //
  2703. // J - Instruction contains relative offset.
  2704. //
  2705. case 'J':
  2706. switch (Width) {
  2707. case X86_WIDTH_BYTE:
  2708. *DisplacementSize = 1;
  2709. break;
  2710. case X86_WIDTH_WORD:
  2711. *DisplacementSize = 2;
  2712. break;
  2713. case X86_WIDTH_LONG:
  2714. *DisplacementSize = 4;
  2715. break;
  2716. case 'v':
  2717. case 'z':
  2718. *DisplacementSize = 4;
  2719. if ((Instruction->Rex & X64_REX_W) != 0) {
  2720. if (Width == 'v') {
  2721. *DisplacementSize = 8;
  2722. }
  2723. } else {
  2724. if (Instruction->AddressOverride == TRUE) {
  2725. *DisplacementSize = 2;
  2726. }
  2727. }
  2728. break;
  2729. }
  2730. break;
  2731. default:
  2732. assert(FALSE);
  2733. return FALSE;
  2734. }
  2735. //
  2736. // Now that the target has been processed, loop again to process the
  2737. // source.
  2738. //
  2739. ParseCount += 1;
  2740. if (ParseCount == 1) {
  2741. if (Instruction->Definition.Source[0] == '\0') {
  2742. break;
  2743. }
  2744. Type = Instruction->Definition.Source[0];
  2745. Width = Instruction->Definition.Source[1];
  2746. } else {
  2747. if (Instruction->Definition.Third[0] == '\0') {
  2748. break;
  2749. }
  2750. Type = Instruction->Definition.Third[0];
  2751. Width = Instruction->Definition.Third[1];
  2752. }
  2753. } while (ParseCount < 3);
  2754. //
  2755. // Handle the cmpcc instructions that actually have an extra immediate on
  2756. // them.
  2757. //
  2758. if (strncmp(Instruction->Definition.Mnemonic, "cmpcc", 5) == 0) {
  2759. *ImmediateSize = 1;
  2760. }
  2761. return TRUE;
  2762. }
  2763. PSTR
  2764. DbgpX86RegisterName (
  2765. PX86_INSTRUCTION Instruction,
  2766. X86_REGISTER_VALUE RegisterNumber,
  2767. CHAR Type
  2768. )
  2769. /*++
  2770. Routine Description:
  2771. This routine reads a register number and a width and returns a string
  2772. representing that register. The register number should be in the same format
  2773. as specified in the REG bits of the ModR/M byte.
  2774. Arguments:
  2775. Instruction - Supplies the remaining register context.
  2776. RegisterNumber - Supplies which register to print out, as specified by the
  2777. REG bits of the ModR/M byte.
  2778. Type - Supplies a width or special register format.
  2779. Return Value:
  2780. The register specifed, in string form.
  2781. --*/
  2782. {
  2783. BOOL LongNames;
  2784. switch (Type) {
  2785. case X86_WIDTH_BYTE:
  2786. LongNames = Instruction->Rex != 0;
  2787. return DbgX86RegisterNames8Bit[LongNames][RegisterNumber];
  2788. case X86_WIDTH_WORD:
  2789. return DbgX86RegisterNames16Bit[RegisterNumber];
  2790. case X86_WIDTH_LONG:
  2791. return DbgX86RegisterNames32Bit[RegisterNumber];
  2792. case X86_WIDTH_LONGLONG:
  2793. return DbgX86RegisterNames64Bit[RegisterNumber];
  2794. case X86_WIDTH_OWORD:
  2795. return DbgX86XmmRegisterNames[RegisterNumber];
  2796. case X86_WIDTH_YWORD:
  2797. return DbgX86YmmRegisterNames[RegisterNumber];
  2798. case X86_FLOATING_POINT_REGISTER:
  2799. return DbgX87RegisterNames[RegisterNumber];
  2800. case X86_CONTROL_REGISTER:
  2801. return DbgX86ControlRegisterNames[RegisterNumber];
  2802. case X86_DEBUG_REGISTER:
  2803. return DbgX86DebugRegisterNames[RegisterNumber];
  2804. case X86_SEGMENT_REGISTER:
  2805. return DbgX86SegmentRegisterNames[RegisterNumber];
  2806. default:
  2807. break;
  2808. }
  2809. assert(FALSE);
  2810. return "ERR";
  2811. }
  2812. INT
  2813. DbgpX86GetDisplacement (
  2814. PX86_INSTRUCTION Instruction,
  2815. PSTR Buffer,
  2816. ULONG BufferLength,
  2817. PLONGLONG DisplacementValue
  2818. )
  2819. /*++
  2820. Routine Description:
  2821. This routine prints an address displacement value.
  2822. Arguments:
  2823. Instruction - Supplies a pointer to the instruction containing the
  2824. displacement.
  2825. Buffer - Supplies a pointer to the output buffer the displacement will be
  2826. printed to.
  2827. BufferLength - Supplies the length of the buffer in bytes.
  2828. DisplacementValue - Supplies a pointer to the variable that will receive the
  2829. numerical displacement value. This can be NULL.
  2830. Return Value:
  2831. Returns the length of the buffer consumed, not including the null
  2832. terminator.
  2833. --*/
  2834. {
  2835. LONGLONG Displacement;
  2836. INT Length;
  2837. if ((BufferLength < 1) || (Instruction == NULL)) {
  2838. return 0;
  2839. }
  2840. Buffer[0] = '\0';
  2841. if (Instruction->Displacement == 0) {
  2842. return 0;
  2843. }
  2844. switch (Instruction->DisplacementSize) {
  2845. case 1:
  2846. Displacement = (SCHAR)Instruction->Displacement;
  2847. break;
  2848. case 2:
  2849. Displacement = (SHORT)Instruction->Displacement;
  2850. break;
  2851. case 4:
  2852. Displacement = (LONG)Instruction->Displacement;
  2853. break;
  2854. case 8:
  2855. Displacement = (LONGLONG)Instruction->Displacement;
  2856. break;
  2857. default:
  2858. return 0;
  2859. }
  2860. if (Displacement < 0) {
  2861. Length = snprintf(Buffer, BufferLength, "-0x%llx", -Displacement);
  2862. } else {
  2863. Length = snprintf(Buffer, BufferLength, "+0x%llx", Displacement);
  2864. }
  2865. if (DisplacementValue != NULL) {
  2866. *DisplacementValue = Displacement;
  2867. }
  2868. return Length;
  2869. }
  2870. PX86_INSTRUCTION_DEFINITION
  2871. DbgpX86GetTwoByteInstruction (
  2872. PX86_INSTRUCTION Instruction
  2873. )
  2874. /*++
  2875. Routine Description:
  2876. This routine finds a two-byte instruction definition corresponding to the
  2877. instruction opcode and prefixes.
  2878. Arguments:
  2879. Instruction - Supplies a pointer to the instruction containing the
  2880. two byte opcode and any prefixes.
  2881. Return Value:
  2882. Returns a pointer to the instruction definition, or NULL if one could not
  2883. be found.
  2884. --*/
  2885. {
  2886. PX86_INSTRUCTION_DEFINITION Definition;
  2887. ULONG InstructionIndex;
  2888. ULONG InstructionLength;
  2889. UCHAR Prefix;
  2890. ULONG PrefixIndex;
  2891. PrefixIndex = 0;
  2892. InstructionLength = sizeof(DbgX86TwoByteInstructions) /
  2893. sizeof(DbgX86TwoByteInstructions[0]);
  2894. //
  2895. // First search through the array looking for a version with the first
  2896. // corresponding prefix.
  2897. //
  2898. while (Instruction->Prefix[PrefixIndex] != 0) {
  2899. InstructionIndex = 0;
  2900. Prefix = Instruction->Prefix[PrefixIndex];
  2901. while (InstructionIndex < InstructionLength) {
  2902. if ((DbgX86TwoByteInstructions[InstructionIndex].Prefix ==
  2903. Prefix) &&
  2904. (DbgX86TwoByteInstructions[InstructionIndex].Opcode ==
  2905. Instruction->Opcode2)) {
  2906. Definition =
  2907. &(DbgX86TwoByteInstructions[InstructionIndex].Instruction);
  2908. switch (Prefix) {
  2909. case X86_PREFIX_REP:
  2910. case X86_PREFIX_REPN:
  2911. Instruction->Rep = "";
  2912. break;
  2913. case X86_PREFIX_LOCK:
  2914. Instruction->Lock = "";
  2915. break;
  2916. default:
  2917. break;
  2918. }
  2919. return Definition;
  2920. }
  2921. InstructionIndex += 1;
  2922. }
  2923. PrefixIndex += 1;
  2924. }
  2925. //
  2926. // The search for the specific prefix instruction was not successful, or
  2927. // no prefixes were present. Search for the opcode with a prefix of zero,
  2928. // indicating that the prefix field is not applicable.
  2929. //
  2930. InstructionIndex = 0;
  2931. while (InstructionIndex < InstructionLength) {
  2932. if ((DbgX86TwoByteInstructions[InstructionIndex].Opcode ==
  2933. Instruction->Opcode2) &&
  2934. (DbgX86TwoByteInstructions[InstructionIndex].Prefix == 0)) {
  2935. return &(DbgX86TwoByteInstructions[InstructionIndex].Instruction);
  2936. }
  2937. InstructionIndex += 1;
  2938. }
  2939. //
  2940. // The search yielded no results. Return NULL.
  2941. //
  2942. return NULL;
  2943. }
  2944. BOOL
  2945. DbgpX86DecodeFloatingPointInstruction (
  2946. PX86_INSTRUCTION Instruction
  2947. )
  2948. /*++
  2949. Routine Description:
  2950. This routine decodes the given x87 floating point instruction by
  2951. manipulating the instruction definition.
  2952. Arguments:
  2953. Instruction - Supplies a pointer to the instruction.
  2954. Return Value:
  2955. TRUE on success.
  2956. FALSE if the instruction is invalid. Well, let's be more PC and say that no
  2957. instruction is "invalid", only "executionally challenged".
  2958. --*/
  2959. {
  2960. BYTE Index;
  2961. BYTE Mod;
  2962. BYTE ModRm;
  2963. BYTE Opcode;
  2964. BYTE Opcode2;
  2965. ModRm = Instruction->ModRm;
  2966. Mod = X86_MODRM_MOD(Instruction->ModRm);
  2967. Opcode = Instruction->Opcode - X87_ESCAPE_OFFSET;
  2968. Opcode2 = (ModRm & X86_REG_MASK) >> X86_REG_SHIFT;
  2969. //
  2970. // Reset the group to 0 so that after this routine tweaks everything it
  2971. // gets treated like a normal instruction.
  2972. //
  2973. Instruction->Definition.Group = 0;
  2974. Instruction->Definition.Mnemonic = NULL;
  2975. //
  2976. // If the ModR/M byte does not specify a register, then use the big
  2977. // table to figure out the mnemonic.
  2978. //
  2979. if (Mod != X86ModValueRegister) {
  2980. Instruction->Definition.Mnemonic = DbgX87Instructions[Opcode][Opcode2];
  2981. if (Instruction->Definition.Mnemonic == NULL) {
  2982. return FALSE;
  2983. }
  2984. return TRUE;
  2985. }
  2986. switch (Opcode) {
  2987. //
  2988. // Handle D8 instructions.
  2989. //
  2990. case 0:
  2991. Instruction->Definition.Mnemonic = DbgX87Instructions[0][Opcode2];
  2992. //
  2993. // The fcom and fcomp instructions take only ST(i). Everything else
  2994. // has two operands, st, and st(i).
  2995. //
  2996. if ((ModRm & X87_FCOM_MASK) == X87_FCOM_OPCODE) {
  2997. Instruction->Definition.Target = X87_REGISTER_TARGET;
  2998. } else {
  2999. Instruction->Definition.Target = X87_ST0_TARGET;
  3000. Instruction->Definition.Source = X87_REGISTER_TARGET;
  3001. }
  3002. break;
  3003. //
  3004. // Handle D9 instructions.
  3005. //
  3006. case 1:
  3007. switch (Opcode2) {
  3008. //
  3009. // C0-C7 is FLD ST(i).
  3010. //
  3011. case 0:
  3012. Instruction->Definition.Mnemonic = X87_FLD_MNEMONIC;
  3013. Instruction->Definition.Target = X87_REGISTER_TARGET;
  3014. break;
  3015. //
  3016. // C8-CF is FXCH ST(i).
  3017. //
  3018. case 1:
  3019. Instruction->Definition.Mnemonic = X87_FXCH_MNEMONIC;
  3020. Instruction->Definition.Target = X87_REGISTER_TARGET;
  3021. break;
  3022. //
  3023. // D0-D7 is just a NOP (really only at D0, but let it slide).
  3024. //
  3025. case 2:
  3026. Instruction->Definition.Mnemonic = X87_NOP_MNEMONIC;
  3027. Instruction->Definition.Target = "";
  3028. break;
  3029. //
  3030. // D8-DF is FSTP1 ST(i).
  3031. //
  3032. case 3:
  3033. Instruction->Definition.Mnemonic = X87_FSTP1_MNEMONIC;
  3034. Instruction->Definition.Target = X87_REGISTER_TARGET;
  3035. break;
  3036. //
  3037. // E0-FF is a grab bag of instructions with no operands.
  3038. //
  3039. default:
  3040. Instruction->Definition.Mnemonic =
  3041. DbgX87D9E0Instructions[ModRm - X87_D9_E0_OFFSET];
  3042. Instruction->Definition.Target = "";
  3043. break;
  3044. }
  3045. break;
  3046. //
  3047. // Handle DA instructions.
  3048. //
  3049. case 2:
  3050. //
  3051. // The fucompp instruction lives off by itself in a wasteland.
  3052. //
  3053. if (ModRm == X87_FUCOMPP_OPCODE) {
  3054. Instruction->Definition.Mnemonic = X87_FUCOMPP_MNEMONIC;
  3055. Instruction->Definition.Target = "";
  3056. } else {
  3057. //
  3058. // There are 8 instructions (4 valid), each of which take the form
  3059. // xxx ST, ST(i). So each instruction takes up 8 bytes.
  3060. //
  3061. Index = (ModRm & X87_DA_C0_MASK) >> X87_DA_CO_SHIFT;
  3062. Instruction->Definition.Mnemonic = DbgX87DAC0Instructions[Index];
  3063. Instruction->Definition.Target = X87_ST0_TARGET;
  3064. Instruction->Definition.Source = X87_REGISTER_TARGET;
  3065. }
  3066. break;
  3067. //
  3068. // Handle DB instructions.
  3069. //
  3070. case 3:
  3071. Index = (ModRm & X87_DB_C0_MASK) >> X87_DB_C0_SHIFT;
  3072. //
  3073. // There's a small rash of inidividual instructions in the E0-E7
  3074. // range.
  3075. //
  3076. if (Index == X87_DB_E0_INDEX) {
  3077. Index = ModRm & X87_DB_E0_MASK;
  3078. Instruction->Definition.Mnemonic = DbgX87DBE0Instructions[Index];
  3079. Instruction->Definition.Target = "";
  3080. //
  3081. // Otherwise there are swaths of instructions that take up 8 bytes
  3082. // each as they take the form xxx ST, ST(i).
  3083. //
  3084. } else {
  3085. Instruction->Definition.Mnemonic = DbgX87DBC0Instructions[Index];
  3086. Instruction->Definition.Target = X87_ST0_TARGET;
  3087. Instruction->Definition.Source = X87_REGISTER_TARGET;
  3088. }
  3089. break;
  3090. //
  3091. // DC is the same as D8, except it handles doubles instead of singles
  3092. // (floats). There's one other annoying detail which is that the FSUB and
  3093. // FSUBR are switched above 0xC0. The same goes for FDIV and FDIVR.
  3094. //
  3095. case 4:
  3096. Instruction->Definition.Mnemonic = DbgX87DCC0Instructions[Opcode2];
  3097. //
  3098. // The fcom and fcomp instructions take only ST(i). Everything else
  3099. // has two operands, st, and st(i).
  3100. //
  3101. if ((ModRm & X87_FCOM_MASK) == X87_FCOM_OPCODE) {
  3102. Instruction->Definition.Target = X87_REGISTER_TARGET;
  3103. } else {
  3104. Instruction->Definition.Target = X87_ST0_TARGET;
  3105. Instruction->Definition.Source = X87_REGISTER_TARGET;
  3106. }
  3107. break;
  3108. //
  3109. // Handle DD instructions.
  3110. //
  3111. case 5:
  3112. Instruction->Definition.Mnemonic = DbgX87DDC0Instructions[Opcode2];
  3113. Instruction->Definition.Target = X87_REGISTER_TARGET;
  3114. break;
  3115. //
  3116. // Handle DE instructions.
  3117. //
  3118. case 6:
  3119. Instruction->Definition.Mnemonic = DbgX87DEC0Instructions[Opcode2];
  3120. Instruction->Definition.Target = X87_REGISTER_TARGET;
  3121. Instruction->Definition.Source = X87_ST0_TARGET;
  3122. break;
  3123. //
  3124. // Handle DF instructions.
  3125. //
  3126. case 7:
  3127. Index = (ModRm & X87_DF_C0_MASK) >> X87_DF_C0_SHIFT;
  3128. //
  3129. // There's a small rash of individual instructions in the E0-E7
  3130. // range. They're pretty old school.
  3131. //
  3132. if (Index == X87_DF_E0_INDEX) {
  3133. Index = ModRm & X87_DF_E0_MASK;
  3134. if (Index < X87_DF_E0_COUNT) {
  3135. Instruction->Definition.Mnemonic =
  3136. DbgX87DFE0Instructions[Index];
  3137. Instruction->Definition.Target = X87_DF_E0_TARGET;
  3138. }
  3139. } else {
  3140. Instruction->Definition.Mnemonic = DbgX87DFC0Instructions[Opcode2];
  3141. Instruction->Definition.Target = X87_REGISTER_TARGET;
  3142. Instruction->Definition.Source = X87_ST0_TARGET;
  3143. }
  3144. break;
  3145. //
  3146. // This function was inappropriately called.
  3147. //
  3148. default:
  3149. assert(FALSE);
  3150. break;
  3151. }
  3152. if (Instruction->Definition.Mnemonic == NULL) {
  3153. return FALSE;
  3154. }
  3155. return TRUE;
  3156. }