3

Where is it possible to find a list of x86 instructions (and x64 instructions) with the (hex) opcode and the length/size in bytes of the instructions, such as:

  • 0x90 = NOP = 1 byte
  • 0xE9 = JMP = 5 bytes
  • 0x8B = MOV = 2 bytes
  • 0x55 = PUSH = 1 byte
  • 0x6A = PUSH = 2 bytes
  • 0x68 = PUSH = 5 bytes

Unsure if all of them are correct.

I've been using this wonderful list, to look through instructions and their opcodes, but it doesn't contain the full length/size in bytes of each opcode.

What confuses me a bit more, is how it at the beginning mentions "one-byte opcodes" and "two-byte opcodes". While the JMP command would be 5 bytes (1 byte for JMP command, 4 bytes for jump distance).

Edit

I don't specifically need a list per se. Overall I'm just searching for a way to deduce the length of instructions.

7
  • There are several jmp opcodes. That's why you have "short" jumps, for example (+/-127 Byte, IIRC). And those are not 5 Byte. Also, the opcode is usually considered x-Byte depending on the opcode, without the operands.
    – 0xC0000022L
    Apr 13, 2016 at 13:41
  • @0xC0000022L but don't they all have different opcodes? if not how do you differentiate between them?
    – vallentin
    Apr 13, 2016 at 13:42
  • They have a different binary representation, exactly. But they are all formally called jmp in their mnemonic form. Also, do you actually need a list, or do you need simply a library/framework to decode opcodes properly?
    – 0xC0000022L
    Apr 13, 2016 at 13:43
  • @0xC0000022L ahh yes, but I'm disassembling machine code, and need to figure out the length of instructions.
    – vallentin
    Apr 13, 2016 at 13:44
  • There are libraries available for that purpose. Are you certain you need to do that manually and you need a comprehensive list? Of course it would still be handy to have a list, but frankly why would you do such an analysis manually anyway. RCE is tedious enough as it is, no?
    – 0xC0000022L
    Apr 13, 2016 at 13:45

3 Answers 3

6

Instead of using a list, it would probably be much more efficient for you to use a small and portable length disassembler, such as https://github.com/greenbender/lend.

3
  • This for now is what I'm going to go for, as it is small enough for my need.
    – vallentin
    Apr 16, 2016 at 8:12
  • Beware that disassembler is under GPLv3, which makes it rather unwieldy for many purposes outside of the FLOSS realm.
    – 0xC0000022L
    Apr 16, 2016 at 18:31
  • It's also only x86...
    – Micrified
    Apr 26, 2018 at 13:53
5

The definitive list is, unsurprisingly, available in Intel's manuals for these processors. These are free downloads from Intel's website. What you want most, or first, is the opcode map. This is important enough that it's typically, if not always, Appendix A in the Software Developer's Manual, Programmer's Reference Manual or whatever.

An opcode map is ordered by the first byte and summarises for you how the instruction continues. For instance, this is where you discover that 0x8B is not just a MOV but specifically a MOV of a word or dword (depending on the operand size attribute) from an effective address to a general register, and that the operand can therefore have a range of formats (whose encoding details are in another appendix) such that the whole instruction is at least 2 bytes but may be as long as 7 bytes (being a mod r/m byte, an optional s-i-b byte, and an optional displacement).

As for the one-byte and two-byte opcodes - and even longer nowadays - these refer just to the bytes at the instruction's start which are necessary for beginning the instruction, however many bytes may follow for the operands. Originally, there were only one-byte opcodes (unless we count escapes to the coprocessor). As the map filled, 0x0F was selected as introducing two-byte opcodes. For instance, the SMSW instruction always starts 0x0F 0x01, whatever its operands. (There is always also a third byte, which differentiates SMSW from other instructions that begin 0x0F 0x01, but I leave the understanding of this as your exercise when you peruse the manuals.)

2
  • Do you have a permalink for the manual, including (presumably) a page number?
    – vallentin
    Apr 15, 2016 at 17:36
  • @Vallentin: how about this one? They used to be available as hard copies. I still have two sets of those.
    – 0xC0000022L
    Apr 18, 2016 at 11:15
0

Making such a list is impossible (depending on what comes after bytes like 8B it may be much longer than 2 bytes). I recommend you use a disassembly library, as almost all will calculate the length and you can access it from there. There are some bytes with a register / number as the only operand, but even in those cases a prefix can change their behavior.

9
  • 1
    "Making such a list is impossible", that is just plain wrong. If it is impossible to deduce the bytes, then it would we as impossible to execute.
    – vallentin
    Apr 13, 2016 at 16:29
  • I mean it's impossible to make a list of "push is 2 bytes". I'm saying you can't look up the opcode to find the length.
    – Lupe
    Apr 13, 2016 at 19:16
  • 2
    that is still complete bogus. If the languages isn't governed by fixed rules. Then it would again be impossible to execute machine code.
    – vallentin
    Apr 13, 2016 at 19:18
  • 1
    Do you feel that you can always determine the length of the instruction by the opcode? I know it's governed by fixed rules; I wrote a disassembler as a project. I think either you aren't understand what I'm saying or I'm not understanding what he's asking: I'm saying that if you have the opcode (e.g. 8B) you can't determine the full length reliably.
    – Lupe
    Apr 13, 2016 at 19:25
  • 1
    I use this most of the time ref.x86asm.net/coder32.html x64 is linked from the homepage
    – Sigtran
    Apr 14, 2016 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.