Почему нет регистра, который содержит более высокие байты EAX?
%AX = (%AH + %AL)
Так почему бы и нет %EAX = (%SOME_REGISTER + %AX)
для некоторых зарегистрироваться %SOME_REGISTER
?
3 ответа:
просто для некоторых разъяснений. В первые микропроцессорные дни 1970-х годов процессоры имели лишь небольшое количество регистров и очень ограниченный набор команд. Как правило, арифметический блок мог работать только на одном регистре процессора, часто называемом "аккумулятором". Аккумулятор на 8-битных процессорах 8080 & Z80 назывался "A". Существовало 6 других 8-битных регистров общего назначения: B, C, D, E, H & L. эти шесть регистров можно было спаривать до образования 3 16-битных регистров: BC, DE & HL. Внутри накопитель был объединен с регистром флагов для формирования 16-битного регистра AF.
когда Intel разработала 16-битное семейство 8086, они хотели иметь возможность переносить код 8080, поэтому они сохранили ту же основную структуру регистра:
8080/Z80 8086 A AX BC BX DE CX HL DX IX SI IY DI
из-за необходимости порта 8-битного кода они должны были иметь возможность ссылаться на отдельные 8-битные части AX, BX, CX & DX. Они называются AL, AH для низких и высоких байтов AX и так далее для BL/BH, CL/CH & DL/DH. ІХ & ий на Z80 когда-либо использовались только в качестве 16-битных регистров указателей, поэтому не было необходимости обращаться к двум половинам SI & DI.
AMD применила тот же трюк, когда они выпустили первые 64-битные процессоры. 64-бит версия регистра AX называется RAX. Итак, теперь у вас есть что-то вроде этого:
|63..32|31..16|15-8|7-0| |AH.|AL.| |AX.....| |EAX............| |RAX...................|
в старые 8-битные дни, был регистр А.
в 16-битные дни был 16-битный регистр AX, который был разделен на две 8-битные части, AH и AL, для тех времен, когда вы все еще хотели работать с 8-битными значениями.
в 32-битные дни был введен 32-битный регистр EAX, но все регистры AX, AH и AL были сохранены. Проектировщики не считали необходимым вводить новый 16-битный регистр, который адресовал биты с 16 по 31 EAX.
здесь опубликовано много ответов, но ни один из них не отвечает на данный вопрос: почему нет регистра, который непосредственно кодирует высокие 16 бит EAX или высокие 32 бита RAX? Ответ сводится к ограничениям самой кодировки инструкций x86.
16-Битный Урок Истории
когда Intel разработала 8086, они использовали схему кодирования переменной длины для многих инструкций. Это означало, что определенные чрезвычайно-общие инструкции, как
POP AX
, может быть представлен в виде одного байта (58), в то время как редкие (но все же потенциально полезные) инструкции, такие какMOV CX, [BX*4+BP+1023]
все еще может быть представлено, даже если для их хранения требуется несколько байтов (в этом примере 8B 8C FF 03).это может показаться разумным решением, но, когда они проектировали, они заполнили большую часть свободного пространства. Так, например, их было восемь
POP
инструкции для восьми человек регистры (AX, CX, DX, BX, SP, BP, SI, DI), и они заполняли опкоды 58 через 5F, а опкод 60 был чем-то совсем другим (PUSHA
), как и код операции 57 (PUSH DI
). Там не осталось места ни для чего после или до этого. Даже выталкивание и выталкивание сегментных регистров-что концептуально почти идентично выталкиванию и выталкиванию регистров общего назначения - должно было быть закодировано в другом месте (около 06/0E/16/1E) только потому, что не было места рядом с остальной частью push / pop инструкции.аналогично, байт" mod r/m " используется для сложной инструкции, такой как
MOV CX, [BX*4+BP+1023]
имеет только три бита для кодирования регистра, что означает, что он может представлять только восемь регистров всего. Это нормально, если у вас есть только восемь регистров, но представляет реальную проблему, если вы хотите иметь больше.(здесь есть отличная карта всех этих распределений байтов в архитектуре x86:http://i.imgur.com/xfeWv.png . Обратите внимание, как там нет пространство, оставшееся в первичной карте, с некоторыми инструкциями, перекрывающими байты, и даже сколько вторичной карты "0F" используется теперь благодаря инструкциям MMX и SSE.)
в сторону 32 и 64 бит
таким образом, чтобы даже позволить расширить дизайн процессора с 16 бит до 32 бит, у них уже была проблема с дизайном, и они решили это с префиксный байт: путем добавления специального байта" 66 " перед всеми стандартными 16-битными инструкциями, процессор знает, что вам нужна та же инструкция, но 32-разрядная версия (EAX) вместо 16-разрядной версии (AX). Остальная часть дизайна осталась прежней: в общей архитектуре процессора было всего восемь регистров общего назначения.
подобный хакер должен был быть сделан для расширения архитектуры до 64-бит (RAX и друзья); там проблема была решена путем добавления еще одного набора префиксных кодов (
REX
, 40-4F), что означало "64-бит" (и эффективно добавил еще два бит в поле" mod r/m"), а также отбрасывание странных старых инструкций, которые никто никогда не использовал, и повторное использование их байтовых кодов для новых вещей.в сторону на 8-битных регистрах
один из самых больших вопросов, чтобы спросить, то, как черт вещи, как AH и AL когда-либо работал в первую очередь, если есть только действительно место в дизайне для восьми регистров. Первая часть ответа заключается в том, что нет такой вещи, как "
PUSH AL
" - некоторые инструкции просто не может работать на байтовых регистрах вообще! Единственные, которые могут быть несколько специальных странностей (например,AAD
иXLAT
) и специальные версии инструкций" mod r/m": имея очень специфический бит, перевернутый в байте" mod r/m", эти" расширенные инструкции " могут быть перевернуты для работы с 8-битными регистрами вместо 16-битных. Так уж получилось, что есть ровно восемь 8-битных регистров: AL, CL, DL, BL, AH, CH, DH и BH (в этом порядке), и это выстраивается очень красиво с восемью слотами регистра, доступными в байте" mod r/m".так что это действительно реальный ответ: Дело не в том, что Intel или AMD намеренно "упустили" высокий 16-битный регистр для EAX или высокий 32-битный регистр для RAX: это то, что высокие 8-битные регистры являются странной оставшейся исторической аномалией и реплицируют их проектирование с более высокими битовыми размерами было бы очень сложно, учитывая требование обратной совместимости архитектуры.
Рассмотрение Производительности
есть еще одно соображение о том, почему эти" высокие регистры " не были добавлены с тех пор: внутри современных процессорных архитектур по соображениям производительности регистры переменного размера фактически не перекрываются: AH и AL не являются частью AX, а AX не является частью EAX, а EAX это не часть RAX: они все отдельные регистры под капотом, и процессор устанавливает флаг недействительности на других, когда вы манипулируете одним из них, чтобы он знал, что ему нужно будет скопировать данные, когда вы читаете от других.
(например: если вы установили AL = 5, процессор не обновляет AX. Но если вы затем читаете из AX, процессор быстро копирует эти 5 из AL в нижние биты AX.)
путем держать регистры отдельно, К. П. У. может сделать все такие умные вещи, как невидимое переименование регистра, чтобы ваш код работал быстрее, но это означает, что ваш код работает медленнее если вы используете старую схему обработки малых регистров как частей больших регистров, потому что процессор должен будет остановить и обновить их. Чтобы вся эта внутренняя бухгалтерия не вышла из-под контроля, дизайнеры процессоров мудро решили добавить отдельные регистры на более новых процессорах, а не добавлять больше перекрытий реестры.
(и да, это означает, что он действительно быстрее на современных процессорах явно "
MOVZX EAX, value
"чем делать это старым, неряшливым способом"MOV AX, value / use EAX
".)вывод
со всем сказанным, могут ли Intel и AMD добавить больше" перекрывающихся " регистров, если они действительно этого хотят? Конечно. Есть способы, чтобы червь их в том случае, если было достаточно спроса. Но учитывая значительный исторический багаж, архитектурный ограничения, заметные ограничения производительности и тот факт, что большинство кода в наши дни генерируется компиляторами, оптимизированными для неперекрывающихся регистров, маловероятно, что они добавят такие вещи в ближайшее время.