Почему? Одна очевидная причина заключается в том, что одна инструкция может включать 32-битную немедленную, например mov $address, %register
. И поэтому call rel32
может достичь любого 32-битного адреса с текущего адреса.
Этим инструкциям требуется место для кода операции (1 байт), а иногда и байта ModR / M, чтобы указать, какой регистр (ы) / память - это операнды.
Если бы инструкция была ограничена 4 байтами, потребовалось бы несколько инструкций для помещения адреса stati c в регистр, и вы не могли бы использовать его в качестве режима прямой адресации памяти , RIS C ISA обычно требуется 2 инструкции для построения произвольных 32-битных констант (включая адреса) в регистре, например, MIPS lui $t0, high_half
/ ori $t0, $t0, low_half
x86 - CISC переменной длины ; общие инструкции короткие, но более длинные инструкции возможны вместо того, чтобы заставлять вас создавать адрес или константу в регистре с отдельной инструкцией.
например, вы можете сделать movl $123456, some_static_variable
и получить кодировку инструкции с эти компоненты:
mov_opcode (1B) Mod/RM (1B) disp32 absolute address (4B) imm32=123456 (4B)
в общей сложности 10 байтов, включая два 4-байтовых значения. (В справочном руководстве по набору инструкций Intel (том 2 для x86 SDM) это форма MOV mov r/m32, imm32
с режимом адресации [disp32]
.)
You может сделать его длиннее с помощью префиксов, например префикса переопределения сегмента fs:
для локального хранилища потока. И / или режим адресации может включать в себя регистр масштабированного индекса, например movl $123456, array(,%ecx,4)
, поэтому после ModRM потребуется байт SIB (масштаб / индекс / основание) для кодирования режима адресации.
Вместо mov
, мы могли бы использовать add
, а затем мы могли бы также использовать префикс lock
, чтобы сделать его атомарной c чтение-модифицировать запись.
Жесткое ограничение на длину инструкции 15 байтов. Если декодирование не находит конца инструкции к тому времени, возникает исключение #UD
недопустимой инструкции. (Ядро Linux доставит SIGILL в процесс, вызывающий ошибку.)
(Забавный факт: исходный 8086 не имеет ограничений и будет с удовольствием продолжать цикл, пытаясь декодировать весь сегмент 64 КБ, полный префиксов rep
)