4

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.

  • 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 '16 at 13:41
  • @0xC0000022L but don't they all have different opcodes? if not how do you differentiate between them? – Vallentin Apr 13 '16 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 '16 at 13:43
  • @0xC0000022L ahh yes, but I'm disassembling machine code, and need to figure out the length of instructions. – Vallentin Apr 13 '16 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 '16 at 13:45
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.

  • This for now is what I'm going to go for, as it is small enough for my need. – Vallentin Apr 16 '16 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 '16 at 18:31
  • It's also only x86... – Micrified Apr 26 '18 at 13:53
4

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.)

  • Do you have a permalink for the manual, including (presumably) a page number? – Vallentin Apr 15 '16 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 '16 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.

  • 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 '16 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 '16 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 '16 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 '16 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 '16 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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