1 |
39 |
zeus |
/////////////////////////////////////////////////////////////////////////
|
2 |
52 |
zeus |
// $Id: syntax.cc,v 1.14 2008/03/20 18:11:57 sshwarts Exp $
|
3 |
39 |
zeus |
/////////////////////////////////////////////////////////////////////////
|
4 |
|
|
|
5 |
|
|
#include <stdio.h>
|
6 |
|
|
#include "disasm.h"
|
7 |
|
|
|
8 |
|
|
//////////////////
|
9 |
|
|
// Intel STYLE
|
10 |
|
|
//////////////////
|
11 |
|
|
|
12 |
|
|
#define BX_DISASM_SUPPORT_X86_64
|
13 |
|
|
|
14 |
|
|
#ifdef BX_DISASM_SUPPORT_X86_64
|
15 |
|
|
|
16 |
|
|
static const char *intel_general_16bit_regname[16] = {
|
17 |
|
|
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
|
18 |
|
|
"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
|
19 |
|
|
};
|
20 |
|
|
|
21 |
|
|
static const char *intel_general_32bit_regname[16] = {
|
22 |
|
|
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
23 |
|
|
"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
|
24 |
|
|
};
|
25 |
|
|
|
26 |
|
|
static const char *intel_general_64bit_regname[16] = {
|
27 |
|
|
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
|
28 |
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
|
29 |
|
|
};
|
30 |
|
|
|
31 |
|
|
static const char *intel_general_8bit_regname_rex[16] = {
|
32 |
|
|
"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
|
33 |
|
|
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
|
34 |
|
|
};
|
35 |
|
|
|
36 |
|
|
#else
|
37 |
|
|
|
38 |
|
|
static const char *intel_general_16bit_regname[8] = {
|
39 |
|
|
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
|
40 |
|
|
};
|
41 |
|
|
|
42 |
|
|
static const char *intel_general_32bit_regname[8] = {
|
43 |
|
|
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
|
44 |
|
|
};
|
45 |
|
|
|
46 |
|
|
#endif
|
47 |
|
|
|
48 |
|
|
static const char *intel_general_8bit_regname[8] = {
|
49 |
|
|
"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
|
50 |
|
|
};
|
51 |
|
|
|
52 |
|
|
static const char *intel_segment_name[8] = {
|
53 |
|
|
"es", "cs", "ss", "ds", "fs", "gs", "??", "??"
|
54 |
|
|
};
|
55 |
|
|
|
56 |
|
|
static const char *intel_index16[8] = {
|
57 |
|
|
"bx+si",
|
58 |
|
|
"bx+di",
|
59 |
|
|
"bp+si",
|
60 |
|
|
"bp+di",
|
61 |
|
|
"si",
|
62 |
|
|
"di",
|
63 |
|
|
"bp",
|
64 |
|
|
"bx"
|
65 |
|
|
};
|
66 |
|
|
|
67 |
|
|
|
68 |
|
|
//////////////////
|
69 |
|
|
// AT&T STYLE
|
70 |
|
|
//////////////////
|
71 |
|
|
|
72 |
|
|
#ifdef BX_DISASM_SUPPORT_X86_64
|
73 |
|
|
|
74 |
|
|
static const char *att_general_16bit_regname[16] = {
|
75 |
|
|
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
|
76 |
|
|
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
|
77 |
|
|
};
|
78 |
|
|
|
79 |
|
|
static const char *att_general_32bit_regname[16] = {
|
80 |
|
|
"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
|
81 |
|
|
"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
|
82 |
|
|
};
|
83 |
|
|
|
84 |
|
|
static const char *att_general_64bit_regname[16] = {
|
85 |
|
|
"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
|
86 |
|
|
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
|
87 |
|
|
};
|
88 |
|
|
|
89 |
|
|
static const char *att_general_8bit_regname_rex[16] = {
|
90 |
|
|
"%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
|
91 |
|
|
"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
|
92 |
|
|
};
|
93 |
|
|
|
94 |
|
|
#else
|
95 |
|
|
|
96 |
|
|
static const char *att_general_16bit_regname[8] = {
|
97 |
|
|
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di"
|
98 |
|
|
};
|
99 |
|
|
|
100 |
|
|
static const char *att_general_32bit_regname[8] = {
|
101 |
|
|
"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
|
102 |
|
|
};
|
103 |
|
|
|
104 |
|
|
#endif
|
105 |
|
|
|
106 |
|
|
static const char *att_general_8bit_regname[8] = {
|
107 |
|
|
"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh"
|
108 |
|
|
};
|
109 |
|
|
|
110 |
|
|
static const char *att_segment_name[8] = {
|
111 |
|
|
"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%??", "%??"
|
112 |
|
|
};
|
113 |
|
|
|
114 |
|
|
static const char *att_index16[8] = {
|
115 |
|
|
"%bx,%si",
|
116 |
|
|
"%bx,%di",
|
117 |
|
|
"%bp,%si",
|
118 |
|
|
"%bp,%di",
|
119 |
|
|
"%si",
|
120 |
|
|
"%di",
|
121 |
|
|
"%bp",
|
122 |
|
|
"%bx"
|
123 |
|
|
};
|
124 |
|
|
|
125 |
|
|
#define NULL_SEGMENT_REGISTER 7
|
126 |
|
|
|
127 |
|
|
void disassembler::initialize_modrm_segregs()
|
128 |
|
|
{
|
129 |
|
|
sreg_mod00_rm16[0] = segment_name[DS_REG];
|
130 |
|
|
sreg_mod00_rm16[1] = segment_name[DS_REG];
|
131 |
|
|
sreg_mod00_rm16[2] = segment_name[SS_REG];
|
132 |
|
|
sreg_mod00_rm16[3] = segment_name[SS_REG];
|
133 |
|
|
sreg_mod00_rm16[4] = segment_name[DS_REG];
|
134 |
|
|
sreg_mod00_rm16[5] = segment_name[DS_REG];
|
135 |
|
|
sreg_mod00_rm16[6] = segment_name[DS_REG];
|
136 |
|
|
sreg_mod00_rm16[7] = segment_name[DS_REG];
|
137 |
|
|
|
138 |
|
|
sreg_mod01or10_rm16[0] = segment_name[DS_REG];
|
139 |
|
|
sreg_mod01or10_rm16[1] = segment_name[DS_REG];
|
140 |
|
|
sreg_mod01or10_rm16[2] = segment_name[SS_REG];
|
141 |
|
|
sreg_mod01or10_rm16[3] = segment_name[SS_REG];
|
142 |
|
|
sreg_mod01or10_rm16[4] = segment_name[DS_REG];
|
143 |
|
|
sreg_mod01or10_rm16[5] = segment_name[DS_REG];
|
144 |
|
|
sreg_mod01or10_rm16[6] = segment_name[SS_REG];
|
145 |
|
|
sreg_mod01or10_rm16[7] = segment_name[DS_REG];
|
146 |
|
|
|
147 |
|
|
sreg_mod01or10_rm32[0] = segment_name[DS_REG];
|
148 |
|
|
sreg_mod01or10_rm32[1] = segment_name[DS_REG];
|
149 |
|
|
sreg_mod01or10_rm32[2] = segment_name[DS_REG];
|
150 |
|
|
sreg_mod01or10_rm32[3] = segment_name[DS_REG];
|
151 |
|
|
sreg_mod01or10_rm32[4] = segment_name[NULL_SEGMENT_REGISTER];
|
152 |
|
|
sreg_mod01or10_rm32[5] = segment_name[SS_REG];
|
153 |
|
|
sreg_mod01or10_rm32[6] = segment_name[DS_REG];
|
154 |
|
|
sreg_mod01or10_rm32[7] = segment_name[DS_REG];
|
155 |
|
|
sreg_mod01or10_rm32[8] = segment_name[DS_REG];
|
156 |
|
|
sreg_mod01or10_rm32[9] = segment_name[DS_REG];
|
157 |
|
|
sreg_mod01or10_rm32[10] = segment_name[DS_REG];
|
158 |
|
|
sreg_mod01or10_rm32[11] = segment_name[DS_REG];
|
159 |
|
|
sreg_mod01or10_rm32[12] = segment_name[NULL_SEGMENT_REGISTER];
|
160 |
|
|
sreg_mod01or10_rm32[13] = segment_name[DS_REG];
|
161 |
|
|
sreg_mod01or10_rm32[14] = segment_name[DS_REG];
|
162 |
|
|
sreg_mod01or10_rm32[15] = segment_name[DS_REG];
|
163 |
|
|
|
164 |
|
|
sreg_mod00_base32[0] = segment_name[DS_REG];
|
165 |
|
|
sreg_mod00_base32[1] = segment_name[DS_REG];
|
166 |
|
|
sreg_mod00_base32[2] = segment_name[DS_REG];
|
167 |
|
|
sreg_mod00_base32[3] = segment_name[DS_REG];
|
168 |
|
|
sreg_mod00_base32[4] = segment_name[SS_REG];
|
169 |
|
|
sreg_mod00_base32[5] = segment_name[DS_REG];
|
170 |
|
|
sreg_mod00_base32[6] = segment_name[DS_REG];
|
171 |
|
|
sreg_mod00_base32[7] = segment_name[DS_REG];
|
172 |
|
|
sreg_mod00_base32[8] = segment_name[DS_REG];
|
173 |
|
|
sreg_mod00_base32[9] = segment_name[DS_REG];
|
174 |
|
|
sreg_mod00_base32[10] = segment_name[DS_REG];
|
175 |
|
|
sreg_mod00_base32[11] = segment_name[DS_REG];
|
176 |
|
|
sreg_mod00_base32[12] = segment_name[DS_REG];
|
177 |
|
|
sreg_mod00_base32[13] = segment_name[DS_REG];
|
178 |
|
|
sreg_mod00_base32[14] = segment_name[DS_REG];
|
179 |
|
|
sreg_mod00_base32[15] = segment_name[DS_REG];
|
180 |
|
|
|
181 |
|
|
sreg_mod01or10_base32[0] = segment_name[DS_REG];
|
182 |
|
|
sreg_mod01or10_base32[1] = segment_name[DS_REG];
|
183 |
|
|
sreg_mod01or10_base32[2] = segment_name[DS_REG];
|
184 |
|
|
sreg_mod01or10_base32[3] = segment_name[DS_REG];
|
185 |
|
|
sreg_mod01or10_base32[4] = segment_name[SS_REG];
|
186 |
|
|
sreg_mod01or10_base32[5] = segment_name[SS_REG];
|
187 |
|
|
sreg_mod01or10_base32[6] = segment_name[DS_REG];
|
188 |
|
|
sreg_mod01or10_base32[7] = segment_name[DS_REG];
|
189 |
|
|
sreg_mod01or10_base32[8] = segment_name[DS_REG];
|
190 |
|
|
sreg_mod01or10_base32[9] = segment_name[DS_REG];
|
191 |
|
|
sreg_mod01or10_base32[10] = segment_name[DS_REG];
|
192 |
|
|
sreg_mod01or10_base32[11] = segment_name[DS_REG];
|
193 |
|
|
sreg_mod01or10_base32[12] = segment_name[DS_REG];
|
194 |
|
|
sreg_mod01or10_base32[13] = segment_name[DS_REG];
|
195 |
|
|
sreg_mod01or10_base32[14] = segment_name[DS_REG];
|
196 |
|
|
sreg_mod01or10_base32[15] = segment_name[DS_REG];
|
197 |
|
|
}
|
198 |
|
|
|
199 |
|
|
//////////////////
|
200 |
|
|
// Intel STYLE
|
201 |
|
|
//////////////////
|
202 |
|
|
|
203 |
|
|
void disassembler::set_syntax_intel()
|
204 |
|
|
{
|
205 |
|
|
intel_mode = 1;
|
206 |
|
|
|
207 |
|
|
general_16bit_regname = intel_general_16bit_regname;
|
208 |
|
|
general_8bit_regname = intel_general_8bit_regname;
|
209 |
|
|
general_32bit_regname = intel_general_32bit_regname;
|
210 |
|
|
general_8bit_regname_rex = intel_general_8bit_regname_rex;
|
211 |
|
|
general_64bit_regname = intel_general_64bit_regname;
|
212 |
|
|
|
213 |
|
|
segment_name = intel_segment_name;
|
214 |
|
|
index16 = intel_index16;
|
215 |
|
|
|
216 |
|
|
initialize_modrm_segregs();
|
217 |
|
|
}
|
218 |
|
|
|
219 |
|
|
void disassembler::print_disassembly_intel(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry)
|
220 |
|
|
{
|
221 |
|
|
// print opcode
|
222 |
|
|
dis_sprintf("%s ", entry->IntelOpcode);
|
223 |
|
|
|
224 |
|
|
if (entry->Operand1) {
|
225 |
|
|
(this->*entry->Operand1)(insn);
|
226 |
|
|
}
|
227 |
|
|
if (entry->Operand2) {
|
228 |
|
|
dis_sprintf(", ");
|
229 |
|
|
(this->*entry->Operand2)(insn);
|
230 |
|
|
}
|
231 |
|
|
if (entry->Operand3) {
|
232 |
|
|
dis_sprintf(", ");
|
233 |
|
|
(this->*entry->Operand3)(insn);
|
234 |
|
|
}
|
235 |
|
|
if (entry->Operand4) {
|
236 |
|
|
dis_sprintf(", ");
|
237 |
|
|
(this->*entry->Operand4)(insn);
|
238 |
|
|
}
|
239 |
|
|
}
|
240 |
|
|
|
241 |
|
|
//////////////////
|
242 |
|
|
// AT&T STYLE
|
243 |
|
|
//////////////////
|
244 |
|
|
|
245 |
|
|
void disassembler::set_syntax_att()
|
246 |
|
|
{
|
247 |
|
|
intel_mode = 0;
|
248 |
|
|
|
249 |
|
|
general_16bit_regname = att_general_16bit_regname;
|
250 |
|
|
general_8bit_regname = att_general_8bit_regname;
|
251 |
|
|
general_32bit_regname = att_general_32bit_regname;
|
252 |
|
|
general_8bit_regname_rex = att_general_8bit_regname_rex;
|
253 |
|
|
general_64bit_regname = att_general_64bit_regname;
|
254 |
|
|
|
255 |
|
|
segment_name = att_segment_name;
|
256 |
|
|
index16 = att_index16;
|
257 |
|
|
|
258 |
|
|
initialize_modrm_segregs();
|
259 |
|
|
}
|
260 |
|
|
|
261 |
|
|
void disassembler::toggle_syntax_mode()
|
262 |
|
|
{
|
263 |
|
|
if (intel_mode) set_syntax_att();
|
264 |
|
|
else set_syntax_intel();
|
265 |
|
|
}
|
266 |
|
|
/*
|
267 |
|
|
void disassembler::print_disassembly_att(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry)
|
268 |
|
|
{
|
269 |
|
|
// print opcode
|
270 |
|
|
dis_sprintf("%s ", entry->AttOpcode);
|
271 |
|
|
|
272 |
|
|
if (entry->Operand4) {
|
273 |
|
|
(this->*entry->Operand4)(insn);
|
274 |
|
|
dis_sprintf(", ");
|
275 |
|
|
}
|
276 |
|
|
if (entry->Operand3) {
|
277 |
|
|
(this->*entry->Operand3)(insn);
|
278 |
|
|
dis_sprintf(", ");
|
279 |
|
|
}
|
280 |
|
|
if (entry->Operand2) {
|
281 |
|
|
(this->*entry->Operand2)(insn);
|
282 |
|
|
dis_sprintf(", ");
|
283 |
|
|
}
|
284 |
|
|
if (entry->Operand1) {
|
285 |
|
|
(this->*entry->Operand1)(insn);
|
286 |
|
|
}
|
287 |
|
|
}
|
288 |
|
|
*/
|
289 |
|
|
void disassembler::print_disassembly_att(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry)
|
290 |
|
|
{
|
291 |
|
|
// print opcode
|
292 |
|
|
dis_sprintf("%s", entry->AttOpcode);
|
293 |
|
|
}
|