dis_groups.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. /////////////////////////////////////////////////////////////////////////
  2. // $Id: dis_groups.cc 11885 2013-10-15 17:19:18Z sshwarts $
  3. /////////////////////////////////////////////////////////////////////////
  4. //
  5. // Copyright (c) 2005-2011 Stanislav Shwartsman
  6. // Written by Stanislav Shwartsman [sshwarts at sourceforge net]
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Lesser General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. // Lesser General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Lesser General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21. #include <stdio.h>
  22. #include <assert.h>
  23. #include "disasm.h"
  24. /*
  25. #if BX_DEBUGGER
  26. #include "../bx_debug/debug.h"
  27. #endif
  28. */
  29. void disassembler::Apw(const x86_insn *insn)
  30. {
  31. Bit16u imm16 = fetch_word();
  32. Bit16u cs_selector = fetch_word();
  33. dis_sprintf("0x%04x:%04x", (unsigned) cs_selector, (unsigned) imm16);
  34. }
  35. void disassembler::Apd(const x86_insn *insn)
  36. {
  37. Bit32u imm32 = fetch_dword();
  38. Bit16u cs_selector = fetch_word();
  39. dis_sprintf("0x%04x:%08x", (unsigned) cs_selector, (unsigned) imm32);
  40. }
  41. // 8-bit general purpose registers
  42. void disassembler::AL_Reg(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rAX_REG]); }
  43. void disassembler::CL_Reg(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rCX_REG]); }
  44. // 16-bit general purpose registers
  45. void disassembler::AX_Reg(const x86_insn *insn) {
  46. dis_sprintf("%s", general_16bit_regname[rAX_REG]);
  47. }
  48. void disassembler::DX_Reg(const x86_insn *insn) {
  49. dis_sprintf("%s", general_16bit_regname[rDX_REG]);
  50. }
  51. // 32-bit general purpose registers
  52. void disassembler::EAX_Reg(const x86_insn *insn)
  53. {
  54. dis_sprintf("%s", general_32bit_regname[rAX_REG]);
  55. }
  56. // 64-bit general purpose registers
  57. void disassembler::RAX_Reg(const x86_insn *insn)
  58. {
  59. dis_sprintf("%s", general_64bit_regname[rAX_REG]);
  60. }
  61. void disassembler::RCX_Reg(const x86_insn *insn)
  62. {
  63. dis_sprintf("%s", general_64bit_regname[rCX_REG]);
  64. }
  65. // segment registers
  66. void disassembler::CS(const x86_insn *insn) { dis_sprintf("%s", segment_name[CS_REG]); }
  67. void disassembler::DS(const x86_insn *insn) { dis_sprintf("%s", segment_name[DS_REG]); }
  68. void disassembler::ES(const x86_insn *insn) { dis_sprintf("%s", segment_name[ES_REG]); }
  69. void disassembler::SS(const x86_insn *insn) { dis_sprintf("%s", segment_name[SS_REG]); }
  70. void disassembler::FS(const x86_insn *insn) { dis_sprintf("%s", segment_name[FS_REG]); }
  71. void disassembler::GS(const x86_insn *insn) { dis_sprintf("%s", segment_name[GS_REG]); }
  72. void disassembler::Sw(const x86_insn *insn) { dis_sprintf("%s", segment_name[insn->nnn]); }
  73. // control register
  74. void disassembler::Cd(const x86_insn *insn)
  75. {
  76. if (intel_mode)
  77. dis_sprintf ("cr%d", insn->nnn);
  78. else
  79. dis_sprintf("%%cr%d", insn->nnn);
  80. }
  81. void disassembler::Cq(const x86_insn *insn) { Cd(insn); }
  82. // debug register
  83. void disassembler::Dd(const x86_insn *insn)
  84. {
  85. if (intel_mode)
  86. dis_sprintf ("dr%d", insn->nnn);
  87. else
  88. dis_sprintf("%%dr%d", insn->nnn);
  89. }
  90. void disassembler::Dq(const x86_insn *insn) { Dd(insn); }
  91. // 8-bit general purpose register
  92. void disassembler::Reg8(const x86_insn *insn)
  93. {
  94. unsigned reg = (insn->b1 & 7) | insn->rex_b;
  95. if (reg < 4 || insn->extend8b)
  96. dis_sprintf("%s", general_8bit_regname_rex[reg]);
  97. else
  98. dis_sprintf("%s", general_8bit_regname[reg]);
  99. }
  100. // 16-bit general purpose register
  101. void disassembler::RX(const x86_insn *insn)
  102. {
  103. dis_sprintf("%s", general_16bit_regname[(insn->b1 & 7) | insn->rex_b]);
  104. }
  105. // 32-bit general purpose register
  106. void disassembler::ERX(const x86_insn *insn)
  107. {
  108. dis_sprintf("%s", general_32bit_regname[(insn->b1 & 7) | insn->rex_b]);
  109. }
  110. // 64-bit general purpose register
  111. void disassembler::RRX(const x86_insn *insn)
  112. {
  113. dis_sprintf("%s", general_64bit_regname[(insn->b1 & 7) | insn->rex_b]);
  114. }
  115. // general purpose register or memory operand
  116. void disassembler::Eb(const x86_insn *insn)
  117. {
  118. if (insn->mod == 3) {
  119. if (insn->rm < 4 || insn->extend8b)
  120. dis_sprintf("%s", general_8bit_regname_rex[insn->rm]);
  121. else
  122. dis_sprintf("%s", general_8bit_regname[insn->rm]);
  123. }
  124. else
  125. (this->*resolve_modrm)(insn, B_SIZE);
  126. }
  127. void disassembler::Ew(const x86_insn *insn)
  128. {
  129. if (insn->mod == 3)
  130. dis_sprintf("%s", general_16bit_regname[insn->rm]);
  131. else
  132. (this->*resolve_modrm)(insn, W_SIZE);
  133. }
  134. void disassembler::Ed(const x86_insn *insn)
  135. {
  136. if (insn->mod == 3)
  137. dis_sprintf("%s", general_32bit_regname[insn->rm]);
  138. else
  139. (this->*resolve_modrm)(insn, D_SIZE);
  140. }
  141. void disassembler::Eq(const x86_insn *insn)
  142. {
  143. if (insn->mod == 3)
  144. dis_sprintf("%s", general_64bit_regname[insn->rm]);
  145. else
  146. (this->*resolve_modrm)(insn, Q_SIZE);
  147. }
  148. void disassembler::Ey(const x86_insn *insn)
  149. {
  150. if (insn->os_64) Eq(insn);
  151. else Ed(insn);
  152. }
  153. void disassembler::Ebd(const x86_insn *insn)
  154. {
  155. if (insn->mod == 3)
  156. dis_sprintf("%s", general_32bit_regname[insn->rm]);
  157. else
  158. (this->*resolve_modrm)(insn, B_SIZE);
  159. }
  160. void disassembler::Ewd(const x86_insn *insn)
  161. {
  162. if (insn->mod == 3)
  163. dis_sprintf("%s", general_32bit_regname[insn->rm]);
  164. else
  165. (this->*resolve_modrm)(insn, W_SIZE);
  166. }
  167. // general purpose register
  168. void disassembler::Gb(const x86_insn *insn)
  169. {
  170. if (insn->nnn < 4 || insn->extend8b)
  171. dis_sprintf("%s", general_8bit_regname_rex[insn->nnn]);
  172. else
  173. dis_sprintf("%s", general_8bit_regname[insn->nnn]);
  174. }
  175. void disassembler::Gw(const x86_insn *insn)
  176. {
  177. dis_sprintf("%s", general_16bit_regname[insn->nnn]);
  178. }
  179. void disassembler::Gd(const x86_insn *insn)
  180. {
  181. dis_sprintf("%s", general_32bit_regname[insn->nnn]);
  182. }
  183. void disassembler::Gq(const x86_insn *insn)
  184. {
  185. dis_sprintf("%s", general_64bit_regname[insn->nnn]);
  186. }
  187. void disassembler::Gy(const x86_insn *insn)
  188. {
  189. if (insn->os_64) Gq(insn);
  190. else Gd(insn);
  191. }
  192. // vex encoded general purpose register
  193. void disassembler::By(const x86_insn *insn)
  194. {
  195. if (insn->os_64)
  196. dis_sprintf("%s", general_64bit_regname[insn->vex_vvv]);
  197. else
  198. dis_sprintf("%s", general_32bit_regname[insn->vex_vvv]);
  199. }
  200. // immediate
  201. void disassembler::I1(const x86_insn *insn)
  202. {
  203. if (! intel_mode) dis_putc('$');
  204. dis_putc ('1');
  205. }
  206. void disassembler::Ib(const x86_insn *insn)
  207. {
  208. if (! intel_mode) dis_putc('$');
  209. dis_sprintf("0x%02x", (unsigned) fetch_byte());
  210. }
  211. void disassembler::Iw(const x86_insn *insn)
  212. {
  213. if (! intel_mode) dis_putc('$');
  214. dis_sprintf("0x%04x", (unsigned) fetch_word());
  215. }
  216. void disassembler::IbIb(const x86_insn *insn)
  217. {
  218. Bit8u ib1 = fetch_byte();
  219. Bit8u ib2 = fetch_byte();
  220. if (intel_mode) {
  221. dis_sprintf("0x%02x, 0x%02x", ib1, ib2);
  222. }
  223. else {
  224. dis_sprintf("$0x%02x, $0x%02x", ib2, ib1);
  225. }
  226. }
  227. void disassembler::IwIb(const x86_insn *insn)
  228. {
  229. Bit16u iw = fetch_word();
  230. Bit8u ib = fetch_byte();
  231. if (intel_mode) {
  232. dis_sprintf("0x%04x, 0x%02x", iw, ib);
  233. }
  234. else {
  235. dis_sprintf("$0x%02x, $0x%04x", ib, iw);
  236. }
  237. }
  238. void disassembler::Id(const x86_insn *insn)
  239. {
  240. if (! intel_mode) dis_putc('$');
  241. dis_sprintf("0x%08x", (unsigned) fetch_dword());
  242. }
  243. void disassembler::Iq(const x86_insn *insn)
  244. {
  245. Bit64u value = fetch_qword();
  246. if (! intel_mode) dis_putc('$');
  247. dis_sprintf("0x%08x%08x", GET32H(value), GET32L(value));
  248. }
  249. // sign extended immediate
  250. void disassembler::sIbw(const x86_insn *insn)
  251. {
  252. if (! intel_mode) dis_putc('$');
  253. Bit16u imm16 = (Bit8s) fetch_byte();
  254. dis_sprintf("0x%04x", (unsigned) imm16);
  255. }
  256. // sign extended immediate
  257. void disassembler::sIbd(const x86_insn *insn)
  258. {
  259. if (! intel_mode) dis_putc('$');
  260. Bit32u imm32 = (Bit8s) fetch_byte();
  261. dis_sprintf ("0x%08x", (unsigned) imm32);
  262. }
  263. // sign extended immediate
  264. void disassembler::sIbq(const x86_insn *insn)
  265. {
  266. if (! intel_mode) dis_putc('$');
  267. Bit64u imm64 = (Bit8s) fetch_byte();
  268. dis_sprintf ("0x%08x%08x", GET32H(imm64), GET32L(imm64));
  269. }
  270. // sign extended immediate
  271. void disassembler::sIdq(const x86_insn *insn)
  272. {
  273. if (! intel_mode) dis_putc('$');
  274. Bit64u imm64 = (Bit32s) fetch_dword();
  275. dis_sprintf ("0x%08x%08x", GET32H(imm64), GET32L(imm64));
  276. }
  277. // floating point
  278. void disassembler::ST0(const x86_insn *insn)
  279. {
  280. if (intel_mode)
  281. dis_sprintf ("st(0)");
  282. else
  283. dis_sprintf("%%st(0)");
  284. }
  285. void disassembler::STi(const x86_insn *insn)
  286. {
  287. if (intel_mode)
  288. dis_sprintf ("st(%d)", insn->rm & 7);
  289. else
  290. dis_sprintf("%%st(%d)", insn->rm & 7);
  291. }
  292. // 16-bit general purpose register
  293. void disassembler::Rw(const x86_insn *insn)
  294. {
  295. dis_sprintf("%s", general_16bit_regname[insn->rm]);
  296. }
  297. // 32-bit general purpose register
  298. void disassembler::Rd(const x86_insn *insn)
  299. {
  300. dis_sprintf("%s", general_32bit_regname[insn->rm]);
  301. }
  302. // 64-bit general purpose register
  303. void disassembler::Rq(const x86_insn *insn)
  304. {
  305. dis_sprintf("%s", general_64bit_regname[insn->rm]);
  306. }
  307. void disassembler::Ry(const x86_insn *insn)
  308. {
  309. if (insn->os_64) Rq(insn);
  310. else Rd(insn);
  311. }
  312. // mmx register
  313. void disassembler::Pq(const x86_insn *insn)
  314. {
  315. if (intel_mode)
  316. dis_sprintf ("mm%d", insn->nnn & 0x7);
  317. else
  318. dis_sprintf("%%mm%d", insn->nnn & 0x7);
  319. }
  320. void disassembler::Nq(const x86_insn *insn)
  321. {
  322. if (intel_mode)
  323. dis_sprintf ("mm%d", insn->rm & 0x7);
  324. else
  325. dis_sprintf("%%mm%d", insn->rm & 0x7);
  326. }
  327. void disassembler::Qd(const x86_insn *insn)
  328. {
  329. if (insn->mod == 3)
  330. {
  331. if (intel_mode)
  332. dis_sprintf ("mm%d", insn->rm & 0x7);
  333. else
  334. dis_sprintf("%%mm%d", insn->rm & 0x7);
  335. }
  336. else
  337. (this->*resolve_modrm)(insn, D_SIZE);
  338. }
  339. void disassembler::Qq(const x86_insn *insn)
  340. {
  341. if (insn->mod == 3)
  342. {
  343. if (intel_mode)
  344. dis_sprintf ("mm%d", insn->rm & 0x7);
  345. else
  346. dis_sprintf("%%mm%d", insn->rm & 0x7);
  347. }
  348. else
  349. (this->*resolve_modrm)(insn, Q_SIZE);
  350. }
  351. // xmm/ymm register
  352. void disassembler::Udq(const x86_insn *insn)
  353. {
  354. dis_sprintf("%s%d", vector_reg_name[insn->vex_l], insn->rm);
  355. }
  356. void disassembler::Ups(const x86_insn *insn) { Udq(insn); }
  357. void disassembler::Upd(const x86_insn *insn) { Udq(insn); }
  358. void disassembler::Uq(const x86_insn *insn) { Udq(insn); }
  359. void disassembler::Vq(const x86_insn *insn)
  360. {
  361. dis_sprintf("%s%d", vector_reg_name[insn->vex_l], insn->nnn);
  362. }
  363. void disassembler::Vdq(const x86_insn *insn) { Vq(insn); }
  364. void disassembler::Vss(const x86_insn *insn) { Vq(insn); }
  365. void disassembler::Vsd(const x86_insn *insn) { Vq(insn); }
  366. void disassembler::Vps(const x86_insn *insn) { Vq(insn); }
  367. void disassembler::Vpd(const x86_insn *insn) { Vq(insn); }
  368. void disassembler::VIb(const x86_insn *insn)
  369. {
  370. unsigned vreg = fetch_byte() >> 4;
  371. if (! insn->is_64) vreg &= 7;
  372. dis_sprintf("%s%d", vector_reg_name[insn->vex_l], vreg);
  373. }
  374. void disassembler::Hdq(const x86_insn *insn)
  375. {
  376. dis_sprintf("%s%d", vector_reg_name[insn->vex_l], insn->vex_vvv);
  377. }
  378. void disassembler::Hps(const x86_insn *insn) { Hdq(insn); }
  379. void disassembler::Hpd(const x86_insn *insn) { Hdq(insn); }
  380. void disassembler::Hss(const x86_insn *insn) { Hdq(insn); }
  381. void disassembler::Hsd(const x86_insn *insn) { Hdq(insn); }
  382. void disassembler::Wb(const x86_insn *insn)
  383. {
  384. if (insn->mod == 3) Udq(insn);
  385. else
  386. (this->*resolve_modrm)(insn, B_SIZE);
  387. }
  388. void disassembler::Ww(const x86_insn *insn)
  389. {
  390. if (insn->mod == 3) Udq(insn);
  391. else
  392. (this->*resolve_modrm)(insn, W_SIZE);
  393. }
  394. void disassembler::Wd(const x86_insn *insn)
  395. {
  396. if (insn->mod == 3) Udq(insn);
  397. else
  398. (this->*resolve_modrm)(insn, D_SIZE);
  399. }
  400. void disassembler::Wq(const x86_insn *insn)
  401. {
  402. if (insn->mod == 3) Udq(insn);
  403. else
  404. (this->*resolve_modrm)(insn, Q_SIZE);
  405. }
  406. void disassembler::Wdq(const x86_insn *insn)
  407. {
  408. if (insn->mod == 3) Udq(insn);
  409. else
  410. (this->*resolve_modrm)(insn, XMM_SIZE + insn->vex_l);
  411. }
  412. void disassembler::Wsd(const x86_insn *insn) { Wq(insn); }
  413. void disassembler::Wss(const x86_insn *insn) { Wd(insn); }
  414. void disassembler::Wpd(const x86_insn *insn) { Wdq(insn); }
  415. void disassembler::Wps(const x86_insn *insn) { Wdq(insn); }
  416. // direct memory access
  417. void disassembler::OP_O(const x86_insn *insn, unsigned size)
  418. {
  419. const char *seg;
  420. if (insn->is_seg_override())
  421. seg = segment_name[insn->seg_override];
  422. else
  423. seg = segment_name[DS_REG];
  424. print_datasize(size);
  425. if (insn->as_64) {
  426. Bit64u imm64 = fetch_qword();
  427. dis_sprintf("%s:0x%08x%08x", seg, GET32H(imm64), GET32L(imm64));
  428. }
  429. else if (insn->as_32) {
  430. Bit32u imm32 = fetch_dword();
  431. dis_sprintf("%s:0x%08x", seg, (unsigned) imm32);
  432. }
  433. else {
  434. Bit16u imm16 = fetch_word();
  435. dis_sprintf("%s:0x%04x", seg, (unsigned) imm16);
  436. }
  437. }
  438. void disassembler::Ob(const x86_insn *insn) { OP_O(insn, B_SIZE); }
  439. void disassembler::Ow(const x86_insn *insn) { OP_O(insn, W_SIZE); }
  440. void disassembler::Od(const x86_insn *insn) { OP_O(insn, D_SIZE); }
  441. void disassembler::Oq(const x86_insn *insn) { OP_O(insn, Q_SIZE); }
  442. // memory operand
  443. void disassembler::OP_M(const x86_insn *insn, unsigned size)
  444. {
  445. if(insn->mod == 3)
  446. dis_sprintf("(bad)");
  447. else
  448. (this->*resolve_modrm)(insn, size);
  449. }
  450. void disassembler::Ma(const x86_insn *insn) { OP_M(insn, X_SIZE); }
  451. void disassembler::Mp(const x86_insn *insn) { OP_M(insn, X_SIZE); }
  452. void disassembler::Ms(const x86_insn *insn) { OP_M(insn, X_SIZE); }
  453. void disassembler::Mx(const x86_insn *insn) { OP_M(insn, X_SIZE); }
  454. void disassembler::Mb(const x86_insn *insn) { OP_M(insn, B_SIZE); }
  455. void disassembler::Mw(const x86_insn *insn) { OP_M(insn, W_SIZE); }
  456. void disassembler::Md(const x86_insn *insn) { OP_M(insn, D_SIZE); }
  457. void disassembler::Mq(const x86_insn *insn) { OP_M(insn, Q_SIZE); }
  458. void disassembler::Mt(const x86_insn *insn) { OP_M(insn, T_SIZE); }
  459. void disassembler::Mdq(const x86_insn *insn) { OP_M(insn, XMM_SIZE + insn->vex_l); }
  460. void disassembler::Mps(const x86_insn *insn) { OP_M(insn, XMM_SIZE + insn->vex_l); }
  461. void disassembler::Mpd(const x86_insn *insn) { OP_M(insn, XMM_SIZE + insn->vex_l); }
  462. void disassembler::Mss(const x86_insn *insn) { OP_M(insn, D_SIZE); }
  463. void disassembler::Msd(const x86_insn *insn) { OP_M(insn, Q_SIZE); }
  464. // gather VSib
  465. void disassembler::VSib(const x86_insn *insn)
  466. {
  467. if(insn->mod == 3)
  468. dis_sprintf("(bad)");
  469. else
  470. (this->*resolve_modrm)(insn, (XMM_SIZE + insn->vex_l) | VSIB_Index);
  471. }
  472. // string instructions
  473. void disassembler::OP_X(const x86_insn *insn, unsigned size)
  474. {
  475. const char *rsi, *seg;
  476. if (insn->as_64) {
  477. rsi = general_64bit_regname[rSI_REG];
  478. }
  479. else {
  480. if (insn->as_32)
  481. rsi = general_32bit_regname[rSI_REG];
  482. else
  483. rsi = general_16bit_regname[rSI_REG];
  484. }
  485. if (insn->is_seg_override())
  486. seg = segment_name[insn->seg_override];
  487. else
  488. seg = segment_name[DS_REG];
  489. print_datasize(size);
  490. if (intel_mode)
  491. dis_sprintf("%s:[%s]", seg, rsi);
  492. else
  493. dis_sprintf("%s:(%s)", seg, rsi);
  494. }
  495. void disassembler::Xb(const x86_insn *insn) { OP_X(insn, B_SIZE); }
  496. void disassembler::Xw(const x86_insn *insn) { OP_X(insn, W_SIZE); }
  497. void disassembler::Xd(const x86_insn *insn) { OP_X(insn, D_SIZE); }
  498. void disassembler::Xq(const x86_insn *insn) { OP_X(insn, Q_SIZE); }
  499. void disassembler::OP_Y(const x86_insn *insn, unsigned size)
  500. {
  501. const char *rdi;
  502. if (insn->as_64) {
  503. rdi = general_64bit_regname[rDI_REG];
  504. }
  505. else {
  506. if (insn->as_32)
  507. rdi = general_32bit_regname[rDI_REG];
  508. else
  509. rdi = general_16bit_regname[rDI_REG];
  510. }
  511. print_datasize(size);
  512. if (intel_mode)
  513. dis_sprintf("%s:[%s]", segment_name[ES_REG], rdi);
  514. else
  515. dis_sprintf("%s:(%s)", segment_name[ES_REG], rdi);
  516. }
  517. void disassembler::Yb(const x86_insn *insn) { OP_Y(insn, B_SIZE); }
  518. void disassembler::Yw(const x86_insn *insn) { OP_Y(insn, W_SIZE); }
  519. void disassembler::Yd(const x86_insn *insn) { OP_Y(insn, D_SIZE); }
  520. void disassembler::Yq(const x86_insn *insn) { OP_Y(insn, Q_SIZE); }
  521. void disassembler::OP_sY(const x86_insn *insn, unsigned size)
  522. {
  523. const char *rdi, *seg;
  524. if (insn->as_64) {
  525. rdi = general_64bit_regname[rDI_REG];
  526. }
  527. else {
  528. if (insn->as_32)
  529. rdi = general_32bit_regname[rDI_REG];
  530. else
  531. rdi = general_16bit_regname[rDI_REG];
  532. }
  533. print_datasize(size);
  534. if (insn->is_seg_override())
  535. seg = segment_name[insn->seg_override];
  536. else
  537. seg = segment_name[DS_REG];
  538. if (intel_mode)
  539. dis_sprintf("%s:[%s]", seg, rdi);
  540. else
  541. dis_sprintf("%s:(%s)", seg, rdi);
  542. }
  543. void disassembler::sYq(const x86_insn *insn) { OP_sY(insn, Q_SIZE); }
  544. void disassembler::sYdq(const x86_insn *insn) { OP_sY(insn, XMM_SIZE + insn->vex_l); }
  545. #define BX_JUMP_TARGET_NOT_REQ ((bx_address)(-1))
  546. // jump offset
  547. void disassembler::Jb(const x86_insn *insn)
  548. {
  549. Bit8s imm8 = (Bit8s) fetch_byte();
  550. if (insn->is_64) {
  551. Bit64u imm64 = (Bit8s) imm8;
  552. if (offset_mode_hex) {
  553. dis_sprintf(".+0x%08x%08x", GET32H(imm64), GET32L(imm64));
  554. }
  555. else {
  556. dis_sprintf(".%+d", (int) imm8);
  557. }
  558. if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
  559. Bit64u target = db_eip + imm64;
  560. target += db_cs_base;
  561. dis_sprintf(" (0x%08x%08x)", GET32H(target), GET32L(target));
  562. }
  563. return;
  564. }
  565. if (insn->os_32) {
  566. Bit32u imm32 = (Bit8s) imm8;
  567. if (offset_mode_hex) {
  568. dis_sprintf(".+0x%08x", (unsigned) imm32);
  569. }
  570. else {
  571. dis_sprintf(".%+d", (int) imm8);
  572. }
  573. if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
  574. Bit32u target = (Bit32u)(db_cs_base + db_eip + (Bit32s) imm32);
  575. dis_sprintf(" (0x%08x)", target);
  576. }
  577. }
  578. else {
  579. Bit16u imm16 = (Bit8s) imm8;
  580. if (offset_mode_hex) {
  581. dis_sprintf(".+0x%04x", (unsigned) imm16);
  582. }
  583. else {
  584. dis_sprintf(".%+d", (int) imm8);
  585. }
  586. if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
  587. Bit16u target = (Bit16u)((db_eip + (Bit16s) imm16) & 0xffff);
  588. dis_sprintf(" (0x%08x)", target + db_cs_base);
  589. }
  590. }
  591. }
  592. void disassembler::Jw(const x86_insn *insn)
  593. {
  594. // Jw supported in 16-bit mode only
  595. assert(! insn->is_64);
  596. Bit16s imm16 = (Bit16s) fetch_word();
  597. if (offset_mode_hex) {
  598. dis_sprintf(".+0x%04x", (unsigned) (Bit16u) imm16);
  599. }
  600. else {
  601. dis_sprintf(".%+d", (int) imm16);
  602. }
  603. if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
  604. Bit16u target = (db_eip + imm16) & 0xffff;
  605. dis_sprintf(" (0x%08x)", target + db_cs_base);
  606. }
  607. }
  608. void disassembler::Jd(const x86_insn *insn)
  609. {
  610. Bit32s imm32 = (Bit32s) fetch_dword();
  611. if (insn->is_64) {
  612. Bit64u imm64 = (Bit32s) imm32;
  613. if (offset_mode_hex) {
  614. dis_sprintf(".+0x%08x%08x", GET32H(imm64), GET32L(imm64));
  615. }
  616. else {
  617. dis_sprintf(".%+d", (int) imm32);
  618. }
  619. if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
  620. Bit64u target = db_cs_base + db_eip + (Bit64s) imm64;
  621. dis_sprintf(" (0x%08x%08x)", GET32H(target), GET32L(target));
  622. }
  623. return;
  624. }
  625. if (offset_mode_hex) {
  626. dis_sprintf(".+0x%08x", (unsigned) imm32);
  627. }
  628. else {
  629. dis_sprintf(".%+d", (int) imm32);
  630. }
  631. if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
  632. Bit32u target = (Bit32u)(db_cs_base + db_eip + (Bit32s) imm32);
  633. dis_sprintf(" (0x%08x)", target);
  634. }
  635. }