static int format_operand_att( x86_op_t *op, x86_insn_t *insn, char *buf, int len) { char str[MAX_OP_STRING]; memset (str, 0, sizeof str); switch ( op->type ) { case op_register: STRNCATF( buf, "%%%s", op->data.reg.name, len ); break; case op_immediate: get_operand_data_str( op, str, sizeof str ); STRNCATF( buf, "$%s", str, len ); break; case op_relative_near: STRNCATF( buf, "0x%08X", (unsigned int)(op->data.sbyte + insn->addr + insn->size), len ); break; case op_relative_far: if (op->datatype == op_word) { STRNCATF( buf, "0x%08X", (unsigned int)(op->data.sword + insn->addr + insn->size), len ); } else { STRNCATF( buf, "0x%08X", (unsigned int)(op->data.sdword + insn->addr + insn->size), len ); } break; case op_absolute: case op_offset: /* ATT requires a '*' before absolute JMP/CALL ops */ if (insn->type == insn_jmp || insn->type == insn_call) STRNCAT( buf, "*", len ); len -= format_seg( op, buf, len, att_syntax ); STRNCATF( buf, "0x%08lX", op->data.sdword, len ); break; case op_expression: len -= format_seg( op, buf, len, att_syntax ); len -= format_expr( &op->data.expression, buf, len, att_syntax ); break; case op_unused: case op_unknown: /* return 0-truncated buffer */ break; } return ( strlen( buf ) ); }
static int format_operand_raw( x86_op_t *op, x86_insn_t *insn, char *buf, int len){ char str[MAX_OP_RAW_STRING]; char *datatype = get_operand_datatype_str(op); switch (op->type) { case op_register: get_operand_regtype_str( op->data.reg.type, str, sizeof str ); STRNCAT( buf, "reg|", len ); STRNCATF( buf, "%s|", datatype, len ); STRNCATF( buf, "%s:", op->data.reg.name, len ); STRNCATF( buf, "%s:", str, len ); STRNCATF( buf, "%d|", op->data.reg.size, len ); break; case op_immediate: get_operand_data_str( op, str, sizeof str ); STRNCAT( buf, "immediate|", len ); STRNCATF( buf, "%s|", datatype, len ); STRNCATF( buf, "%s|", str, len ); break; case op_relative_near: /* NOTE: in raw format, we print the * relative offset, not the actual * address of the jump target */ STRNCAT( buf, "relative|", len ); STRNCATF( buf, "%s|", datatype, len ); STRNCATF( buf, "%hhd|", op->data.sbyte, len ); break; case op_relative_far: STRNCAT( buf, "relative|", len ); STRNCATF( buf, "%s|", datatype, len ); if (op->datatype == op_word) { STRNCATF( buf, "%hd|", op->data.sword, len); break; } else { STRNCATF( buf, "%d|", op->data.sdword, len ); } break; case op_absolute: STRNCAT( buf, "absolute_address|", len ); STRNCATF( buf, "%s|", datatype, len ); STRNCATF( buf, "$0x%04hX:", op->data.absolute.segment, len ); if (op->datatype == op_descr16) { STRNCATF( buf, "0x%04hX|", op->data.absolute.offset.off16, len ); } else { STRNCATF( buf, "0x%08X|", op->data.absolute.offset.off32, len ); } break; case op_expression: STRNCAT( buf, "address_expression|", len ); STRNCATF( buf, "%s|", datatype, len ); len -= format_seg( op, buf, len, native_syntax ); len -= format_expr( &op->data.expression, buf, len, raw_syntax ); STRNCAT( buf, "|", len ); break; case op_offset: STRNCAT( buf, "segment_offset|", len ); STRNCATF( buf, "%s|", datatype, len ); len -= format_seg( op, buf, len, xml_syntax ); STRNCATF( buf, "%08X|", op->data.sdword, len ); break; case op_unused: case op_unknown: /* return 0-truncated buffer */ break; } return( strlen( buf ) ); }
static int format_operand_xml( x86_op_t *op, x86_insn_t *insn, char *buf, int len){ char str[MAX_OP_STRING] = "\0"; switch (op->type) { case op_register: get_operand_regtype_str( op->data.reg.type, str, sizeof str ); STRNCAT( buf, "\t\t<register ", len ); STRNCATF( buf, "name=\"%s\" ", op->data.reg.name, len ); STRNCATF( buf, "type=\"%s\" ", str, len ); STRNCATF( buf, "size=%d/>\n", op->data.reg.size, len ); break; case op_immediate: get_operand_data_str( op, str, sizeof str ); STRNCAT( buf, "\t\t<immediate ", len ); STRNCATF( buf, "type=\"%s\" ", get_operand_datatype_str (op), len ); STRNCATF( buf, "value=\"%s\"/>\n", str, len ); break; case op_relative_near: STRNCAT( buf, "\t\t<relative_offset ", len ); STRNCATF( buf, "value=\"0x%08X\"/>\n", (unsigned int)(op->data.sbyte + insn->addr + insn->size), len ); break; case op_relative_far: STRNCAT( buf, "\t\t<relative_offset ", len ); if (op->datatype == op_word) { STRNCATF( buf, "value=\"0x%08X\"/>\n", (unsigned int)(op->data.sword + insn->addr + insn->size), len); break; } else { STRNCATF( buf, "value=\"0x%08X\"/>\n", op->data.sdword + insn->addr + insn->size, len ); } break; case op_absolute: STRNCATF( buf, "\t\t<absolute_address segment=\"0x%04hX\"", op->data.absolute.segment, len ); if (op->datatype == op_descr16) { STRNCATF( buf, "offset=\"0x%04hX\">", op->data.absolute.offset.off16, len ); } else { STRNCATF( buf, "offset=\"0x%08X\">", op->data.absolute.offset.off32, len ); } STRNCAT( buf, "\t\t</absolute_address>\n", len ); break; case op_expression: STRNCAT( buf, "\t\t<address_expression>\n", len ); len -= format_seg( op, buf, len, xml_syntax ); len -= format_expr( &op->data.expression, buf, len, xml_syntax ); STRNCAT( buf, "\t\t</address_expression>\n", len ); break; case op_offset: STRNCAT( buf, "\t\t<segment_offset>\n", len ); len -= format_seg( op, buf, len, xml_syntax ); STRNCAT( buf, "\t\t\t<address ", len); STRNCATF( buf, "value=\"0x%08X\"/>\n", op->data.sdword, len ); STRNCAT( buf, "\t\t</segment_offset>\n", len ); break; case op_unused: case op_unknown: /* return 0-truncated buffer */ break; } return( strlen( buf ) ); }
static int format_operand_native( x86_op_t *op, x86_insn_t *insn, char *buf, int len){ char str[MAX_OP_STRING]; switch (op->type) { case op_register: STRNCAT( buf, op->data.reg.name, len ); break; case op_immediate: get_operand_data_str( op, str, sizeof str ); STRNCAT( buf, str, len ); break; case op_relative_near: STRNCATF( buf, "0x%08X", (unsigned int)(op->data.sbyte + insn->addr + insn->size), len ); break; case op_relative_far: if ( op->datatype == op_word ) { STRNCATF( buf, "0x%08X", (unsigned int)(op->data.sword + insn->addr + insn->size), len ); break; } else { STRNCATF( buf, "0x%08X", op->data.sdword + insn->addr + insn->size, len ); } break; case op_absolute: STRNCATF( buf, "$0x%04hX" ":", op->data.absolute.segment, len ); if (op->datatype == op_descr16) { STRNCATF( buf, "0x%04hX", op->data.absolute.offset.off16, len ); } else { STRNCATF( buf, "0x%08X", op->data.absolute.offset.off32, len ); } break; case op_offset: len -= format_seg( op, buf, len, native_syntax ); STRNCATF( buf, "[0x%08X]", op->data.sdword, len ); break; case op_expression: len -= format_seg( op, buf, len, native_syntax ); len -= format_expr( &op->data.expression, buf, len, native_syntax ); break; case op_unused: case op_unknown: /* return 0-truncated buffer */ break; } return( strlen( buf ) ); }
static int format_expr( x86_ea_t *ea, char *buf, int len, enum x86_asm_format format ) { char str[MAX_OP_STRING]; if ( format == att_syntax ) { if (ea->base.name[0] || ea->index.name[0] || ea->scale) { PRINT_DISPLACEMENT(ea); STRNCAT( buf, "(", len ); if ( ea->base.name[0]) { STRNCATF( buf, "%%%s", ea->base.name, len ); } if ( ea->index.name[0]) { STRNCATF( buf, ",%%%s", ea->index.name, len ); if ( ea->scale > 1 ) { STRNCATF( buf, ",%d", ea->scale, len ); } } /* handle the syntactic exception */ if ( ! ea->base.name[0] && ! ea->index.name[0] ) { STRNCATF( buf, ",%d", ea->scale, len ); } STRNCAT( buf, ")", len ); } else STRNCATF( buf, "0x%X", ea->disp, len ); } else if ( format == xml_syntax ){ if ( ea->base.name[0]) { STRNCAT (buf, "\t\t\t<base>\n", len); get_operand_regtype_str (ea->base.type, str, sizeof str); STRNCAT (buf, "\t\t\t\t<register ", len); STRNCATF (buf, "name=\"%s\" ", ea->base.name, len); STRNCATF (buf, "type=\"%s\" ", str, len); STRNCATF (buf, "size=%d/>\n", ea->base.size, len); STRNCAT (buf, "\t\t\t</base>\n", len); } if ( ea->index.name[0]) { STRNCAT (buf, "\t\t\t<index>\n", len); get_operand_regtype_str (ea->index.type, str, sizeof str); STRNCAT (buf, "\t\t\t\t<register ", len); STRNCATF (buf, "name=\"%s\" ", ea->index.name, len); STRNCATF (buf, "type=\"%s\" ", str, len); STRNCATF (buf, "size=%d/>\n", ea->index.size, len); STRNCAT (buf, "\t\t\t</index>\n", len); } //scale STRNCAT (buf, "\t\t\t<scale>\n", len); STRNCAT (buf, "\t\t\t\t<immediate ", len); STRNCATF (buf, "value=\"%d\"/>\n", ea->scale, len); STRNCAT (buf, "\t\t\t</scale>\n", len); if ( ea->disp_size ) { STRNCAT (buf, "\t\t\t<displacement>\n", len); if ( ea->disp_size > 1 && ! ea->disp_sign ) { STRNCAT (buf, "\t\t\t\t<address ", len); STRNCATF (buf, "value=\"0x%X" "\"/>\n", ea->disp, len); } else { STRNCAT (buf, "\t\t\t\t<immediate ", len); STRNCATF (buf, "value=%d" "/>\n", ea->disp, len); } STRNCAT (buf, "\t\t\t</displacement>\n", len); } } else if ( format == raw_syntax ) { PRINT_DISPLACEMENT(ea); STRNCAT( buf, "(", len ); STRNCATF( buf, "%s,", ea->base.name, len ); STRNCATF( buf, "%s,", ea->index.name, len ); STRNCATF( buf, "%d", ea->scale, len ); STRNCAT( buf, ")", len ); } else { STRNCAT( buf, "[", len ); if ( ea->base.name[0] ) { STRNCAT( buf, ea->base.name, len ); if ( ea->index.name[0] || (ea->disp_size && ! ea->disp_sign) ) { STRNCAT( buf, "+", len ); } } if ( ea->index.name[0] ) { STRNCAT( buf, ea->index.name, len ); if ( ea->scale > 1 ) { STRNCATF( buf, "*%d", ea->scale, len ); } if ( ea->disp_size && ! ea->disp_sign ) { STRNCAT( buf, "+", len ); } } if ( ea->disp_size || (! ea->index.name[0] && ! ea->base.name[0] ) ) { PRINT_DISPLACEMENT(ea); } STRNCAT( buf, "]", len ); } return( strlen(buf) ); }
int x86_format_insn( x86_insn_t *insn, char *buf, int len, enum x86_asm_format format ){ char str[MAX_OP_STRING]; x86_op_t *src, *dst; int i; memset(buf, 0, len); if ( format == intel_syntax ) { /* INTEL STYLE: mnemonic dest, src, imm */ STRNCAT( buf, insn->prefix_string, len ); STRNCAT( buf, insn->mnemonic, len ); STRNCAT( buf, "\t", len ); /* dest */ if ( (dst = x86_operand_1st( insn )) && !(dst->flags & op_implied) ) { x86_format_operand( dst, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } /* src */ if ( (src = x86_operand_2nd( insn )) ) { if ( !(dst->flags & op_implied) ) { STRNCAT( buf, ", ", len ); } x86_format_operand( src, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } /* imm */ if ( x86_operand_3rd( insn )) { STRNCAT( buf, ", ", len ); x86_format_operand( x86_operand_3rd( insn ), str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } } else if ( format == att_syntax ) { /* ATT STYLE: mnemonic src, dest, imm */ STRNCAT( buf, insn->prefix_string, len ); format_att_mnemonic(insn, str, MAX_OP_STRING); STRNCATF( buf, "%s\t", str, len); /* not sure which is correct? sometimes GNU as requires * an imm as the first operand, sometimes as the third... */ /* imm */ if ( x86_operand_3rd( insn ) ) { x86_format_operand(x86_operand_3rd( insn ), str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); /* there is always 'dest' operand if there is 'src' */ STRNCAT( buf, ", ", len ); } if ( (insn->note & insn_note_nonswap ) == 0 ) { /* regular AT&T style swap */ src = x86_operand_2nd( insn ); dst = x86_operand_1st( insn ); } else { /* special-case instructions */ src = x86_operand_1st( insn ); dst = x86_operand_2nd( insn ); } /* src */ if ( src ) { x86_format_operand(src, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); /* there is always 'dest' operand if there is 'src' */ if ( dst && !(dst->flags & op_implied) ) { STRNCAT( buf, ", ", len ); } } /* dest */ if ( dst && !(dst->flags & op_implied) ) { x86_format_operand( dst, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } } else if ( format == raw_syntax ) { format_raw_insn( insn, buf, len ); } else if ( format == xml_syntax ) { format_xml_insn( insn, buf, len ); } else { /* default to native */ /* NATIVE style: RVA\tBYTES\tMNEMONIC\tOPERANDS */ /* print address */ STRNCATF( buf, "%08X\t", insn->addr, len ); /* print bytes */ for ( i = 0; i < insn->size; i++ ) { STRNCATF( buf, "%02X ", insn->bytes[i], len ); } STRNCAT( buf, "\t", len ); /* print mnemonic */ STRNCAT( buf, insn->prefix_string, len ); STRNCAT( buf, insn->mnemonic, len ); STRNCAT( buf, "\t", len ); /* print operands */ /* dest */ if ( x86_operand_1st( insn ) ) { x86_format_operand( x86_operand_1st( insn ), str, MAX_OP_STRING, format); STRNCATF( buf, "%s\t", str, len ); } /* src */ if ( x86_operand_2nd( insn ) ) { x86_format_operand(x86_operand_2nd( insn ), str, MAX_OP_STRING, format); STRNCATF( buf, "%s\t", str, len ); } /* imm */ if ( x86_operand_3rd( insn )) { x86_format_operand( x86_operand_3rd( insn ), str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } } return( strlen( buf ) ); }
static int format_xml_insn( x86_insn_t *insn, char *buf, int len ) { char str[MAX_OP_XML_STRING]; int i; STRNCAT( buf, "<x86_insn>\n", len ); STRNCATF( buf, "\t<address rva=\"0x%08X\" ", insn->addr, len ); STRNCATF( buf, "offset=\"0x%08X\" ", insn->offset, len ); STRNCATF( buf, "size=%d bytes=\"", insn->size, len ); for ( i = 0; i < insn->size; i++ ) { STRNCATF( buf, "%02X ", insn->bytes[i], len ); } STRNCAT( buf, "\"/>\n", len ); STRNCAT( buf, "\t<prefix type=\"", len ); len -= format_insn_prefix_str( insn->prefix, buf, len ); STRNCATF( buf, "\" string=\"%s\"/>\n", insn->prefix_string, len ); STRNCATF( buf, "\t<mnemonic group=\"%s\" ", get_insn_group_str (insn->group), len ); STRNCATF( buf, "type=\"%s\" ", get_insn_type_str (insn->type), len ); STRNCATF( buf, "string=\"%s\"/>\n", insn->mnemonic, len ); STRNCAT( buf, "\t<flags type=set>\n", len ); STRNCAT( buf, "\t\t<flag name=\"", len ); len -= format_insn_eflags_str( insn->flags_set, buf, len ); STRNCAT( buf, "\"/>\n\t</flags>\n", len ); STRNCAT( buf, "\t<flags type=tested>\n", len ); STRNCAT( buf, "\t\t<flag name=\"", len ); len -= format_insn_eflags_str( insn->flags_tested, buf, len ); STRNCAT( buf, "\"/>\n\t</flags>\n", len ); if ( x86_operand_1st( insn ) ) { x86_format_operand( x86_operand_1st(insn), str, sizeof str, xml_syntax); STRNCAT( buf, "\t<operand name=dest>\n", len ); STRNCAT( buf, str, len ); STRNCAT( buf, "\t</operand>\n", len ); } if ( x86_operand_2nd( insn ) ) { x86_format_operand( x86_operand_2nd( insn ), str, sizeof str, xml_syntax); STRNCAT( buf, "\t<operand name=src>\n", len ); STRNCAT( buf, str, len ); STRNCAT( buf, "\t</operand>\n", len ); } if ( x86_operand_3rd( insn ) ) { x86_format_operand( x86_operand_3rd(insn), str, sizeof str, xml_syntax); STRNCAT( buf, "\t<operand name=imm>\n", len ); STRNCAT( buf, str, len ); STRNCAT( buf, "\t</operand>\n", len ); } STRNCAT( buf, "</x86_insn>\n", len ); return strlen (buf); }
static int format_raw_insn( x86_insn_t *insn, char *buf, int len ){ struct op_string opstr = { buf, len }; int i; /* RAW style: * ADDRESS|OFFSET|SIZE|BYTES| * PREFIX|PREFIX_STRING|GROUP|TYPE|NOTES| * MNEMONIC|CPU|ISA|FLAGS_SET|FLAGS_TESTED| * STACK_MOD|STACK_MOD_VAL * [|OP_TYPE|OP_DATATYPE|OP_ACCESS|OP_FLAGS|OP]* * * Register values are encoded as: * NAME:TYPE:SIZE * * Effective addresses are encoded as: * disp(base_reg,index_reg,scale) */ STRNCATF( buf, "0x%08X|", insn->addr , len ); STRNCATF( buf, "0x%08X|", insn->offset, len ); STRNCATF( buf, "%d|" , insn->size , len ); /* print bytes */ for ( i = 0; i < insn->size; i++ ) { STRNCATF( buf, "%02X ", insn->bytes[i], len ); } STRNCAT( buf, "|", len ); len -= format_insn_prefix_str( insn->prefix, buf, len ); STRNCATF( buf, "|%s|", insn->prefix_string , len ); STRNCATF( buf, "%s|", get_insn_group_str( insn->group ), len ); STRNCATF( buf, "%s|", get_insn_type_str( insn->type ) , len ); STRNCATF( buf, "%s|", insn->mnemonic , len ); STRNCATF( buf, "%s|", get_insn_cpu_str( insn->cpu ) , len ); STRNCATF( buf, "%s|", get_insn_isa_str( insn->isa ) , len ); /* insn note */ len -= format_insn_note( insn, buf, len ); len -= format_insn_eflags_str( insn->flags_set, buf, len ); STRNCAT( buf, "|", len ); len -= format_insn_eflags_str( insn->flags_tested, buf, len ); STRNCAT( buf, "|", len ); STRNCATF( buf, "%d|", insn->stack_mod, len ); STRNCATF( buf, "%d|", insn->stack_mod_val, len ); opstr.len = len; x86_operand_foreach( insn, format_op_raw, &opstr, op_any ); return( strlen (buf) ); }
static int format_operand_raw( x86_op_t *op, x86_insn_t *insn, char *buf, int len) { char str[MAX_OP_RAW_STRING]; char *datatype = get_operand_datatype_str(op); switch (op->type) { case op_register: get_operand_regtype_str( op->data.reg.type, str, sizeof str ); STRNCAT( buf, "reg|", len ); STRNCATF( buf, "%s|", datatype, len ); STRNCATF( buf, "%s:", op->data.reg.name, len ); STRNCATF( buf, "%s:", str, len ); STRNCATF( buf, "%d|", op->data.reg.size, len ); break; case op_immediate: get_operand_data_str( op, str, sizeof str ); STRNCAT( buf, "immediate|", len ); STRNCATF( buf, "%s|", datatype, len ); STRNCATF( buf, "%s|", str, len ); break; case op_relative_near: STRNCAT( buf, "relative|", len ); STRNCATF( buf, "%s|", datatype, len ); STRNCATF( buf, "%08X|", (unsigned int)(op->data.sbyte + insn->addr + insn->size), len ); break; case op_relative_far: STRNCAT( buf, "relative|", len ); STRNCATF( buf, "%s|", datatype, len ); if (op->datatype == op_word) { STRNCATF( buf, "%08X", (unsigned int)(op->data.sword + insn->addr + insn->size), len); break; } else { STRNCATF( buf, "%08lX|", op->data.sdword + insn->addr + insn->size, len ); } break; case op_absolute: STRNCAT( buf, "absolute_address|", len ); STRNCATF( buf, "%s|", datatype, len ); len -= format_seg( op, buf, len, native_syntax ); STRNCATF( buf, "%08lX|", op->data.sdword, len ); break; case op_expression: STRNCAT( buf, "address_expression|", len ); STRNCATF( buf, "%s|", datatype, len ); len -= format_seg( op, buf, len, native_syntax ); len -= format_expr( &op->data.expression, buf, len, raw_syntax ); STRNCAT( buf, "|", len ); break; case op_offset: STRNCAT( buf, "segment_offset|", len ); STRNCATF( buf, "%s|", datatype, len ); len -= format_seg( op, buf, len, xml_syntax ); STRNCATF( buf, "%08lX|", op->data.sdword, len ); break; case op_unused: case op_unknown: /* return 0-truncated buffer */ break; } return( strlen( buf ) ); }
int x86_format_insn( x86_insn_t *insn, char *buf, int len, enum x86_asm_format format ) { char str[MAX_OP_STRING]; int i; memset(buf, 0, len); if ( format == intel_syntax ) { /* INTEL STYLE: mnemonic dest, src, imm */ STRNCAT( buf, insn->prefix_string, len ); STRNCAT( buf, insn->mnemonic, len ); STRNCAT( buf, "\t", len ); /* dest */ if ( x86_operand_1st( insn ) ) { x86_format_operand( x86_operand_1st( insn ), insn, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } /* src */ if ( x86_operand_2nd( insn ) ) { STRNCAT( buf, ", ", len ); x86_format_operand(x86_operand_2nd( insn ), insn, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } /* imm */ if ( x86_operand_3rd( insn )) { STRNCAT( buf, ", ", len ); x86_format_operand( x86_operand_3rd( insn ), insn, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } } else if ( format == att_syntax ) { /* ATT STYLE: mnemonic src, dest, imm */ STRNCAT( buf, insn->prefix_string, len ); format_att_mnemonic(insn, str, MAX_OP_STRING); STRNCATF( buf, "%s\t", str, len); /* src */ if ( x86_operand_2nd( insn ) ) { x86_format_operand(x86_operand_2nd( insn ), insn, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); /* there is always 'dest' operand if there is 'src' */ STRNCAT( buf, ", ", len ); } /* dest */ if ( x86_operand_1st( insn ) ) { x86_format_operand( x86_operand_1st( insn ), insn, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } /* imm */ if ( x86_operand_3rd( insn ) ) { STRNCAT( buf, ", ", len ); x86_format_operand(x86_operand_3rd( insn ), insn, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } } else if ( format == raw_syntax ) { format_raw_insn( insn, buf, len ); } else if ( format == xml_syntax ) { format_xml_insn( insn, buf, len ); } else { /* default to native */ /* NATIVE style: RVA\tBYTES\tMNEMONIC\tOPERANDS */ /* print address */ STRNCATF( buf, "%08lX\t", insn->addr, len ); /* print bytes */ for ( i = 0; i < insn->size; i++ ) { STRNCATF( buf, "%02X ", insn->bytes[i], len ); } STRNCAT( buf, "\t", len ); /* print mnemonic */ STRNCAT( buf, insn->prefix_string, len ); STRNCAT( buf, insn->mnemonic, len ); STRNCAT( buf, "\t", len ); /* print operands */ /* dest */ if ( x86_operand_1st( insn ) ) { x86_format_operand( x86_operand_1st( insn ), insn, str, MAX_OP_STRING, format); STRNCATF( buf, "%s\t", str, len ); } /* src */ if ( x86_operand_2nd( insn ) ) { x86_format_operand(x86_operand_2nd( insn ), insn, str, MAX_OP_STRING, format); STRNCATF( buf, "%s\t", str, len ); } /* imm */ if ( x86_operand_3rd( insn )) { x86_format_operand( x86_operand_3rd( insn ), insn, str, MAX_OP_STRING, format); STRNCAT( buf, str, len ); } } return( strlen( buf ) ); }