2 Intel Open Source License
4 Copyright (c) 2002-2007 Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are
10 Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer. Redistributions
12 in binary form must reproduce the above copyright notice, this list of
13 conditions and the following disclaimer in the documentation and/or
14 other materials provided with the distribution. Neither the name of
15 the Intel Corporation nor the names of its contributors may be used to
16 endorse or promote products derived from this software without
17 specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
23 ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 /// @author Mark Charney <mark.charney@intel.com>
35 #include "xed-interface.h"
37 #include "xed-examples-ostreams.H"
44 int main(int argc, char** argv);
46 void print_attributes(xed_decoded_inst_t* xedd) {
47 const xed_inst_t* xi = xed_decoded_inst_inst(xedd);
48 unsigned int i, nattributes = xed_attribute_max();
49 xed_uint32_t all_attributes = xed_inst_get_attributes(xi);
50 if (all_attributes == 0)
52 cout << "ATTRIBUTES: ";
53 for(i=0;i<nattributes;i++) {
54 xed_attribute_enum_t attr = xed_attribute(i);
55 if (xed_inst_get_attribute(xi,attr))
56 cout << xed_attribute_enum_t2str(attr) << " ";
61 void print_flags(xed_decoded_inst_t* xedd) {
62 unsigned int i, nflags;
63 if (xed_decoded_inst_uses_rflags(xedd)) {
64 cout << "FLAGS:" << endl;
65 const xed_simple_flag_t* rfi = xed_decoded_inst_get_rflags_info(xedd);
66 if (xed_simple_flag_reads_flags(rfi)) {
67 cout << " reads-rflags ";
69 else if (xed_simple_flag_writes_flags(rfi)) {
70 //XED provides may-write and must-write information
71 if (xed_simple_flag_get_may_write(rfi)) {
72 cout << " may-write-rflags ";
74 if (xed_simple_flag_get_must_write(rfi)) {
75 cout << " must-write-rflags ";
78 nflags = xed_simple_flag_get_nflags(rfi);
79 for( i=0;i<nflags ;i++) {
80 const xed_flag_action_t* fa = xed_simple_flag_get_flag_action(rfi,i);
82 xed_flag_action_print(fa,buf,500);
87 const xed_flag_set_t* read_set = xed_simple_flag_get_read_flag_set(rfi);
88 const xed_flag_set_t* written_set = xed_simple_flag_get_written_flag_set(rfi);
90 xed_flag_set_print(read_set,buf,500);
91 cout << " read: " << buf << endl;
92 xed_flag_set_print(written_set,buf,500);
93 cout << " written: " << buf << endl;
97 void print_memops(xed_decoded_inst_t* xedd) {
98 unsigned int i, memops = xed_decoded_inst_number_of_memory_operands(xedd);
99 cout << "Memory Operands" << endl;
101 for( i=0;i<memops ; i++) {
102 xed_bool_t r_or_w = false;
103 cout << " " << i << " ";
104 if ( xed_decoded_inst_mem_read(xedd,i)) {
108 if (xed_decoded_inst_mem_written(xedd,i)) {
113 cout << "agen "; // LEA instructions
115 xed_reg_enum_t seg = xed_decoded_inst_get_seg_reg(xedd,i);
116 if (seg != XED_REG_INVALID) {
117 cout << "SEG= " << xed_reg_enum_t2str(seg) << " ";
119 xed_reg_enum_t base = xed_decoded_inst_get_base_reg(xedd,i);
120 if (base != XED_REG_INVALID) {
121 cout << "BASE= " << xed_reg_enum_t2str(base) << "/"
122 << xed_reg_class_enum_t2str(xed_reg_class(base)) << " ";
124 xed_reg_enum_t indx = xed_decoded_inst_get_index_reg(xedd,i);
125 if (i == 0 && indx != XED_REG_INVALID) {
126 cout << "INDEX= " << xed_reg_enum_t2str(indx)
127 << "/" << xed_reg_class_enum_t2str(xed_reg_class(indx)) << " ";
128 if (xed_decoded_inst_get_scale(xedd,i) != 0) {
129 // only have a scale if the index exists.
130 cout << "SCALE= " << xed_decoded_inst_get_scale(xedd,i) << " ";
133 xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xedd,i);
135 cout << "DISPLACEMENT_BYTES= " << disp_bits << " ";
136 xed_int64_t disp = xed_decoded_inst_get_memory_displacement(xedd,i);
137 cout << hex << setfill('0') << setw(16) << disp << setfill(' ') << dec;
141 cout << " MemopBytes = " << xed_decoded_inst_get_memory_operand_length(xedd,0) << endl;
144 void print_operands(xed_decoded_inst_t* xedd) {
145 unsigned int i, noperands;
146 cout << "Operands" << endl;
147 const xed_inst_t* xi = xed_decoded_inst_inst(xedd);
148 noperands = xed_inst_noperands(xi);
149 for( i=0; i < noperands ; i++) {
150 const xed_operand_t* op = xed_inst_operand(xi,i);
151 xed_operand_enum_t op_name = xed_operand_name(op);
152 cout << i << " " << xed_operand_enum_t2str(op_name) << " ";
154 case XED_OPERAND_AGEN:
155 case XED_OPERAND_MEM0:
156 case XED_OPERAND_MEM1:
157 // we print memops in a different function
159 case XED_OPERAND_PTR: // pointer (always in conjunction with a IMM0)
160 case XED_OPERAND_RELBR: { // branch displacements
161 xed_uint_t disp_bits = xed_decoded_inst_get_branch_displacement_width(xedd);
163 cout << "BRANCH_DISPLACEMENT_BYTES= " << disp_bits << " ";
164 xed_int32_t disp = xed_decoded_inst_get_branch_displacement(xedd);
165 cout << hex << setfill('0') << setw(8) << disp << setfill(' ') << dec;
170 case XED_OPERAND_IMM0: { // immediates
171 xed_uint_t width = xed_decoded_inst_get_immediate_width(xedd);
172 if (xed_decoded_inst_get_immediate_is_signed(xedd)) {
173 xed_int32_t x =xed_decoded_inst_get_signed_immediate(xedd);
174 cout << hex << setfill('0') << setw(8) << x << setfill(' ') << dec
175 << '(' << width << ')';
178 xed_uint64_t x = xed_decoded_inst_get_unsigned_immediate(xedd);
179 cout << hex << setfill('0') << setw(16) << x << setfill(' ') << dec
180 << '(' << width << ')';
184 case XED_OPERAND_IMM1: { // immediates
185 xed_uint8_t x = xed_decoded_inst_get_second_immediate(xedd);
186 cout << hex << setfill('0') << setw(2) << (int)x << setfill(' ') << dec;
190 case XED_OPERAND_REG0:
191 case XED_OPERAND_REG1:
192 case XED_OPERAND_REG2:
193 case XED_OPERAND_REG3:
194 case XED_OPERAND_REG4:
195 case XED_OPERAND_REG5:
196 case XED_OPERAND_REG6:
197 case XED_OPERAND_REG7:
198 case XED_OPERAND_REG8:
199 case XED_OPERAND_REG9:
200 case XED_OPERAND_REG10:
201 case XED_OPERAND_REG11:
202 case XED_OPERAND_REG12:
203 case XED_OPERAND_REG13:
204 case XED_OPERAND_REG14:
205 case XED_OPERAND_REG15: {
206 xed_reg_enum_t r = xed_decoded_inst_get_reg(xedd, op_name);
207 cout << xed_operand_enum_t2str(op_name) << "=" << xed_reg_enum_t2str(r);
211 cout << "[Not currently printing value of field " << xed_operand_enum_t2str(op_name) << ']';
215 cout << " " << xed_operand_visibility_enum_t2str(xed_operand_operand_visibility(op))
216 << " / " << xed_operand_action_enum_t2str(xed_operand_rw(op))
217 << " / " << xed_operand_width_enum_t2str(xed_operand_width(op));
218 cout << " bytes=" << xed_decoded_inst_operand_length(xedd,i);
223 int main(int argc, char** argv) {
225 xed_decoded_inst_t xedd;
227 unsigned char itext[XED_MAX_INSTRUCTION_BYTES];
228 xed_bool_t long_mode = false;
229 unsigned int first_argv;
232 xed_state_zero(&dstate);
233 if (argc > 2 && strcmp(argv[1], "-64") == 0)
238 dstate.mmode=XED_MACHINE_MODE_LONG_64;
242 xed_state_init(&dstate,
243 XED_MACHINE_MODE_LEGACY_32,
244 XED_ADDRESS_WIDTH_32b,
245 XED_ADDRESS_WIDTH_32b);
248 xed_decoded_inst_zero_set_mode(&xedd, &dstate);
250 for( i=first_argv ;i < argc; i++) {
252 // sscanf is deprecated for MSVS8, so I'm using istringstreams
253 //sscanf(argv[i],"%x", &x);
254 istringstream s(argv[i]);
256 assert(bytes < XED_MAX_INSTRUCTION_BYTES);
257 itext[bytes++] = STATIC_CAST(xed_uint8_t,x);
260 cout << "Must supply some hex bytes" << endl;
264 cout << "Attempting to decode: " << hex << setfill('0') ;
266 cout << setw(2) << static_cast<xed_uint_t>(itext[i]) << " ";
267 cout << endl << setfill(' ') << dec;
269 xed_error_enum_t xed_error = xed_decode(&xedd,
270 REINTERPRET_CAST(const xed_uint8_t*,itext),
275 case XED_ERROR_BUFFER_TOO_SHORT:
276 cout << "Not enough bytes provided" << endl;
278 case XED_ERROR_GENERAL_ERROR:
279 cout << "Could not decode given input." << endl;
282 cout << "Unhandled error code " << xed_error_enum_t2str(xed_error) << endl;
288 << xed_iclass_enum_t2str(xed_decoded_inst_get_iclass(&xedd)) << "\t";
290 << xed_category_enum_t2str(xed_decoded_inst_get_category(&xedd)) << "\t";
291 cout << "ISA-extension "
292 << xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xedd)) << endl;
293 cout << "instruction-length "
294 << xed_decoded_inst_get_length(&xedd) << endl;
295 cout << "effective-operand-width "
296 << xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xedd)) << endl;
297 cout << "effective-address-width "
298 << xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xedd)) << endl;
299 cout << "iform-enum-name "
300 << xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xedd)) << endl;
301 cout << "iform-enum-name-dispatch (zero based) "
302 << xed_decoded_inst_get_iform_enum_dispatch(&xedd) << endl;
303 cout << "iclass-max-iform-dispatch "
304 << xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xedd)) << endl;
307 print_operands(&xedd);
316 print_attributes(&xedd);