Читать «Журнал «Компьютерра» №41 от 08 ноября 2005 года» онлайн - страница 32

Журнал 613 Компьютерра

Но кто сказал, что x86-64 - это только 64-битные указатели, команды и регистры GPR?..

IA-32 versus x86-64

Переделывая почти весь процессор и весь набор поддерживаемых им инструкций, мы все равно получаем несовместимость в 64-битном режиме со старыми программами. Так почему бы заодно не исправить ошибки предшественников и не убрать из x86 устаревшие ограничения? 64-битный режим не просто улучшенная версия IA-32 ISA, фактически это следующая версия архитектуры x86, во многом лишенная «родовых травм» этого семейства, начинавшегося с микроконтроллеров и долгое время не претендовавшего на «серьезное» использование.

Первое и, пожалуй, главное преимущество, которое получила архитектура x86-64, - долгожданная поддержка шестнадцати регистров общего назначения и шестнадцати регистров XMM. На первый взгляд это чисто количественное изменение, но на самом деле - принципиальная во всех отношениях доработка архитектуры IA-32. Судите сами: у современного IA-32 восемь регистров общего назначения (EAX, EBX, ECX, EDX, EDI, ESI, EBP и ESP), восемь 64-битных регистров MMX (MMX0-MMX7) и восемь же регистров SSE (XMM0-XMM7). Не замечаете ничего странного? Откуда вообще взялась цифра восемь? Для ответа на этот вопрос нам потребуется обратиться к «основам основ» - к формату x86-инструкций.

Каждая инструкция представляет собой длинную комбинацию из пяти составляющих: а) опкода (operation code, opcode), описывающего, что нужно сделать с данными, б) поля ModR/M, в котором записывается «подвид» инструкции, режим адресации памяти (как и у всякого CISC-процессорa, этих подвидов у x86 много) и один или два регистра, используемых инструкцией, в) поля SIB (Scale-Index-Base), в котором при некоторых режимах адресации памяти записываются еще два регистра (база и индекс) и масштаб, г) полей Displacement и Immediate, в них записываются используемые инструкцией константы, д) набора «приставок» (prefixes), позволяющих задать «нестандартные» режимы использования инструкции. Обязательным является только поле опкода, все остальные опциональны и могут отсутствовать[Теперь понимаете, что имелось в виду под «непомерной сложностью декодирования CISC-инструкций»?].

Оставим в стороне вопрос о том, для чего нужна столь сложная конструкция и как она работает, и сосредоточимся на одном-единственном интересующем нас аспекте: как в x86 кодируются используемые инструкциями операнды. Смотрите: поля Reg/Opcode[В принципе здесь может быть записан не регистр, а (для некоторых инструкций) дополнительный опкод, указывающий на ту или иную разновидность одной и той же инструкции] и R/M[Здесь тоже не всегда записывается регистр - иногда это поле используют для кодирования одной из 24 разновидностей режимов адресации памяти. В x86 много подобных «тонкостей»] занимают по три бита, поля Index и Base в SIB - тоже трехбитные. А трехбитных комбинаций, как легко посчитать, всего восемь, именно столько регистров может быть одновременно доступно любой программе. Так было задумано еще три десятка лет назад, при проектировании Intel 8086, и с тех пор ничего не изменилось, хотя Pentium 4 отличается от 8086, как небо от земли. Восемь регистров современных Athlon и Pentium не блажь разработчиков и не техническая необходимость, а фундаментальное ограничение самого набора инструкций x86.