2008-10-23 5 views
59

%AX = (%AH + %AL)Почему нет регистра, который содержит более высокие байты EAX?

Так почему бы не %EAX = (%SOME_RESTIER + %AX) для некоторого регистра %SOME_REGISTER?

+1

Не могли бы вы уточнить? – BCS 2008-10-23 01:36:26

+6

незначительная коррекция, EAX не равна AX, точнее, AX представляет младшие 16 бит (половину) EAX. Аналогично, AH и AL являются двумя половинами AX. – 2008-10-23 02:40:37

+0

@EvanTeran Возможно ли получить верхнюю половину EAX, а также нижнюю половину? – 2013-03-05 15:27:40

ответ

128

Просто для уточнений. В ранние микропроцессорные дни 1970-х годов у процессоров было только небольшое количество регистров и очень ограниченный набор инструкций. Как правило, арифметический блок может работать только на одном регистре CPU, который часто называют «аккумулятором». Аккумулятор на 8 бит 8080 & Процессоры Z80 назывались «А». Было 6 других 8-разрядных регистров общего назначения: B, C, D, E, H & L. Эти шесть регистров можно было спаривать, чтобы сформировать 3 16-битных регистра: BC, DE & HL. Внутри накопитель был объединен с регистром Flags для формирования битового регистра AF 16.

Когда 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. IX & IY на Z80 использовались только как 16-разрядные регистры указателей, поэтому не нужно было обращаться к двум половинам SI & DI.

Когда 80386 был выпущен в середине 1980-х годов, они создали «расширенные» версии всех регистров. Таким образом, AX стал EAX, BX стал EBX и т. Д. Не нужно было получать доступ к верхним 16 битам этих новых расширенных регистров, поэтому они не создали псевдо-регистр EAXH.

AMD применила тот же трюк, когда они выпустили первые 64-разрядные процессоры. 64-разрядная версия регистра AX называется RAX. Итак, теперь у вас есть что-то, что выглядит следующим образом:

|63..32|31..16|15-8|7-0| 
       |AH.|AL.| 
       |AX.....| 
     |EAX............| 
|RAX...................| 
25

В старые 8-битные дни существовал регистр A.

В 16-битные дни существовал 16-разрядный регистр AX, который был разделен на две 8-битные части, AH и AL, в те периоды, когда вы все еще хотели работать с 8-битными значениями.

В 32-битные дни был введен 32-разрядный регистр EAX, но все регистры AX, AH и AL были сохранены. Дизайнеры не чувствовали необходимости вводить новый 16-битный регистр, который адресовал биты с 16 по 31 EAX.

20

Есть много ответов, размещенных здесь, но никто на самом деле не ответить на данный вопрос: почему не существует регистра, который непосредственно кодирует высокие 16 бит EAX или 32 бита RAX? Ответ сводится к ограничениям самой кодировки инструкции x86.

16-Bit Урок истории

Когда 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» байт в nt всех стандартных 16-битных инструкций, CPU знает, что вам нужна одна и та же команда, но 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 отметил, что дизайн 8086 должен был быть «совместим с исходным кодом» с 8080/8085: в 8086 была предусмотрена эквивалентная инструкция для каждой из инструкций 8080/8085, но она не использовалась те же байтовые коды (они даже не близки), и вам придется перекомпилировать (собрать) вашу программу, чтобы заставить ее использовать новые байт-коды. Но «совместимый с исходным кодом» был способом продвижения старого программного обеспечения, и это позволяло отдельным пользователям A, B, C 8085 и т. Д.и комбинированные регистры «BC» и «DE», чтобы по-прежнему работать над новым процессором, даже если они теперь назывались «AL» и «BL» и «BX» и «DX» (или независимо от того, какое отображение было).

Это действительно реальный ответ. Это не то, что Intel или AMD намеренно «оставили» высокий 16-разрядный регистр для EAX или высокий 32-разрядный регистр для RAX: это то, что высокие 8-битные регистры странная остаточная историческая аномалия и репликация их дизайна при более высоких размерах бит были бы действительно сложными, если бы требовалось, чтобы архитектура была обратно совместимой.

Перформанс Рассмотрение

Существует еще один соображение, почему эти «высокие регистры» не были добавлены, поскольку, как хорошо: Внутри современных архитектур процессоров, по соображениям производительности, переменно размера регистров фактически не перекрываются для реального: AH и AL не являются частью AX, а AX не является частью EAX, и EAX не является частью RAX: все они являются отдельными регистрами под капотом, а процессор устанавливает флаг недействительности для других при манипулировании одним из них, чтобы он знал, что ему нужно будет скопировать данные, когда вы читаете их.

(Например: если вы установите AL = 5, процессор не обновляет AX Но если вы затем считываемые из AX, процессор быстро копирует, что 5 из AL в нижние биты Акса.).

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

(И да, это означает, что это на самом деле быстрее на современных процессорах явно «MOVZX EAX, value», чем сделать это старый, sloppier путь «MOV AX, value/use EAX».)

Заключение

С все, что сказал, может ли Intel и AMD добавить больше «перекрывающихся» регистров, если они действительно действительно хотели? Конечно. Есть способы черви их, если будет достаточно спроса. Но учитывая значительный исторический багаж, существующие архитектурные ограничения, заметные ограничения производительности и тот факт, что большинство кодов в эти дни генерируются компиляторами, оптимизированными для неперекрывающихся регистров, маловероятно, что они добавят такие вещи в ближайшее время.

 Смежные вопросы

  • Нет связанных вопросов^_^