syn-intel.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* udis86 - libudis86/syn-intel.c
  2. *
  3. * Copyright (c) 2002-2013 Vivek Thampi
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "types.h"
  27. #include "extern.h"
  28. #include "decode.h"
  29. #include "itab.h"
  30. #include "syn.h"
  31. #include "udint.h"
  32. /* -----------------------------------------------------------------------------
  33. * opr_cast() - Prints an operand cast.
  34. * -----------------------------------------------------------------------------
  35. */
  36. static void
  37. opr_cast(struct ud* u, struct ud_operand* op)
  38. {
  39. if (u->br_far) {
  40. ud_asmprintf(u, "far ");
  41. }
  42. switch(op->size) {
  43. case 8: ud_asmprintf(u, "byte " ); break;
  44. case 16: ud_asmprintf(u, "word " ); break;
  45. case 32: ud_asmprintf(u, "dword "); break;
  46. case 64: ud_asmprintf(u, "qword "); break;
  47. case 80: ud_asmprintf(u, "tword "); break;
  48. case 128: ud_asmprintf(u, "oword "); break;
  49. case 256: ud_asmprintf(u, "yword "); break;
  50. default: break;
  51. }
  52. }
  53. /* -----------------------------------------------------------------------------
  54. * gen_operand() - Generates assembly output for each operand.
  55. * -----------------------------------------------------------------------------
  56. */
  57. static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
  58. {
  59. switch(op->type) {
  60. case UD_OP_REG:
  61. ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
  62. break;
  63. case UD_OP_MEM:
  64. if (syn_cast) {
  65. opr_cast(u, op);
  66. }
  67. ud_asmprintf(u, "[");
  68. if (u->pfx_seg) {
  69. ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
  70. }
  71. if (op->base) {
  72. ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
  73. }
  74. if (op->index) {
  75. ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "",
  76. ud_reg_tab[op->index - UD_R_AL]);
  77. if (op->scale) {
  78. ud_asmprintf(u, "*%d", op->scale);
  79. }
  80. }
  81. if (op->offset != 0) {
  82. ud_syn_print_mem_disp(u, op, (op->base != UD_NONE ||
  83. op->index != UD_NONE) ? 1 : 0);
  84. }
  85. ud_asmprintf(u, "]");
  86. break;
  87. case UD_OP_IMM:
  88. ud_syn_print_imm(u, op);
  89. break;
  90. case UD_OP_JIMM:
  91. ud_syn_print_addr(u, ud_syn_rel_target(u, op));
  92. break;
  93. case UD_OP_PTR:
  94. switch (op->size) {
  95. case 32:
  96. ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg,
  97. op->lval.ptr.off & 0xFFFF);
  98. break;
  99. case 48:
  100. ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg,
  101. op->lval.ptr.off);
  102. break;
  103. }
  104. break;
  105. case UD_OP_CONST:
  106. if (syn_cast) opr_cast(u, op);
  107. ud_asmprintf(u, "%d", op->lval.udword);
  108. break;
  109. default: return;
  110. }
  111. }
  112. /* =============================================================================
  113. * translates to intel syntax
  114. * =============================================================================
  115. */
  116. extern void
  117. ud_translate_intel(struct ud* u)
  118. {
  119. /* check if P_OSO prefix is used */
  120. if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
  121. switch (u->dis_mode) {
  122. case 16: ud_asmprintf(u, "o32 "); break;
  123. case 32:
  124. case 64: ud_asmprintf(u, "o16 "); break;
  125. }
  126. }
  127. /* check if P_ASO prefix was used */
  128. if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
  129. switch (u->dis_mode) {
  130. case 16: ud_asmprintf(u, "a32 "); break;
  131. case 32: ud_asmprintf(u, "a16 "); break;
  132. case 64: ud_asmprintf(u, "a32 "); break;
  133. }
  134. }
  135. if (u->pfx_seg &&
  136. u->operand[0].type != UD_OP_MEM &&
  137. u->operand[1].type != UD_OP_MEM ) {
  138. ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
  139. }
  140. if (u->pfx_lock) {
  141. ud_asmprintf(u, "lock ");
  142. }
  143. if (u->pfx_rep) {
  144. ud_asmprintf(u, "rep ");
  145. } else if (u->pfx_repe) {
  146. ud_asmprintf(u, "repe ");
  147. } else if (u->pfx_repne) {
  148. ud_asmprintf(u, "repne ");
  149. }
  150. /* print the instruction mnemonic */
  151. ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
  152. if (u->operand[0].type != UD_NONE) {
  153. int cast = 0;
  154. ud_asmprintf(u, " ");
  155. if (u->operand[0].type == UD_OP_MEM) {
  156. if (u->operand[1].type == UD_OP_IMM ||
  157. u->operand[1].type == UD_OP_CONST ||
  158. u->operand[1].type == UD_NONE ||
  159. (u->operand[0].size != u->operand[1].size)) {
  160. cast = 1;
  161. } else if (u->operand[1].type == UD_OP_REG &&
  162. u->operand[1].base == UD_R_CL) {
  163. switch (u->mnemonic) {
  164. case UD_Ircl:
  165. case UD_Irol:
  166. case UD_Iror:
  167. case UD_Ircr:
  168. case UD_Ishl:
  169. case UD_Ishr:
  170. case UD_Isar:
  171. cast = 1;
  172. break;
  173. default: break;
  174. }
  175. }
  176. }
  177. gen_operand(u, &u->operand[0], cast);
  178. }
  179. if (u->operand[1].type != UD_NONE) {
  180. int cast = 0;
  181. ud_asmprintf(u, ", ");
  182. if (u->operand[1].type == UD_OP_MEM &&
  183. u->operand[0].size != u->operand[1].size &&
  184. !ud_opr_is_sreg(&u->operand[0])) {
  185. cast = 1;
  186. }
  187. gen_operand(u, &u->operand[1], cast);
  188. }
  189. if (u->operand[2].type != UD_NONE) {
  190. int cast = 0;
  191. ud_asmprintf(u, ", ");
  192. if (u->operand[2].type == UD_OP_MEM &&
  193. u->operand[2].size != u->operand[1].size) {
  194. cast = 1;
  195. }
  196. gen_operand(u, &u->operand[2], cast);
  197. }
  198. if (u->operand[3].type != UD_NONE) {
  199. ud_asmprintf(u, ", ");
  200. gen_operand(u, &u->operand[3], 0);
  201. }
  202. }
  203. /*
  204. vim: set ts=2 sw=2 expandtab
  205. */