resolve.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. /////////////////////////////////////////////////////////////////////////
  2. // $Id: resolve.cc 11863 2013-10-07 19:23:19Z sshwarts $
  3. /////////////////////////////////////////////////////////////////////////
  4. //
  5. // Copyright (c) 2005-2013 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. //
  22. /////////////////////////////////////////////////////////////////////////
  23. #include <stdio.h>
  24. #include <assert.h>
  25. #include "disasm.h"
  26. void disassembler::decode_modrm(x86_insn *insn)
  27. {
  28. insn->modrm = fetch_byte();
  29. BX_DECODE_MODRM(insn->modrm, insn->mod, insn->nnn, insn->rm);
  30. // MOVs with CRx and DRx always use register ops and ignore the mod field.
  31. if ((insn->b1 & ~3) == 0x120) insn->mod = 3;
  32. insn->nnn |= insn->rex_r;
  33. insn->rm |= insn->rex_b;
  34. if (insn->mod == 3) {
  35. return; /* mod, reg, reg */
  36. }
  37. if (insn->as_64)
  38. {
  39. if ((insn->rm & 7) != 4) { /* rm != 100b, no s-i-b byte */
  40. // one byte modrm
  41. switch (insn->mod) {
  42. case 0:
  43. resolve_modrm = &disassembler::resolve64_mod0;
  44. if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
  45. insn->displacement.displ32 = fetch_dword();
  46. break;
  47. case 1:
  48. /* reg, 8-bit displacement, sign extend */
  49. resolve_modrm = &disassembler::resolve64_mod1or2;
  50. insn->displacement.displ32 = (Bit8s) fetch_byte();
  51. break;
  52. case 2:
  53. /* reg, 32-bit displacement */
  54. resolve_modrm = &disassembler::resolve64_mod1or2;
  55. insn->displacement.displ32 = fetch_dword();
  56. break;
  57. } /* switch (mod) */
  58. } /* if (rm != 4) */
  59. else { /* rm == 4, s-i-b byte follows */
  60. insn->sib = fetch_byte();
  61. BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
  62. insn->base |= insn->rex_b;
  63. insn->index |= insn->rex_x;
  64. switch (insn->mod) {
  65. case 0:
  66. resolve_modrm = &disassembler::resolve64_mod0_rm4;
  67. if ((insn->base & 7) == 5)
  68. insn->displacement.displ32 = fetch_dword();
  69. break;
  70. case 1:
  71. resolve_modrm = &disassembler::resolve64_mod1or2_rm4;
  72. insn->displacement.displ32 = (Bit8s) fetch_byte();
  73. break;
  74. case 2:
  75. resolve_modrm = &disassembler::resolve64_mod1or2_rm4;
  76. insn->displacement.displ32 = fetch_dword();
  77. break;
  78. }
  79. } /* s-i-b byte follows */
  80. }
  81. else
  82. {
  83. if (insn->as_32)
  84. {
  85. if ((insn->rm & 7) != 4) { /* rm != 100b, no s-i-b byte */
  86. // one byte modrm
  87. switch (insn->mod) {
  88. case 0:
  89. resolve_modrm = &disassembler::resolve32_mod0;
  90. if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
  91. insn->displacement.displ32 = fetch_dword();
  92. break;
  93. case 1:
  94. /* reg, 8-bit displacement, sign extend */
  95. resolve_modrm = &disassembler::resolve32_mod1or2;
  96. insn->displacement.displ32 = (Bit8s) fetch_byte();
  97. break;
  98. case 2:
  99. /* reg, 32-bit displacement */
  100. resolve_modrm = &disassembler::resolve32_mod1or2;
  101. insn->displacement.displ32 = fetch_dword();
  102. break;
  103. } /* switch (mod) */
  104. } /* if (rm != 4) */
  105. else { /* rm == 4, s-i-b byte follows */
  106. insn->sib = fetch_byte();
  107. BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
  108. insn->base |= insn->rex_b;
  109. insn->index |= insn->rex_x;
  110. switch (insn->mod) {
  111. case 0:
  112. resolve_modrm = &disassembler::resolve32_mod0_rm4;
  113. if ((insn->base & 7) == 5)
  114. insn->displacement.displ32 = fetch_dword();
  115. break;
  116. case 1:
  117. resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
  118. insn->displacement.displ32 = (Bit8s) fetch_byte();
  119. break;
  120. case 2:
  121. resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
  122. insn->displacement.displ32 = fetch_dword();
  123. break;
  124. }
  125. } /* s-i-b byte follows */
  126. }
  127. else {
  128. assert(insn->rex_b == 0);
  129. assert(insn->rex_x == 0);
  130. assert(insn->rex_r == 0);
  131. /* 16 bit addressing modes. */
  132. switch (insn->mod) {
  133. case 0:
  134. resolve_modrm = &disassembler::resolve16_mod0;
  135. if(insn->rm == 6)
  136. insn->displacement.displ16 = fetch_word();
  137. break;
  138. case 1:
  139. /* reg, 8-bit displacement, sign extend */
  140. resolve_modrm = &disassembler::resolve16_mod1or2;
  141. insn->displacement.displ16 = (Bit8s) fetch_byte();
  142. break;
  143. case 2:
  144. resolve_modrm = &disassembler::resolve16_mod1or2;
  145. insn->displacement.displ16 = fetch_word();
  146. break;
  147. } /* switch (mod) ... */
  148. }
  149. }
  150. }
  151. void disassembler::resolve16_mod0(const x86_insn *insn, unsigned datasize)
  152. {
  153. const char *seg;
  154. if (insn->is_seg_override())
  155. seg = segment_name[insn->seg_override];
  156. else
  157. seg = sreg_mod00_rm16[insn->rm];
  158. if(insn->rm == 6)
  159. print_memory_access16(datasize, seg, NULL, insn->displacement.displ16);
  160. else
  161. print_memory_access16(datasize, seg, index16[insn->rm], 0);
  162. }
  163. void disassembler::resolve16_mod1or2(const x86_insn *insn, unsigned datasize)
  164. {
  165. const char *seg;
  166. if (insn->is_seg_override())
  167. seg = segment_name[insn->seg_override];
  168. else
  169. seg = sreg_mod01or10_rm16[insn->rm];
  170. print_memory_access16(datasize, seg, index16[insn->rm], insn->displacement.displ16);
  171. }
  172. void disassembler::resolve32_mod0(const x86_insn *insn, unsigned datasize)
  173. {
  174. const char *seg, *eip_regname = NULL;
  175. if (insn->is_seg_override())
  176. seg = segment_name[insn->seg_override];
  177. else
  178. seg = segment_name[DS_REG];
  179. if (insn->is_64) {
  180. if (intel_mode) eip_regname = "eip";
  181. else eip_regname = "%eip";
  182. }
  183. if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
  184. print_memory_access32(datasize, seg, eip_regname, NULL, 0, insn->displacement.displ32);
  185. else
  186. print_memory_access32(datasize, seg, general_32bit_regname[insn->rm], NULL, 0, 0);
  187. }
  188. void disassembler::resolve32_mod1or2(const x86_insn *insn, unsigned datasize)
  189. {
  190. const char *seg;
  191. if (insn->is_seg_override())
  192. seg = segment_name[insn->seg_override];
  193. else
  194. seg = sreg_mod01or10_base32[insn->rm];
  195. print_memory_access32(datasize, seg,
  196. general_32bit_regname[insn->rm], NULL, 0, insn->displacement.displ32);
  197. }
  198. void disassembler::resolve32_mod0_rm4(const x86_insn *insn, unsigned datasize)
  199. {
  200. char vsib_index[8];
  201. const char *seg, *base = NULL, *index = NULL;
  202. Bit32u disp32 = 0;
  203. if (insn->is_seg_override())
  204. seg = segment_name[insn->seg_override];
  205. else
  206. seg = sreg_mod00_base32[insn->base];
  207. if ((insn->base & 7) != 5)
  208. base = general_32bit_regname[insn->base];
  209. else
  210. disp32 = insn->displacement.displ32;
  211. if (datasize & VSIB_Index) {
  212. sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
  213. index = vsib_index;
  214. }
  215. else {
  216. if (insn->index != 4)
  217. index = general_32bit_regname[insn->index];
  218. }
  219. print_memory_access32(datasize, seg, base, index, insn->scale, disp32);
  220. }
  221. void disassembler::resolve32_mod1or2_rm4(const x86_insn *insn, unsigned datasize)
  222. {
  223. char vsib_index[8];
  224. const char *seg, *index = NULL;
  225. if (insn->is_seg_override())
  226. seg = segment_name[insn->seg_override];
  227. else
  228. seg = sreg_mod01or10_base32[insn->base];
  229. if (datasize & VSIB_Index) {
  230. sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
  231. index = vsib_index;
  232. }
  233. else {
  234. if (insn->index != 4)
  235. index = general_32bit_regname[insn->index];
  236. }
  237. print_memory_access32(datasize, seg,
  238. general_32bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
  239. }
  240. void disassembler::resolve64_mod0(const x86_insn *insn, unsigned datasize)
  241. {
  242. const char *seg, *rip_regname;
  243. if (insn->is_seg_override())
  244. seg = segment_name[insn->seg_override];
  245. else
  246. seg = segment_name[DS_REG];
  247. if (intel_mode) rip_regname = "rip";
  248. else rip_regname = "%rip";
  249. if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
  250. print_memory_access64(datasize, seg, rip_regname, NULL, 0, (Bit32s) insn->displacement.displ32);
  251. else
  252. print_memory_access64(datasize, seg, general_64bit_regname[insn->rm], NULL, 0, 0);
  253. }
  254. void disassembler::resolve64_mod1or2(const x86_insn *insn, unsigned datasize)
  255. {
  256. const char *seg;
  257. if (insn->is_seg_override())
  258. seg = segment_name[insn->seg_override];
  259. else
  260. seg = sreg_mod01or10_base32[insn->rm];
  261. print_memory_access64(datasize, seg,
  262. general_64bit_regname[insn->rm], NULL, 0, (Bit32s) insn->displacement.displ32);
  263. }
  264. void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned datasize)
  265. {
  266. char vsib_index[8];
  267. const char *seg, *base = NULL, *index = NULL;
  268. Bit32s disp32 = 0;
  269. if (insn->is_seg_override())
  270. seg = segment_name[insn->seg_override];
  271. else
  272. seg = sreg_mod00_base32[insn->base];
  273. if ((insn->base & 7) != 5)
  274. base = general_64bit_regname[insn->base];
  275. else
  276. disp32 = (Bit32s) insn->displacement.displ32;
  277. if (datasize & VSIB_Index) {
  278. sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
  279. index = vsib_index;
  280. }
  281. else {
  282. if (insn->index != 4)
  283. index = general_64bit_regname[insn->index];
  284. }
  285. print_memory_access64(datasize, seg, base, index, insn->scale, disp32);
  286. }
  287. void disassembler::resolve64_mod1or2_rm4(const x86_insn *insn, unsigned datasize)
  288. {
  289. char vsib_index[8];
  290. const char *seg, *index = NULL;
  291. if (insn->is_seg_override())
  292. seg = segment_name[insn->seg_override];
  293. else
  294. seg = sreg_mod01or10_base32[insn->base];
  295. if (datasize & VSIB_Index) {
  296. sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
  297. index = vsib_index;
  298. }
  299. else {
  300. if (insn->index != 4)
  301. index = general_64bit_regname[insn->index];
  302. }
  303. print_memory_access64(datasize, seg,
  304. general_64bit_regname[insn->base], index, insn->scale, (Bit32s) insn->displacement.displ32);
  305. }
  306. void disassembler::print_datasize(unsigned size)
  307. {
  308. if (!intel_mode || !print_mem_datasize) return;
  309. switch(size & 0xf)
  310. {
  311. case B_SIZE:
  312. dis_sprintf("byte ptr ");
  313. break;
  314. case W_SIZE:
  315. dis_sprintf("word ptr ");
  316. break;
  317. case D_SIZE:
  318. dis_sprintf("dword ptr ");
  319. break;
  320. case Q_SIZE:
  321. dis_sprintf("qword ptr ");
  322. break;
  323. case T_SIZE:
  324. dis_sprintf("tbyte ptr ");
  325. break;
  326. case XMM_SIZE:
  327. dis_sprintf("dqword ptr ");
  328. break;
  329. case YMM_SIZE:
  330. dis_sprintf("qqword ptr ");
  331. break;
  332. case X_SIZE:
  333. break;
  334. };
  335. }
  336. void disassembler::print_memory_access16(int datasize,
  337. const char *seg, const char *index, Bit16u disp)
  338. {
  339. print_datasize(datasize);
  340. dis_sprintf("%s:", seg);
  341. if (intel_mode)
  342. {
  343. if (index == NULL)
  344. {
  345. dis_sprintf("0x%04x", (unsigned) disp);
  346. }
  347. else
  348. {
  349. if (disp != 0) {
  350. if (offset_mode_hex)
  351. dis_sprintf("[%s+0x%04x]", index, (unsigned) disp);
  352. else
  353. dis_sprintf("[%s%+d]", index, (int) (Bit16s) disp);
  354. }
  355. else
  356. dis_sprintf("[%s]", index);
  357. }
  358. }
  359. else
  360. {
  361. if (index == NULL)
  362. {
  363. dis_sprintf("0x%04x", (unsigned) disp);
  364. }
  365. else
  366. {
  367. if (disp != 0) {
  368. if (offset_mode_hex)
  369. dis_sprintf("0x%04x(%s,1)", (unsigned) disp, index);
  370. else
  371. dis_sprintf("%d(%s,1)", (int) (Bit16s) disp, index);
  372. }
  373. else
  374. dis_sprintf("(%s,1)", index);
  375. }
  376. }
  377. }
  378. void disassembler::print_memory_access32(int datasize,
  379. const char *seg, const char *base, const char *index, int scale, Bit32s disp)
  380. {
  381. print_datasize(datasize);
  382. dis_sprintf("%s:", seg);
  383. scale = 1 << scale;
  384. if (intel_mode)
  385. {
  386. if (base == NULL)
  387. {
  388. if (index == NULL)
  389. {
  390. dis_sprintf("0x%08x", (unsigned) disp);
  391. }
  392. else
  393. {
  394. if (scale != 1)
  395. {
  396. if (disp != 0) {
  397. if (offset_mode_hex)
  398. dis_sprintf("[%s*%d+0x%08x]", index, scale, (unsigned) disp);
  399. else
  400. dis_sprintf("[%s*%d%+d]", index, scale, (int) disp);
  401. }
  402. else
  403. dis_sprintf("[%s*%d]", index, scale);
  404. }
  405. else
  406. {
  407. if (disp != 0) {
  408. if (offset_mode_hex)
  409. dis_sprintf("[%s+0x%08x]", index, (unsigned) disp);
  410. else
  411. dis_sprintf("[%s%+d]", index, (int) disp);
  412. }
  413. else {
  414. dis_sprintf("[%s]", index);
  415. }
  416. }
  417. }
  418. }
  419. else
  420. {
  421. if (index == NULL)
  422. {
  423. if (disp != 0) {
  424. if (offset_mode_hex)
  425. dis_sprintf("[%s+0x%08x]", base, (unsigned) disp);
  426. else
  427. dis_sprintf("[%s%+d]", base, (int) disp);
  428. }
  429. else {
  430. dis_sprintf("[%s]", base);
  431. }
  432. }
  433. else
  434. {
  435. if (scale != 1)
  436. {
  437. if (disp != 0) {
  438. if (offset_mode_hex)
  439. dis_sprintf("[%s+%s*%d+0x%08x]", base, index, scale, (unsigned) disp);
  440. else
  441. dis_sprintf("[%s+%s*%d%+d]", base, index, scale, (int) disp);
  442. }
  443. else {
  444. dis_sprintf("[%s+%s*%d]", base, index, scale);
  445. }
  446. }
  447. else
  448. {
  449. if (disp != 0) {
  450. if (offset_mode_hex)
  451. dis_sprintf("[%s+%s+0x%08x]", base, index, (unsigned) disp);
  452. else
  453. dis_sprintf("[%s+%s%+d]", base, index, (int) disp);
  454. }
  455. else
  456. dis_sprintf("[%s+%s]", base, index);
  457. }
  458. }
  459. }
  460. }
  461. else
  462. {
  463. if (base == NULL)
  464. {
  465. if (index == NULL)
  466. {
  467. dis_sprintf("0x%08x", (unsigned) disp);
  468. }
  469. else
  470. {
  471. if (disp != 0) {
  472. if (offset_mode_hex)
  473. dis_sprintf("0x%08x(,%s,%d)", (unsigned) disp, index, scale);
  474. else
  475. dis_sprintf("%d(,%s,%d)", (int) disp, index, scale);
  476. }
  477. else
  478. dis_sprintf("(,%s,%d)", index, scale);
  479. }
  480. }
  481. else
  482. {
  483. if (index == NULL)
  484. {
  485. if (disp != 0) {
  486. if (offset_mode_hex)
  487. dis_sprintf("0x%08x(%s)", (unsigned) disp, base);
  488. else
  489. dis_sprintf("%d(%s)", (int) disp, base);
  490. }
  491. else
  492. dis_sprintf("(%s)", base);
  493. }
  494. else
  495. {
  496. if (disp != 0) {
  497. if (offset_mode_hex)
  498. dis_sprintf("0x%08x(%s,%s,%d)", (unsigned) disp, base, index, scale);
  499. else
  500. dis_sprintf("%d(%s,%s,%d)", (int) disp, base, index, scale);
  501. }
  502. else
  503. dis_sprintf("(%s,%s,%d)", base, index, scale);
  504. }
  505. }
  506. }
  507. }
  508. void disassembler::print_memory_access64(int datasize,
  509. const char *seg, const char *base, const char *index, int scale, Bit32s disp)
  510. {
  511. Bit64u disp64 = (Bit64s) disp;
  512. print_datasize(datasize);
  513. dis_sprintf("%s:", seg);
  514. scale = 1 << scale;
  515. if (intel_mode)
  516. {
  517. if (base == NULL)
  518. {
  519. if (index == NULL)
  520. {
  521. dis_sprintf("0x%08x%08x", GET32H(disp64), GET32L(disp64));
  522. }
  523. else
  524. {
  525. if (scale != 1)
  526. {
  527. if (disp != 0) {
  528. if (offset_mode_hex)
  529. dis_sprintf("[%s*%d+0x%08x%08x]", index, scale, GET32H(disp64), GET32L(disp64));
  530. else
  531. dis_sprintf("[%s*%d%+d]", index, scale, (int) disp);
  532. }
  533. else
  534. dis_sprintf("[%s*%d]", index, scale);
  535. }
  536. else
  537. {
  538. if (disp != 0) {
  539. if (offset_mode_hex)
  540. dis_sprintf("[%s+0x%08x%08x]", index, GET32H(disp64), GET32L(disp64));
  541. else
  542. dis_sprintf("[%s%+d]", index, (int) disp);
  543. }
  544. else {
  545. dis_sprintf("[%s]", index);
  546. }
  547. }
  548. }
  549. }
  550. else
  551. {
  552. if (index == NULL)
  553. {
  554. if (disp != 0) {
  555. if (offset_mode_hex)
  556. dis_sprintf("[%s+0x%08x%08x]", base, GET32H(disp64), GET32L(disp64));
  557. else
  558. dis_sprintf("[%s%+d]", base, (int) disp);
  559. }
  560. else {
  561. dis_sprintf("[%s]", base);
  562. }
  563. }
  564. else
  565. {
  566. if (scale != 1)
  567. {
  568. if (disp != 0) {
  569. if (offset_mode_hex)
  570. dis_sprintf("[%s+%s*%d+0x%08x%08x]", base, index, scale, GET32H(disp64), GET32L(disp64));
  571. else
  572. dis_sprintf("[%s+%s*%d%+d]", base, index, scale, (int) disp);
  573. }
  574. else {
  575. dis_sprintf("[%s+%s*%d]", base, index, scale);
  576. }
  577. }
  578. else
  579. {
  580. if (disp != 0) {
  581. if (offset_mode_hex)
  582. dis_sprintf("[%s+%s+0x%08x%08x]", base, index, GET32H(disp64), GET32L(disp64));
  583. else
  584. dis_sprintf("[%s+%s%+d]", base, index, (int) disp);
  585. }
  586. else
  587. dis_sprintf("[%s+%s]", base, index);
  588. }
  589. }
  590. }
  591. }
  592. else
  593. {
  594. if (base == NULL)
  595. {
  596. if (index == NULL)
  597. {
  598. dis_sprintf("0x%08x%08x", GET32H(disp64), GET32L(disp64));
  599. }
  600. else
  601. {
  602. if (disp != 0) {
  603. if (offset_mode_hex)
  604. dis_sprintf("0x%08x%08x(,%s,%d)", GET32H(disp64), GET32L(disp64), index, scale);
  605. else
  606. dis_sprintf("%d(,%s,%d)", (int) disp, index, scale);
  607. }
  608. else
  609. dis_sprintf("(,%s,%d)", index, scale);
  610. }
  611. }
  612. else
  613. {
  614. if (index == NULL)
  615. {
  616. if (disp != 0) {
  617. if (offset_mode_hex)
  618. dis_sprintf("0x%08x%08x(%s)", GET32H(disp64), GET32L(disp64), base);
  619. else
  620. dis_sprintf("%d(%s)", (int) disp, base);
  621. }
  622. else
  623. dis_sprintf("(%s)", base);
  624. }
  625. else
  626. {
  627. if (disp != 0) {
  628. if (offset_mode_hex)
  629. dis_sprintf("0x%08x%08x(%s,%s,%d)", GET32H(disp64), GET32L(disp64), base, index, scale);
  630. else
  631. dis_sprintf("%d(%s,%s,%d)", (int) disp, base, index, scale);
  632. }
  633. else
  634. dis_sprintf("(%s,%s,%d)", base, index, scale);
  635. }
  636. }
  637. }
  638. }