В бинарном кодировании важно свести всю работу компьютера
к обработке чисел или числовых выражений.
Поэтому для начала скажем, что все действия компьютера
будь то условные и безусловные переходы, включение и выключение
монитора, вывод текста и т.п. может быть описано числовым способом
с учётом того что числа эти хранятся в бинарном виде и имеют фиксированную
длину.
Все эти данные, будь то команды, коды регистров, текстовые коды
имеют три числовые характеристики
1. Местом где они находятся. Точнее местом где они начинаются. Место
   где они кончаются определяется через (2).
2. Колличество бит которые они занимают. (Размер определяющий предел
   числа выражаемого этим размером).
3. Состоянием этих бит (Т.е. какое число они выражают)

Например мы видем в HEX редакторе то что мы воспринимаем как двойное слово:
0100: 12345678 .........
1. Смещение от начала файла 0100h.
2. Количество бит 32
3. Состояние бит 12345678h
Т.е. 3 числовые характеристики. 0100h,20h,12345678h

Если мы изменим (2) скажем с 32 бит на 8.
и оставим смещение (3) 0100h
то получим характеристики уже:
1. Смещение 100h
2. Количество бит 8
3. Состояние бит 78h
Изменив и смещение (1) пусть на 101h и колличество бит на 16 (10h)
мы получим.
1. Смещение 101h
2. Колличество бит 10h
3. Состояние бит 3456h.

Говоря о месте, откуда инструкция должна брать операнды, имеются два
типа операндов которые можно отнести к одной категории исходя из их 
местоположения.
Это смещение (displacement) и непосредственный операнд (immediate).
пример смещения:
mov eax,[eax][15h] 8B 40 15
в мнемонике смещение обозначено как [15h]
байт в опкоде на который отражается эта часть мненоники тоже 15
пример непосредственного операнда:
mov al,15h B0 15
в мнемонике непосредственный операнд обозначен как ,15h
байт в опкоде на который отражается эта часть мнемоники тоже 15.
Мы бы могли сказать, что оба этих типа смещение и непосредственный операнд
схожи тем что их значение непосредственно включается в опкод инструкции.
Но мы скажем чуть точнее:
Их значение находится в участке памяти которую занимает инструкции.
Находится в КОНЦЕ этого участка памяти, после определяющей части.

Что такое определяющая часть? Это часть которая определяет что делать, с чем 
делать, как делать и какой размер операндов.
Например в инструкции 
mov al,15h B0 15
определяющая часть это B0
1011 0 000
Четыре старших бита определяют что это инструкция mov reg,imm
Следующий бит определяет размер операнда 0 - значит размер байт.
Следующие три бита определяют какой регистр учавствует 000 - al.
Следующий байт 15 - это значение которое нужно поместить. С ним не
нужно что либо делать дополнительно - это просто байт который будет
скопирован в al.
если в инструкции представлены одновременно и смещение и непосредственный
операнд, то после определяющей части сначала идут байты смещения, помом байты
непосредственного операнда.
например 
mov byte ptr [eax][1],2  С6 40 01 02
[1] - смещение
,2  - непосредственный операнд.
Вы видите, что после определяющей части C6 40 идут 01 02
т.е. сначала непосредственное значение смещения а потом непосредственное 
значение непосредственного операнда.

Оба типа данных, значения которых помещается непосредственно в память где 
расположена инструкция (т.е. смещение и непосредственный операнд), могут быть
представлены в "ужатом" до байта виде. Однако, мы поговорим пока о самом
простом представлении непосредственного операнда, который используется в 
инструкциях.
	mov reg,imm
	mov mem,imm

В этих инструкция часть опкода отведённая на непосредственный операнд занимает 
ровно столько бит сколько бит занимает приемник.
Приведём для наглядности пример с помещением нуля:
мнемоника	опкод

mov al,0	B4 00 ;байт непосредственного операнда 00
mov ax,0     66 B8 00 00 ;байты непосредственного операнда 00 00
mov eax,0       B8 00 00 00 00 ;байты непосредственного операнда 00 00 00 00
Т.е. на передачу 0 в al инструкция занимает 1 byte под непосредственный
операнд а в eax - 4 байта. Ровно столько каков размер самого приемника.
 
Перейдём к формату.
mov reg,imm
1011 w reg imm.
Как уже сказано часть imm будет занимать столько байт сколько и приемник.
Определение размера приемника происходит так же как и в других случаях при
помощи бита w.
Если w = 0 то размер байт и трёхбитовое поле reg определяет один из 8и 
8-разрядных регистров.
Если w = 1 то размер операнда полный (слово или двойное слово).
Наличие префикса 66h переключает команду между полным и альтернативным полным
размером (при размере по умолчанию 16 бит - делает операнд 32х битным и 
наоборот). Подробнее см. Opcode Prefixes.
Таким образом разница между размером инструкций
mov reg16,imm и mov reg32,imm 
Возрастает в 16 битном коде.
в 32 битном 
mov reg16,imm - 1byte for prefix 66 + 1(1011wreg)+2bytes for imm = 4 bytes
mov reg32,imm - 1(1011wreg)+4bytes for imm. = 5 bytes
в 16 битном
mov reg16,imm - 1(1011wreg)+2bytes for imm = 3 bytes
mov reg32,imm - 1(66h)+1(1011wreg)+4bytes of imm = 6 bytes.
простая арифметика показывает что эта разница определяется разницей размеров
непосредственных операндов и наличием (отсутсвием) префикса.
т.е  ((4+1) - 2)-(4-(2+1) = 4-4 + 2-2 + 1 +1 = 2
здесь 4 и 2 - колличество байт отведённых под непосредственный операнд.
а + 1 - наличие префикса.
Выражение банальное  - просто чтобы показать что разница эта - два размера
префикса, и занимай от x байт а не 1 она была бы 2x.
И как вывод замена mov reg32,imm на mov reg16,imm
сохраняет на 2 байта больше в 16-битном коде чем аналогичная замена в 32х 
битном.
Эта разница сохраняется и для инструкций mov mem,imm поскольку размеры 
непосредственных операндов и наличие префиксов работают в них подобным же 
образом.
Другая инструкция 
mov mem/reg, imm
Имеет следующий формат:
1100 011w modr/m(md 000 r/m)[opt. sib and/or disp] imm.
В зависимости от значений в modr/m в этот блок помимо байта modr/m 
могут быть включены последовательно байт sib и смещение.
Подробнее о кодировании операнда через modr/m см. Opcode #7.
Обычно этот формат используется только для mov mem,imm
но не что не мешает использовать его и для кодирования mov reg,imm,
поместив в поле mod 11.
При этом этот вариант будет на байт длинее чем 1011wreg imm.
Но возможно это можно будет использовать в целях выравнивания для того,
что бы увеличить длину инструкции без дополнительных команд и тактов 
процессора.
Среднее поле байта modr/m должно содержать 000. В противном случае возникнет
исколючение invalid opcode.
В остальном же операнд приемник определяется через поле m/r точно также как и
в прочих инструкциях с использованием байта modr/m. Это уже было рассмотрено в 
предыдущих статьях.
