1
|
1 /* -----------------------------------------------------------------------------
|
|
2 * syn-intel.c
|
|
3 *
|
|
4 * Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com>
|
|
5 * All rights reserved. See (LICENSE)
|
|
6 * -----------------------------------------------------------------------------
|
|
7 */
|
|
8
|
|
9 #include "types.h"
|
|
10 #include "extern.h"
|
|
11 #include "opcmap.h"
|
|
12 #include "syn.h"
|
|
13
|
|
14 /* -----------------------------------------------------------------------------
|
|
15 * opr_cast() - Prints an operand cast.
|
|
16 * -----------------------------------------------------------------------------
|
|
17 */
|
|
18 static void
|
|
19 opr_cast(struct ud* u, struct ud_operand* op)
|
|
20 {
|
|
21 switch(op->size) {
|
|
22 case 8: mkasm(u, "byte " ); break;
|
|
23 case 16: mkasm(u, "word " ); break;
|
|
24 case 32: mkasm(u, "dword "); break;
|
|
25 case 64: mkasm(u, "qword "); break;
|
|
26 case 80: mkasm(u, "tbyte "); break;
|
|
27 default: break;
|
|
28 }
|
|
29 if (u->br_far)
|
|
30 mkasm(u, "far ");
|
|
31 else if (u->br_near)
|
|
32 mkasm(u, "near ");
|
|
33 }
|
|
34
|
|
35 /* -----------------------------------------------------------------------------
|
|
36 * gen_operand() - Generates assembly output for each operand.
|
|
37 * -----------------------------------------------------------------------------
|
|
38 */
|
|
39 static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
|
|
40 {
|
|
41 switch(op->type) {
|
|
42 case UD_OP_REG:
|
|
43 mkasm(u, ud_reg_tab[op->base - UD_R_AL]);
|
|
44 break;
|
|
45
|
|
46 case UD_OP_MEM: {
|
|
47
|
|
48 int op_f = 0;
|
|
49
|
|
50 if (syn_cast)
|
|
51 opr_cast(u, op);
|
|
52
|
|
53 mkasm(u, "[");
|
|
54
|
|
55 if (u->pfx_seg)
|
|
56 mkasm(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
|
57
|
|
58 if (op->base) {
|
|
59 mkasm(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
|
|
60 op_f = 1;
|
|
61 }
|
|
62
|
|
63 if (op->index) {
|
|
64 if (op_f)
|
|
65 mkasm(u, "+");
|
|
66 mkasm(u, "%s", ud_reg_tab[op->index - UD_R_AL]);
|
|
67 op_f = 1;
|
|
68 }
|
|
69
|
|
70 if (op->scale)
|
|
71 mkasm(u, "*%d", op->scale);
|
|
72
|
|
73 if (op->offset == 8) {
|
|
74 if (op->lval.sbyte < 0)
|
|
75 mkasm(u, "-0x%x", -op->lval.sbyte);
|
|
76 else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sbyte);
|
|
77 }
|
|
78 else if (op->offset == 16)
|
|
79 mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.uword);
|
|
80 else if (op->offset == 32) {
|
|
81 if (u->adr_mode == 64) {
|
|
82 if (op->lval.sdword < 0)
|
|
83 mkasm(u, "-0x%x", -op->lval.sdword);
|
|
84 else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sdword);
|
|
85 }
|
|
86 else mkasm(u, "%s0x%lx", (op_f) ? "+" : "", op->lval.udword);
|
|
87 }
|
|
88 else if (op->offset == 64)
|
|
89 mkasm(u, "%s0x" FMT64 "x", (op_f) ? "+" : "", op->lval.uqword);
|
|
90
|
|
91 mkasm(u, "]");
|
|
92 break;
|
|
93 }
|
|
94
|
|
95 case UD_OP_IMM:
|
|
96 if (syn_cast) opr_cast(u, op);
|
|
97 switch (op->size) {
|
|
98 case 8: mkasm(u, "0x%x", op->lval.ubyte); break;
|
|
99 case 16: mkasm(u, "0x%x", op->lval.uword); break;
|
|
100 case 32: mkasm(u, "0x%lx", op->lval.udword); break;
|
|
101 case 64: mkasm(u, "0x" FMT64 "x", op->lval.uqword); break;
|
|
102 default: break;
|
|
103 }
|
|
104 break;
|
|
105
|
|
106 case UD_OP_JIMM:
|
|
107 if (syn_cast) opr_cast(u, op);
|
|
108 switch (op->size) {
|
|
109 case 8:
|
|
110 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
|
|
111 break;
|
|
112 case 16:
|
|
113 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
|
|
114 break;
|
|
115 case 32:
|
|
116 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
|
|
117 break;
|
|
118 default:break;
|
|
119 }
|
|
120 break;
|
|
121
|
|
122 case UD_OP_PTR:
|
|
123 switch (op->size) {
|
|
124 case 32:
|
|
125 mkasm(u, "word 0x%x:0x%x", op->lval.ptr.seg,
|
|
126 op->lval.ptr.off & 0xFFFF);
|
|
127 break;
|
|
128 case 48:
|
|
129 mkasm(u, "dword 0x%x:0x%lx", op->lval.ptr.seg,
|
|
130 op->lval.ptr.off);
|
|
131 break;
|
|
132 }
|
|
133 break;
|
|
134
|
|
135 case UD_OP_CONST:
|
|
136 if (syn_cast) opr_cast(u, op);
|
|
137 mkasm(u, "%d", op->lval.udword);
|
|
138 break;
|
|
139
|
|
140 default: return;
|
|
141 }
|
|
142 }
|
|
143
|
|
144 /* =============================================================================
|
|
145 * translates to intel syntax
|
|
146 * =============================================================================
|
|
147 */
|
|
148 extern void ud_translate_intel(struct ud* u)
|
|
149 {
|
|
150 /* -- prefixes -- */
|
|
151
|
|
152 /* check if P_O32 prefix is used */
|
|
153 if (! P_O32(u->mapen->prefix) && u->pfx_opr) {
|
|
154 switch (u->dis_mode) {
|
|
155 case 16:
|
|
156 mkasm(u, "o32 ");
|
|
157 break;
|
|
158 case 32:
|
|
159 case 64:
|
|
160 mkasm(u, "o16 ");
|
|
161 break;
|
|
162 }
|
|
163 }
|
|
164
|
|
165 /* check if P_A32 prefix was used */
|
|
166 if (! P_A32(u->mapen->prefix) && u->pfx_adr) {
|
|
167 switch (u->dis_mode) {
|
|
168 case 16:
|
|
169 mkasm(u, "a32 ");
|
|
170 break;
|
|
171 case 32:
|
|
172 mkasm(u, "a16 ");
|
|
173 break;
|
|
174 case 64:
|
|
175 mkasm(u, "a32 ");
|
|
176 break;
|
|
177 }
|
|
178 }
|
|
179
|
|
180 if (u->pfx_lock)
|
|
181 mkasm(u, "lock ");
|
|
182 if (u->pfx_rep)
|
|
183 mkasm(u, "rep ");
|
|
184 if (u->pfx_repne)
|
|
185 mkasm(u, "repne ");
|
|
186
|
|
187 /* print the instruction mnemonic */
|
|
188 mkasm(u, "%s ", ud_lookup_mnemonic(u->mnemonic));
|
|
189
|
|
190 /* operand 1 */
|
|
191 if (u->operand[0].type != UD_NONE) {
|
|
192 gen_operand(u, &u->operand[0], u->c1);
|
|
193 }
|
|
194 /* operand 2 */
|
|
195 if (u->operand[1].type != UD_NONE) {
|
|
196 mkasm(u, ", ");
|
|
197 gen_operand(u, &u->operand[1], u->c2);
|
|
198 }
|
|
199
|
|
200 /* operand 3 */
|
|
201 if (u->operand[2].type != UD_NONE) {
|
|
202 mkasm(u, ", ");
|
|
203 gen_operand(u, &u->operand[2], u->c3);
|
|
204 }
|
|
205 }
|