Search code examples
assemblyx86x86-64machine-codeopcode

x64 instruction encoding and the ModRM byte


The encoding of

call qword ptr [rax]
call qword ptr [rcx]

is

FF 10
FF 11

I can see where the last digit (0/1) comes from (the register number), but I'm trying to figure out where the second last digit (1) comes from. According to AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions page 56,

"/digit - Indicates that the ModRM byte specifies only one register or memory (r/m) operand. The digit is specified by the ModRM reg field and is used as an instruction-opcode extension. Valid digit values range from 0 to 7."

The equivalent Intel document says something similar, and call via a register is specified to be encoded as

FF /2

and... I have no idea what that means, or how the 2 in the specification connects to the high 1 digit in the end result. Is there a differently worded explanation available anywhere?


Solution

  • The ModR/M byte has 3 fields:

    bit 7 & bit 6 = mod
    bit 5 through bit 3 = reg = /digit
    bit 2 through bit 0 = r/m
    

    This is depicted in Figure 2-1. Intel 64 and IA-32 Architectures Instruction Format of Vol. 2A of Intel® 64 and IA-32 Architectures Software Developer’s Manual.

    So, there:

      0x10 = 00.010.000 (mod=0, reg/digit=2, r/m=0)

    and

      0x11 = 00.010.001 (mod=0, reg/digit=2, r/m=1).