x64 instruction encoding and the ModRM byte
assembly, machine-code, opcode, x86, x86-64
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`).
Problem
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?