Почему Intel не сделала доступной старшую часть регистров своих процессоров? - PullRequest
6 голосов
/ 15 марта 2011

При программировании на ассемблере и выполнении каких-либо манипуляций со строками я использую al, ah и иногда другие для хранения символов, потому что это позволяет мне хранить больше данных в моих регистрах. Я думаю, что это очень удобная функция, но инженеры Intel, похоже, не согласны со мной, потому что они не сделали доступными два старших байта регистров (или я ошибаюсь?). Я не понимаю почему. Я думал об этом некоторое время, и мои предположения:

  1. Они могут сделать процессор слишком сложным
  2. Они были бы бесполезны
  3. возможно, оба из вышеперечисленных

Я придумал номер два, потому что никогда не видел, чтобы скомпилированная программа (скажем, с gcc) использовала al или bh или любую из них.

Ответы [ 5 ]

9 голосов
/ 16 марта 2011

Хотя это немного неуклюже, вы можете просто поменять местами регистры с помощью rol reg,16 (или ror reg,16, если хотите). На процессорах Netbust (Pentium IV) это довольно неэффективно, но на большинстве более новых (или более старых) процессоров у вас обычно есть смещение ствола, чтобы сделать это за один такт.

Что касается того, почему они этого не сделали, то все довольно просто: им нужно было бы полностью переделать кодировку инструкций, если они действительно хотят это сделать. В оригинальном дизайне они использовали все коды, которые соответствовали размерам полей, которые они использовали для указания регистра. Фактически, они уже используют что-то вроде хака, когда значение кодировки зависит от режима, и существуют префиксы размера адреса и размера операнда, если вам нужно использовать другой размер. Например, чтобы использовать AX при работе в 32-битном режиме, перед самой инструкцией инструкция будет иметь префикс переопределения операнда. Если бы они действительно хотели этого достаточно, они могли бы расширить эту концепцию, указав такие вещи, как «байт в битах 16–23 регистра X», но это сделало бы декодирование более сложным, а декодирование инструкций x86 уже относительно болезненно. .

6 голосов
/ 16 марта 2011

Краткий ответ из-за того, как он эволюционировал из 16 битов.

Почему нет регистра, содержащего старшие байты EAX?

5 голосов
/ 16 марта 2011

Помимо проблемы с кодировкой инструкций, которую Джерри правильно упоминает, здесь есть и другие вещи.

Большинство нетривиальных ЦП конвейерно: это означает, что при обычной работе инструкции начинают выполняться до того, как предыдущие инструкции закончили выполнение. Это означает, что процессор должен обнаруживать любые зависимости инструкции от более ранних инструкций и предотвращать выполнение инструкции до тех пор, пока не станут доступны данные (или флаги условий), от которых она зависит [1].

Наличие имен для разных частей регистра усложняет отслеживание зависимостей. Если я напишу:

mov  ax,  dx
add  eax, ecx

тогда ядро ​​должно знать, что ax является частью eax, и что дополнение должно ждать, пока не станет доступен результат перемещения. Это называется частичное обновление регистра ; хотя это кажется очень простым, разработчикам аппаратного обеспечения обычно не нравятся их, и они стараются избегать необходимости отслеживать их как можно больше (особенно в современных процессорах, вышедших из строя).

Наличие имен для верхних половин регистров добавляет дополнительный набор частичных имен регистров, которые необходимо отслеживать, что добавляет площадь матрицы и энергопотребление, но приносит мало пользы. В конце концов, именно так принимаются решения по проектированию ЦП: компромисс между площадью кристалла (и мощностью) и выгодой.

Частичное обновление регистра - не единственная вещь, которая усложняется наличием имен для верхних частей регистра, но это одно из самых простых объяснений; Есть много других мелких вещей, которые должны быть усложнены в современном процессоре x86 для его поддержки; в совокупности дополнительная сложность будет существенной.

[1] Существуют и другие способы разрешения зависимостей, но мы их здесь игнорируем для простоты; они создают аналогичные проблемы.

2 голосов
/ 16 марта 2011

В дополнение к тому, что Джерри и Стивен уже сказали.

Первые мысли, что вы должны попытаться быть консервативными с вашими кодами операций / инструкциями. Вступление в это началось с топора, ах, и ал. Есть ли добавленная стоимость при переходе к eax, чтобы обеспечить байтовый доступ к этому верхнему регистру (кроме поворотов или сдвигов, которые уже существуют, чтобы обеспечить это)? На самом деле, нет. Если вы выполняете байтовые операции, почему вы используете 32-битный регистр и почему используете старшие байты? Возможно, оптимизировать код по-другому, используя преимущества того, что доступно, или допуская то, что доступно, и используя преимущества в других областях.

Я думаю, что есть причина, по которой большинство наборов команд в мире не имеют этих четырех имен для одного и того же регистра. И я не думаю, что это патенты, которые в игре. В свое время это была, наверное, классная особенность или дизайн. Вероятно, его корни были в переходе людей с 8-битных процессоров на эту 8/16-битную штуку. Во всяком случае, я думаю, что ах, ах, аакс был плохим дизайном, и все учились на этом. Как сказал Стивен, у вас есть проблемы с аппаратным обеспечением, если вы должны были строго реализовать это в прямой логике, то это беспорядок, гнездо муксов для крыс, чтобы все соединить (плохо для скорости и плохо для питания), тогда вы попадаете во время. кошмар, который бродил Стивен. Но есть история микрокодирования для этого набора команд, так что вы по сути эмулируете эти инструкции с каким-то другим процессором, и таким же образом он добавляет к этому кошмару. Мудрее всего было бы переопределить топор как 32-битный и избавиться от ах и ал. Мудро с точки зрения дизайна, но неразумно для мобильности (хорошо для разработки, плохо для маркетинга, продаж и т. Д.). Я думаю, что причина того, что этот усталый старый набор инструкций не ограничивается книгами по истории и музеями, (среди нескольких других причин) из-за обратной совместимости.

Я настоятельно рекомендую изучить ряд других наборов инструкций, как новых, так и старых. MSP430, ARM, большой палец, MIPS, 6502, Z80, PIC (старый, который не MIPS) и т. д. Просто назвать несколько. Видеть различия и сходства между наборами инструкций очень полезно для ИМО. И в зависимости от того, насколько глубоко вы углубляетесь в понимание (переменная длина слова по сравнению с фиксированной длиной и т. Д.), Понимая, какой выбор мы делаем для Intel при выполнении этого перехода с 16 на 32 бита, а в последнее время - с 32 на 64 бита, пытаясь сохранить долю рынка. .

Я думаю, что решение, которое они выбрали в то время, было правильным, вставив ранее неопределенный код операции перед тем, что обычно декодируется как 16-битный код операции, превращая его в 32-битный код операции. Или иногда нет, если нет следующих непосредственных значений (требующих знания того, сколько читать). Казалось, в соответствии с инструкцией, установленной в то время. Итак, вернемся к ответу Джерри, причина в том, что комбинация дизайна 8/16 битной инструкции задает историю и причины ее расширения. Разумеется, они могли бы так же легко использовать аналогичное кодирование для обеспечения доступа к старшим 16 битам в топоре, ах, как и раньше, и они могли бы так же легко умножить четыре базовых регистра A, B, C, D на 8 или 16. или 32 регистра общего назначения (A, B, C, D, E, F, G, H, ...), оставаясь при этом обратно совместимыми.

1 голос
/ 16 марта 2011

Фактически, традиционные коды операций x86 допускают как выбор размера операнда (иногда как специальное кодирование команды, иногда через байты префикса), так и биты выбора номера регистра. Для выбора регистра всегда есть три бита в кодировке команд. Это позволяет в общей сложности восемь регистров.

Первоначально их было четыре, AX / BX / BP / SP для 16 бит и AL / AH / BL / BH для 8 бит.

Добавление еще двух дало CX / DX плюс CL / CH / DL / DH. Больше не осталось 8-битных регистров, но все еще два неиспользуемых значения в регистре выбора для 16-битных.

Которые были предоставлены в другой версии архитектуры Intel индексом regs DI / SI.

После этого они исчерпали 3 бита выбора регистра (и сделали невозможным предоставление 8-битных регистров для SI / DI / BP / SP).

Таким образом, 64-битному режиму AMD64 удалось удвоить набор регистров, используя префиксные байты (префикс «используйте новые регистры»), аналогично тому, как традиционный код x86 выбирал между 16 и 32-битными операциями. Тот же метод использовался для предоставления 8-битных регистров, где «традиционно» не было ни одного, то есть для SP/BP/SI/DI.

Для иллюстрации см., Например, следующие кодировки команд:

0:     00 c0                add    %al,%al
2:     00 c1                add    %al,%cl
4:     00 c2                add    %al,%dl
6:     00 c3                add    %al,%bl
8:     00 c4                add    %al,%ah
a:     00 c5                add    %al,%ch
c:     00 c6                add    %al,%dh
e:     00 c7                add    %al,%bh
10: 40 00 c4                add    %al,%spl
13: 40 00 c5                add    %al,%bpl
16: 40 00 c6                add    %al,%sil
19: 40 00 c7                add    %al,%dil

И, для [16-бит / 64-бит] / 32-бит, бок о бок, потому что это так показательно:

0   : [66/48] 01 c0     add   %?ax,%?ax
2/3 : [66/48] 01 c1     add   %?ax,%?cx
4/6 : [66/48] 01 c2     add   %?ax,%?dx
6/9 : [66/48] 01 c3     add   %?ax,%?bx
8/c : [66/48] 01 c4     add   %?ax,%?sp
a/f : [66/48] 01 c5     add   %?ax,%?bp
c/12: [66/48] 01 c6     add   %?ax,%?si
e/15: [66/48] 01 c7     add   %?ax,%?di

Префикс 0x66 обозначает 16-битную операцию, а 0x48 - один из байтов префикса для 64-битной операции (он был бы другим, если бы ваша цель и / или источник были одним из «нового» максимума). пронумерованные регистры).

Чтобы вернуться к исходному вопросу, как получить доступ к старшим битам; ну, более новые процессоры имеют инструкции SSE для этой цели; каждое 8/16/32/64-битное поле векторного регистра доступно отдельно через, например, случайные инструкции, и на самом деле большая часть кода манипуляции со строками, предоставляемого Intel / AMD в их оптимизированных библиотеках в наши дни, больше не использует обычные регистры ЦП, а вместо этого - векторные регистры. Если вам нужна симметрия между верхней / нижней половиной (или другими дробями) некоторого большего значения, используйте векторные регистры.

...