Каждый доступ к памяти имеет размер операнда, указанный в инструкции машинного кода. (Режим адресации не является подходящим термином: разные режимы адресации - это разные способы задания наименьшего адреса фрагментадоступная память, например [rdi]
против [rdi + rdx*8]
против [RIP + rel32]
)
Кодирование различных размеров операндов выполняется с префиксами (для 16 против 32 против 64-битных дляцелочисленные инструкции) или другой код операции для той же мнемоники (8-разрядное целое). Или с битами в префиксе VEX или EVEX для инструкций AVX / AVX512, которые могут использовать регистры xmm, ymm или zmm.
Декодирование также зависит от текущего режима, подразумевающего размер операнда по умолчанию: 32 для 32- и 64-битного режима или 16 для 16-битного режима. Префикс 66
opererand-size подразумевает противоположный размер.
В 64-битном режиме бит .W
(ширина) в префиксе REX устанавливает размер операнда равным 64-битному. (И некоторые инструкции, такие как push
/ pop
, по умолчанию используют 64-битный размер операнда без префикса, но большинство инструкций, таких как add
/ sub
/ mov
, все еще по умолчанию 32-битные)
Также есть префикс 0x67
размера адреса, который меняет режимы адресации на другой размер. (16 против 32 или в 64-битном режиме 64 -> 32.)
Например, mov [rdi], eax
- это хранилище слов, и кодирование машинного кода будет указывать это, не используя специальныхпрефиксы кода операции для 16/32/64-битного размера операнда. (см. https://www.felixcloutier.com/x86/mov для доступных кодировок. Но обратите внимание, что руководство Intel не упоминает 66
префиксы размера операнда в каждой записи: у него есть 2 идентичных кодировки с различными размерами. У вас естьчтобы узнать, какой из них нуждается в префиксе 66
на основе значения по умолчанию для текущего режима.)
16-битный размер операнда, такой как mov [rdi], ax
, будет иметь тот же машинный код, что и префикс размера операнда 66
.
8-битный размер операнда (mov [rdi], al
) имеет собственный код операции, префиксы не нужны.
movzx
/ movsx
- интересные случаи:размер доступа к памяти отличается от регистра назначения. Размер доступа к памяти (байт или слово) определяется кодом операции. Префиксы размера операнда влияют только на размер назначения. За исключением x86-64 63 /r
movsxd
(dword-> qword sign-extension), где префикс 66
размера операнда делает уменьшение размера доступа к памяти до m16
в соответствии с назначением.
Аналогично для SIMD-инструкций;кодировка команд однозначно определяет размер доступа к памяти, а также регистры для чтения или записи.