- Main Page
- Modules
- Data Structures
- Files

- Search for |

# XED User Guide

by Mark Charney

2013-04-15

## Introduction

XED is an acronym for X86 Encoder Decoder. It is pronounced like the (British) English "z".

XED is a software library (and associated headers) written in C for encoding and decoding X86 (IA-32 instruction set and Intel® 64 instruction set) instructions. The decoder takes sequences of 1-15 bytes along with machine mode information and produces a data structure describing the opcode and operands, and flags. The encoder takes a similar data structure and produces a sequence of 1 to 15 bytes. XED is multi-thread safe.

XED was designed to be very fast and extensible.

XED compiles with the following compilers:

- GNU gcc 2.96, 3.2.x...3.4.x, 4.0...4.7
- Microsoft Visual C++ 6 (VC98), Visual Studio 7 (.NET 2003), VS8 (Professional 2005), VS9 (Professional 2008), and Dev10 (2010).
- Intel ICL/ICC 7.1, 8, 9, 10, 11 and 12.

XED works with the following operating systems:

- Linux, various flavors
- Microsoft Windows (with and without cygwin)
- Apple Mac OS* X
- FreeBSD

The XED examples (Examples of using XED) also include binary image readers for Windows PECOFF, ELF and Mac OS* X MACHO binary file formats for 32b and 64b. These allow XED to be used as a simple (not symbolic) disassembler. The XED disassembler supports 3 output formats: Intel, ATT SYSV, and a more detailed internal format describing all resources read and written.

## Table of Contents

- Building Building your program with XED
- Terms Terminology
- Overview Overview of the XED approach
- API reference Detailed descriptions of the API
- Examples Examples
- Feedback Questions? Bugs?
- Disclaimer and Legal Information

## Building your program using XED.

This section describes the requirements for compiling with XED and linking the libxed.a library. It assumes you are building from a XED kit, and not directly from the sources. (See the "install" option in the XED build manual for information on making kits).

The structure of a XED2 kit is as follows:

                                  |-bin------
                                  |-doc------|-html-
                                  |-examples-
                   |-xed-kit-name-|-include--
                                  |-lib------
                                  |-misc-----

To use XED your sources should include the top-most header file: xed-interface.h.

Your compilation statement must include:

    -Ixed-kit-name/include

where "xed-kit-name" is the place you've unpacked the XED kit.

Your Linux or Mac OS* X link statement must reference the libxed library:

    -lxed-kit-name/lib/libxed.a

(or link against libxed.lib for Windows).

XED uses base types with the following names: xed_uint8_t, xed_uint16_t, xed_uint32_t, xed_uint64_t xed_int8_t, xed_int16_t, xed_int32_t, and xed_int64_t. XED also defines a "xed_uint_t" type that is shorthand for "unsigned int".

Please see the section XED initialization for more information about using XED, and also the examples in Examples of using XED.

## Terminology

X86 instructions are 1-15 byte values. They consist of several well defined components that total at most 15 bytes:

- legacy prefix bytes. Used for many purposes.
- REX prefix byte. Only in 64b mode. It has 4 1-bit fields: W, R, X, and B. The W bit modifies the operation width. The R, X and B fields extend the register encodings.
- 1-3 opcode bytes
- MODRM byte. Used for addressing memory, refining opcodes, specifying registers. Optional, but common. It has 3 fields: the 2-bit mod, the 3-bit reg and 3-bit "r/m" fields.
- SIB byte. Used for specifying memory addressing, optional. It has 3 fields: the 2-bit scale, 3-bit index and 3-bit base.
- Displacement bytes. Used for specifying memory offsets, optional.
- Immediate bytes. Optional

One specific opcode byte is used as an 'escape' to indicate that two opcode bytes are required. All two-byte opcodes have this escape as their first opcode byte.

Immediates and displacements are usually limited to 4 bytes, but there are several variants of the MOV instruction that can take 8B values. The AMD 3DNow ISA extension uses the immediate field to provide additional opcode information.

The encodings are very byte-oriented. Bit-fields in the REX, opcode, MODRM and SIB bytes are simple and self-contained.

The legacy prefix bytes are used for:

- operand size overrides (1 prefix),
- address size overrides (1 prefix),
- atomic locking (1 prefix),
- default segment overrides (6 prefixes),
- repeating certain instructions (2 prefixes), and
- opcode refinement.

There are 11 distinct legacy prefixes. Three of them (operand size, and the two repeat prefixes) have different meanings in different contexts; Sometimes they are used for opcode refinement and do not have their default meaning. Less frequently. two of the segment overrides can be used for conditional branch hints.

There are also multiple ways to encode certain instructions, with the same or differing length.

## Overview of XED approach

XED has two fundamental interfaces: encoding and decoding. Supporting these interfaces are many data structures, but the two starting points are the xed_encoder_request_t and the xed_decoded_inst_t . The xed_decoded_inst_t has more information than the xed_encoder_request_t , but both types are derived from a set of common fields called the xed_operand_values_t.

The output of the decoder, the xed_decoded_inst_t , includes additional information that is not required for encoding, but provides more information about the instruction resources.

The common operand fields, used by both the encoder and decoder, hold the operands and the memory addressing information.

The decoder has an operands array that holds order of the decoded operands. This array indicates whether or not the operands are read or written.

The encoder has an operand array where the encoder user must specify the order of the operands used for encoding.

===========================================================================

## Instruction classes

The xed_iclass_enum_t class describes the instruction names. The names are (mostly) taken from the Intel manual, with exceptions only for certain ambiguities. This is what is typically thought of as the instruction mnemonic. Note, XED does not typically distinguish instructions based on width unless the ISA manuals do so as well. For example, xed_iclass_enum_t's are not suffixed with "w", "l" or "q" typically. There are instructions whose xed_iclass_enum_t ends in a "B" or a "Q" (including all byte operations and certain string operations) and those names are preserved as described in the Intel programmers' reference manuals.

### Special Cases

There are many special cases that must be accounted for in attempting to handle all the nuances of the ISA. This is an attempt to explain the nonstandard handling of certain instruction names.

The FAR versions of 3 opcodes (really 6 distinct opcodes) are given the opcode names CALL_FAR, JMP_FAR and RET_FAR. The AMD documentation lists the far return as RETF. I call that RET_FAR to be consistent with the other far operations.

To distinguish the SSE2 MOVSD instruction from the base string instruction MOVSD, XED calls the SSE version MOVSD_XMM.

### NOPs

NOPs are very special. XED allows for encoding NOPs of 1 to 9 bytes through the use of the XED_ICLASS_NOP (the one byte nop), and XED_ICLASS_NOP2 ... XED_ICLASS_NOP9. These use the recommended NOP sequences from the Intel Software Developers Manual.

The instruction 0x90 is very special in the instruction set because it gets special treatment in 64b mode. In 64b mode, 32b register writes normally zero the upper 32 bits of a 64b register. No so for 0x90. If it did zero the upper 32 bits, it would not be a NOP.

There are two important NOP categories. XED_CATEGORY_NOP and XED_CATEGORY_WIDENOP. The XED_CATEGORY_NOP applies only to the 0x90 opcode. The WIDENOP category applies to the NOPs in the two byte table row 0F19...0F1F. The WIDENOPs take MODRM bytes, and optional SIB and displacements.

===========================================================================

## Operands

XED uses the operand order documented in the Intel Programmers' Reference Manual. In most cases, the first operand is a source and destination (read and written) and the second operand is just a source (read).

For decode requests (xed_decoded_inst_t), the operands array is stored in the xed_inst_t strcture once the instruction is decoded. For encode requests, the request's operand order is stored in the xed_encoder_request_t.

There are several types of operands:

- registers (xed_reg_enum_t)
- branch displacements
- memory operations (which include base, index, segment and memory displacements)
- immediates
- pseudo resources (which are listed in the xed_reg_enum_t)

Each operand has two associated attributes: the R/W action and a visibility. The R/W actions (xed_operand_action_enum_t) indicate whether the operand is read, written or both read-and-written, or conditionally read or written. The visibility attribute (xed_operand_visibility_enum_t) is described in the next subsection.

The memory operation operand is really a pointer to separate fields that hold the memory operation information. The memory operation information is comprised of:

- a segment register
- a base register
- an index register
- a displacement

There are several important things to note:

- There can only be two memory operations, MEM0 and MEM1.
- MEM0 could also be an AGEN -- a special operand that uses memory information but does not actually read memory. This is only used for the LEA instruction.
- There can only be an index and displacement associated with MEM0.
- There is just one displacement associated with the common fields. It could be associated with either the AGEN/MEM0 or with a branch or call instruction.

### Operand Resource Visibilities

See xed_operand_visibility_enum_t .

There are 3 basic types of resource visibilites:

- EXPLICIT (EXPL),
- IMPLICIT (IMPL), and
- IMPLICIT SUPPRESSED (SUPP) (usually referred to as just "SUPPRESSED").

Explicit are what you think they are: resources that are required for the encoding and for each explicit resource, there is field in the corresponding instruction encoding. The implicit and suppressed resources are a more subtle.

SUPP operands are:

- not used in picking an encoding,
- not printed in disassembly,
- not represented using operand bits in the encoding.

IMPL operands are:

- used in picking an encoding,
- expressed in disassembly, and
- not represented using operand bits in the encoding (like SUPP).

The implicit resources are required for selecting an encoding, but do not show up as a specific field in the instruction representation. Implicit resources do show up in a conventional instruction disassembly. In the IA-32 instruction set or Intel64 instruction set, there are many instructions that use EAX or RAX implicitly, for example. Sometimes the CL or RCX register is implicit. Also, some instructions have an implicit 1 immediate. The opcode you chose fixes your choice of implicit register or immediate.

The suppressed resources are a form of implicit resource, but they are resources not required for encoding. The suppressed operands are not normally displayed in a conventional disassembly. The suppressed operands are emitted by the decoder but are not used when encoding. They are ignored by the encoder. Examples are the stack pointer for PUSH and POP operations. There are many others, like pseudo resources.

The explicit and implicit resources are expressed resources -- they show up in disassembly and are required for encoding. The suppressed resources are considered a kind of implicit resources that are not expressed in ATT System V or Intel disassembly formats.

The suppressed operands are always after the implicit and explicit operands in the operand order.

### x87 Register stack popping

The Intel(R) Software Developers Manual indicates that "FADDP st2", reads st0, st2 writes st2 and pops the x87 stack. The result ends up in st1 after the instruction executes. That is not how XED represents the operation. XED will say that "FADDP st2" reads st0 and st2 and writes st2. The output register that XED provides is essentially "pre pop". The pop occurs afterward, conceptually. The actual result ends up in the st1 register after the stack pop operation. XED also lists the pseudo resources indicating that a stack pop has occurred. This behavior affects the output register of following instructions: FADDP, FMULP, FSUBRP, FSUBP, FDIVRP, FDIVP.

### Pseudo Resources

Some instructions reference machine registers or perform interesting operations that we need to represent. For example, the IDTR and GDTR are represented as pseudo resources. Operations that pop the x87 floating point register stack can have a X87POP or X87POP2 "register" to indicate if the x87 register stack is popped once or twice. These are part of the xed_reg_enum_t.

### Immediates and Displacements

Using the API functions for setting immediates, memory displacements and branch displacements. Immediates and Displacements are stored in normal integers internally, but they are stored endian swapped and left justified. The API functions take care of all the endian swapping and positioning so you don't have to worry about that detail.

Immediates and displacements are different things in the ISA. They can be 1, 2, 4 or 8 bytes. Branch displacements (1, 2 or 4 bytes) and Memory displacements (1, 2, 4 or 8 bytes) refer to the signed constants that are used for relative distances or memory "offsets" from a base register (including the instruction pointer) or start of a memory region.

Immediates are signed or unsigned and are used for numerical computations, shift distances, and also hold things like segment selectors for far pointers for certain jump or call instructions.

There is also a second 1B immedate used only for the ENTER instruction.

XED will try to use the shortest allowed width for a displacement or immediate. You can control XED's selection of allowed widths using a notion of "legal widths". A "legal width" is a binary number where each bit represents a legal desired width. For example, when you have a valid base register in 32 or 64b addressing, and a displacement is required, your displacement must be either 1 byte or 4 bytes long. This is expressed by OR'ing 1 and 4 together to get 0101 (base 2) or 5 (base 10).

If a four byte displacement was required, but the value was representable in fewer than four bytes, then the legal width should be set to 0100 (base 2) or 4 (base 10).

## API Reference

- INIT Initialization
- DEC Decoding instructions
- DECODE_CACHE Using the decode cache
- ENC Encoding instructions
- ENCHL High level API for encoding instructions
- OPERANDS Operand storage fields
- IFORM Iforms
- ISASET ISA-sets and chips
- PRINT Printing (disassembling) instructions
- REGINTFC Register interface functions
- FLAGS Flags interface functions
- AGEN Address generation calculation support
- ENUM Enumerations
- Examples Examples

## Questions? Bugs?

Send bugs and questions to mark.charney@intel.com. Complete bug reports that are easy to reproduce are fixed faster, so try to provide as much information as possible. Include: kit number, your OS version, compiler version. Try to reproduce the problem in a simple example that you can send us.

## Disclaimer and Legal Information

The information in this manual is subject to change without notice and Intel Corporation assumes no responsibility or liability for any errors or inaccuracies that may appear in this document or any software that may be provided in association with this document. This document and the software described in it are furnished under license and may only be used or copied in accordance with the terms of the license. No license, express or implied, by estoppel or otherwise, to any intellectual property rights is granted by this document. The information in this document is provided in connection with Intel products and should not be construed as a commitment by Intel Corporation.

EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER, AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT. Intel products are not intended for use in medical, life saving, life sustaining, critical control or safety systems, or in nuclear facility applications.

Designers must not rely on the absence or characteristics of any features or instructions marked "reserved" or "undefined." Intel reserves these for future definition and shall have no responsibility whatsoever for conflicts or incompat- ibilities arising from future changes to them.

The software described in this document may contain software defects which may cause the product to deviate from published specifications. Current characterized software defects are available on request.

Intel, the Intel logo, Intel SpeedStep, Intel NetBurst, Intel NetStructure, MMX, Intel386, Intel486, Celeron, Intel Centrino, Intel Xeon, Intel XScale, Itanium, Pentium, Pentium II Xeon, Pentium III Xeon, Pentium M, and VTune are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

Other names and brands may be claimed as the property of others.

Copyright (c) 2002-2013 Intel Corporation. All Rights Reserved.