]> andersk Git - udis86.git/blob - libudis86/syn-intel.c
Initial commit
[udis86.git] / libudis86 / syn-intel.c
1 /* udis86 - libudis86/syn-intel.c
2  *
3  * Copyright (c) 2002-2009 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
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   switch(op->size) {
40         case  8: mkasm(u, "byte " ); break;
41         case 16: mkasm(u, "word " ); break;
42         case 32: mkasm(u, "dword "); break;
43         case 64: mkasm(u, "qword "); break;
44         case 80: mkasm(u, "tword "); break;
45         default: break;
46   }
47   if (u->br_far)
48         mkasm(u, "far "); 
49   else if (u->br_near)
50         mkasm(u, "near ");
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                 mkasm(u, ud_reg_tab[op->base - UD_R_AL]);
62                 break;
63
64         case UD_OP_MEM: {
65
66                 int op_f = 0;
67
68                 if (syn_cast) 
69                         opr_cast(u, op);
70
71                 mkasm(u, "[");
72
73                 if (u->pfx_seg)
74                         mkasm(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
75
76                 if (op->base) {
77                         mkasm(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
78                         op_f = 1;
79                 }
80
81                 if (op->index) {
82                         if (op_f)
83                                 mkasm(u, "+");
84                         mkasm(u, "%s", ud_reg_tab[op->index - UD_R_AL]);
85                         op_f = 1;
86                 }
87
88                 if (op->scale)
89                         mkasm(u, "*%d", op->scale);
90
91                 if (op->offset == 8) {
92                         if (op->lval.sbyte < 0)
93                                 mkasm(u, "-0x%x", -op->lval.sbyte);
94                         else    mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sbyte);
95                 }
96                 else if (op->offset == 16)
97                         mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.uword);
98                 else if (op->offset == 32) {
99                         if (u->adr_mode == 64) {
100                                 if (op->lval.sdword < 0)
101                                         mkasm(u, "-0x%x", -op->lval.sdword);
102                                 else    mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sdword);
103                         } 
104                         else    mkasm(u, "%s0x%lx", (op_f) ? "+" : "", op->lval.udword);
105                 }
106                 else if (op->offset == 64) 
107                         mkasm(u, "%s0x" FMT64 "x", (op_f) ? "+" : "", op->lval.uqword);
108
109                 mkasm(u, "]");
110                 break;
111         }
112                         
113         case UD_OP_IMM:
114                 if (syn_cast) opr_cast(u, op);
115                 switch (op->size) {
116                         case  8: mkasm(u, "0x%x", op->lval.ubyte);    break;
117                         case 16: mkasm(u, "0x%x", op->lval.uword);    break;
118                         case 32: mkasm(u, "0x%lx", op->lval.udword);  break;
119                         case 64: mkasm(u, "0x" FMT64 "x", op->lval.uqword); break;
120                         default: break;
121                 }
122                 break;
123
124         case UD_OP_JIMM:
125                 if (syn_cast) opr_cast(u, op);
126                 switch (op->size) {
127                         case  8:
128                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte); 
129                                 break;
130                         case 16:
131                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
132                                 break;
133                         case 32:
134                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
135                                 break;
136                         default:break;
137                 }
138                 break;
139
140         case UD_OP_PTR:
141                 switch (op->size) {
142                         case 32:
143                                 mkasm(u, "word 0x%x:0x%x", op->lval.ptr.seg, 
144                                         op->lval.ptr.off & 0xFFFF);
145                                 break;
146                         case 48:
147                                 mkasm(u, "dword 0x%x:0x%lx", op->lval.ptr.seg, 
148                                         op->lval.ptr.off);
149                                 break;
150                 }
151                 break;
152
153         case UD_OP_CONST:
154                 if (syn_cast) opr_cast(u, op);
155                 mkasm(u, "%d", op->lval.udword);
156                 break;
157
158         default: return;
159   }
160 }
161
162 /* =============================================================================
163  * translates to intel syntax 
164  * =============================================================================
165  */
166 extern void ud_translate_intel(struct ud* u)
167 {
168   /* -- prefixes -- */
169
170   /* check if P_OSO prefix is used */
171   if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
172         switch (u->dis_mode) {
173                 case 16: 
174                         mkasm(u, "o32 ");
175                         break;
176                 case 32:
177                 case 64:
178                         mkasm(u, "o16 ");
179                         break;
180         }
181   }
182
183   /* check if P_ASO prefix was used */
184   if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
185         switch (u->dis_mode) {
186                 case 16: 
187                         mkasm(u, "a32 ");
188                         break;
189                 case 32:
190                         mkasm(u, "a16 ");
191                         break;
192                 case 64:
193                         mkasm(u, "a32 ");
194                         break;
195         }
196   }
197
198   if (u->pfx_lock)
199         mkasm(u, "lock ");
200   if (u->pfx_rep)
201         mkasm(u, "rep ");
202   if (u->pfx_repne)
203         mkasm(u, "repne ");
204   if (u->implicit_addr && u->pfx_seg)
205         mkasm(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
206
207   /* print the instruction mnemonic */
208   mkasm(u, "%s ", ud_lookup_mnemonic(u->mnemonic));
209
210   /* operand 1 */
211   if (u->operand[0].type != UD_NONE) {
212         gen_operand(u, &u->operand[0], u->c1);
213   }
214   /* operand 2 */
215   if (u->operand[1].type != UD_NONE) {
216         mkasm(u, ", ");
217         gen_operand(u, &u->operand[1], u->c2);
218   }
219
220   /* operand 3 */
221   if (u->operand[2].type != UD_NONE) {
222         mkasm(u, ", ");
223         gen_operand(u, &u->operand[2], u->c3);
224   }
225 }
This page took 0.509774 seconds and 5 git commands to generate.