16-битные режимы адресации позволяют только одному байту ModRM кодировать регистр (3 бита), режим (2 бита) и операнд регистра / памяти (3 бита), поэтому нет места для закодировать масштабный коэффициент или даже разрешить произвольным регистрам быть основаниями или индексами. 16-битные режимы адресации NASM x86 перечисляет их все, это не длинный список! Просто подмножества (BP|BX) + (DI|SI) + disp0/8/16
. Помните, что в такой инструкции, как add cx, [bx+si]
, для назначения регистра требуется 3-битовое поле /r
в ModRM, чтобы закодировать, какой из 8 регистров GP.
(2-битный «режим» сигнализирует, является ли он регистром или памятью, например, add bx, cx
против add [bx], cx
и сколько существует байтов непосредственного смещения: disp8 / disp16 или без смещения.)
В 32/64-битных режимах адресации поле r / m в ModRM может быть escape-кодом, который сигнализирует о присутствии байта SIB (Scale / Index / Base) , что дает место для кодировать режимы адресации с масштабированным индексом с помощью 2-битного счетчика сдвигов.
А также достаточно места для кодирования, чтобы мы могли использовать любой регистр в качестве базы и любой регистр (кроме ESP) в качестве индекса. Таким образом, 32-битные режимы адресации делают регистры более ортогональными. См. rbp не разрешен в качестве базы SIB? для подробной информации о escape-последовательностях, например [esp]
всегда нужен байт SIB, потому что кодировка, которая будет означать base = ESP, является escape-кодом для присутствия байта SIB.
См. https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing_2 или таблицы ModRM / SIB в руководствах Intel для получения более подробной информации.