Поиск…


16-разрядные регистры

Когда Intel определила оригинальный 8086, это был 16-разрядный процессор с 20-битной адресной шиной (см. Ниже). Они определили 8 16-разрядных регистров общего назначения, но дали определенные роли для определенных инструкций:

  • AX Аккумуляторный регистр.
    Многие коды операций либо принимали этот регистр, либо быстрее, если он был указан.
  • DX Регистр данных.
    Иногда это сочеталось как 16 бит 32-битного значения с AX - например, в результате умножения.
  • CX Регистр счетчика.
    Это использовалось в ряде ориентированных на цикл инструкций в качестве неявного счетчика для этих циклов - например, LOOPNE (цикл, если не равный) и REP (повторное перемещение / сравнение)
  • BX Базовый регистр.
    Это можно использовать для индексации базы структуры в памяти - ни один из вышеперечисленных регистров не может использоваться для непосредственного индексации в память.
  • SI Регистр исходного индекса.
    Это был неявный исходный индекс в памяти для определенных операций перемещения и сравнения.
  • DI Регистр индекса назначения.
    Это был неявный индекс назначения в память для определенных операций перемещения и сравнения.
  • SP Регистр указателя стека.
    Это наименее универсальный регистр в наборе! Он указал на текущую позицию в стеке, которая была явно использована для операций PUSH и POP , неявно для CALL и RET с подпрограммами, и ОЧЕНЬ неявно во время прерываний. Таким образом, использование его для чего-либо другого было опасным для вашей программы!
  • BP Регистр базового указателя.
    Когда подпрограммы вызывают другие подпрограммы, стек содержит несколько «кадров стека». BP может использоваться для хранения текущего кадра стека, а затем, когда была вызвана новая подпрограмма, она может быть сохранена в стеке, новый стек стека создан и используется, а при возврате из внутренней подпрограммы можно восстановить значение старого фрейма стека ,

Заметки:

  1. Первые три регистра не могут использоваться для индексирования в память.

  2. BX , SI и DI по умолчанию в текущий сегмент данных (см. Ниже).

     MOV    AX, [BX+5]     ; Point into Data Segment
     MOV    AX, ES:[DI+5]  ; Override into Extra Segment
    
  3. DI , при использовании в операциях памяти в оперативную память , такие как MOVS и CMPS , исключительно использует Добавочный сегмент (см ниже). Это нельзя переопределить.

  4. SP и BP используют сегмент стека (см. Ниже) по умолчанию.

32-разрядные регистры

Когда Intel выпустила 80386, они обновились с 16-разрядного процессора до 32-разрядного. 32-битная обработка означает две вещи: обе манипулируемые данные были 32-битными, а адреса доступа к памяти были 32-разрядными. Чтобы сделать это, но по-прежнему совместимы с более ранними процессорами, они представили совершенно новые режимы для процессора. Это было либо в 16-битном режиме, либо в 32-битном режиме, но вы можете переопределить этот режим по принципу «инструкция за инструкцией» для данных, адресации или обоих!

Прежде всего, они должны были определить 32-битные регистры. Они сделали это, просто расширив существующие восемь из 16 бит до 32 бит и предоставив им «расширенные» имена с префиксом E : EAX , EBX , ECX , EDX , ESI , EDI , EBP и ESP . Нижние 16 бит этих регистров были такими же, как и раньше, но верхние половины регистров были доступны для 32-битных операций, таких как ADD и CMP . Верхние половинки не были доступны отдельно, как это было сделано с 8-битными регистрами.

Процессор должен был иметь отдельные 16-битные и 32-битные режимы, потому что Intel использовал одни и те же коды операций для многих операций: CMP AX,DX в 16-битном режиме и CMP EAX,EDX в 32-битном режиме имели точно такие же коды операций ! Это означало, что один и тот же код НЕ МОЖЕТ запускаться в любом режиме:

Код операции для «Переместить немедленно в AX » равен 0xB8 , за которым следуют два байта 0xB8 0x12 0x34 значения: 0xB8 0x12 0x34

Код операции для «Переместить немедленно в EAX » равен 0xB8 , за которым следуют четыре байта непосредственного значения: 0xB8 0x12 0x34 0x56 0x78

Таким образом, ассемблер должен знать, в каком режиме находится процессор при выполнении кода, чтобы он знал, что испускает правильное количество байтов.

8-битные регистры

Первые четыре 16-битных регистра могли бы иметь их верхнюю и нижнюю половину байт, которые были доступны непосредственно в качестве собственных регистров:

  • AH и AL - это верхние и нижние половинки регистра AX .
  • BH и BL - это верхние и нижние половинки регистра BX .
  • CH и CL - это верхние и нижние половинки регистра CX .
  • DH и DL - это верхние и DX регистры регистра DX .

Обратите внимание, что это означает, что изменение AH или AL немедленно изменит AX ! Также обратите внимание, что любая операция в 8-битном регистре не может повлиять на его «партнер» - приращение AL такое, что оно переполнено с 0xFF на 0x00 , не изменит AH .

64-разрядные регистры также имеют 8-битные версии, представляющие их нижние байты:

  • SIL для RSI
  • DIL для RDI
  • BPL для RBP
  • SPL для RSP

То же самое относится к регистрам R8 через R15 : их соответствующие нижние части байта называются R8B - R15B .

Сегментные регистры

сегментация

Когда Intel разрабатывала оригинальные 8086, уже было множество 8-разрядных процессоров с 16-разрядными возможностями, но они хотели создать настоящий 16-разрядный процессор. Они также хотели создать что-то лучшее и более способное, чем то, что уже было там, поэтому они хотели иметь доступ к максимальному объему памяти 65 536 байт, что подразумевалось 16-разрядными регистрами адресации.

Регистры исходного сегмента

Поэтому они внедрили идею «Сегменты» - блок памяти объемом 64 килобайта, индексированный 16-разрядными регистрами адресов, которые могут быть повторно основаны на адресах различных областей общей памяти. Чтобы удерживать эти сегментные базы, они включали регистры сегментов:

  • CS Регистр сегмента кода.
    Это содержит сегмент кода, который в настоящее время выполняется, индексируется неявным регистром IP (указателем инструкций).
  • DS Регистр сегмента данных.
    Это содержит сегмент по умолчанию для данных, которыми управляет программа.
  • ES Регистр дополнительных сегментов.
    Это содержит второй сегмент данных для одновременных операций с данными по всей памяти.
  • SS Регистр сегмента стека.
    Это удерживает сегмент памяти, который содержит текущий стек.

Размер сегмента?

Регистры сегментов могут быть любого размера, но их ширина 16 бит облегчает взаимодействие с другими регистрами. Следующий вопрос: должны ли сегменты перекрываться, и если да, то сколько? Ответ на этот вопрос будет определять общий объем памяти, к которому можно получить доступ.

Если бы не было перекрытия вообще, тогда адресное пространство было бы 32 бита - 4 гигабайта - совершенно неслыханный размер в то время! Более «естественное» перекрытие 8 бит создаст 24-битное адресное пространство или 16 мегабайт. В конце концов Intel решила сохранить еще четыре адресных контакта на процессоре, сделав адресное пространство 1 мегабайт с 12-битным перекрытием - они считали это достаточно большим на время!

Больше регистров сегментов!

Когда Intel разрабатывала 80386, они признали, что существующего набора из 4 регистров сегмента недостаточно для сложности программ, которые они хотели, чтобы они могли поддерживать. Поэтому они добавили еще два:

  • FS Регистр дальнего сегмента
  • GS Регистр глобального сегмента

Эти новые регистры сегментов не имели применений, которые использовались в процессорах: они были просто доступны для любого программиста.

Некоторые говорят, что имена были выбраны просто для продолжения темы C , D , E существующего набора ...

64-разрядные регистры

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

Для однонаправленного Intel они придумали 64-битные расширения для 32-битного дизайна Intel и выпустили первый 64-битный чип, который все еще мог бы работать с 32-разрядным кодом x86. Intel закончила дизайн AMD в своих версиях 64-битной архитектуры.

64-битная конструкция сделала ряд изменений в наборе регистров, сохраняя обратную совместимость:

  • Существующие регистры общего назначения были расширены до 64 бит и названы с префиксом R : RAX , RBX , RCX , RDX , RSI , RDI , RBP и RSP .

    Опять же, нижние половины этих регистров были теми же E prefix-регистрами, что и раньше, и верхние половины не могли быть независимо доступны.

  • Добавлено еще 8 64-битных регистров и не названы, а просто пронумерованы: R8 , R9 , R10 , R11 , R12 , R13 , R14 и R15 .
    • 32-разрядная R8D половина этих регистров составляет от R8D до R15D (D для DWORD, как обычно).
    • К младшим 16 битам этих регистров можно было получить суффикс W до имени регистра: R8W R15W .
  • Теперь можно получить доступ к самым низким 8 битам из всех 16 регистров:
    • Традиционные AL , BL , CL и DL ;
    • Низкие байты (традиционно) указателя регистрируются: SIL , DIL , BPL и SPL ;
    • А низкие байты 8 новых регистров: R8B через R15B .
    • Однако AH , BH , CH и DH недоступны в инструкциях, в которых используется префикс REX (для 64-разрядного размера операнда или для доступа к R8-R15 или для доступа к SIL , DIL , BPL или SPL ). С префиксом REX бит-шаблон машинного кода, который раньше означал AH означает SPL и т. Д. См. Таблицу 3-1 руководства по эксплуатации инструкции Intel (том 2).

Запись в 32-разрядный регистр всегда нулирует верхние 32 бита регистра полной ширины, в отличие от записи в 8 или 16-разрядный регистр (который сливается со старым значением, что является дополнительной зависимостью для исполнения вне порядка ).

Регистрация флагов

Когда арифметический логический блок x86 (ALU) выполняет операции типа NOT и ADD , он помещает результаты этих операций («стал нулевым», «переполнен», «стал отрицательным») в специальном 16-битном регистре FLAGS . 32-разрядные процессоры обновили это до 32 бит и назвали его EFLAGS , в то время как 64-разрядные процессоры обновили его до 64 бит и назвали его RFLAGS .

Коды условий

Но независимо от имени, регистр не доступен напрямую (за исключением нескольких инструкций - см. Ниже). Вместо этого отдельные флаги ссылаются в определенных инструкциях, таких как условный переход или условный набор, известный как Jcc и SETcc где cc означает «код условия» и ссылается на следующую таблицу:

Код условия название Определение
E , Z Равно, ноль ZF == 1
NE , NZ Не равно, но не ноль ZF == 0
O перелив OF == 1
NO Нет переполнения OF == 0
S подписанный SF == 1
NS Не подписано SF == 0
P паритет PF == 1
NP Нет четности PF == 0
-------------- ---- ----------
C , B , NAE Нести, ниже, не выше или равно CF == 1
NC , NB , AE Не переносите, не ниже, выше или равно CF == 0
A , NBE Выше, не ниже или равно CF == 0 и ZF == 0
NA , BE Не выше, ниже или равно CF == 1 или ZF == 1
--------------- ---- ----------
GE , NL Больше или равно, не меньше SF == OF
NGE , L Не больше или равно, меньше SF ! = OF
G , NLE Больше, не меньше или равно ZF == 0 и SF == OF
NG , LE Не больше, меньше или равно ZF == 1 или SF ! = OF

В 16 бит вычитание 1 из 0 равно либо 65,535 либо -1 зависимости от того, используется ли беззнаковая или подписанная арифметика, но пункт назначения имеет значение 0xFFFF любом случае. Только интерпретируя коды условий, значение ясно. Еще более важно, если 1 вычитается из 0x8000 : в беззнаковой арифметике, которая просто меняет 32,768 на 32,767 ; в то время как в знаковой арифметике он меняет -32,768 в 32,767 - гораздо более примечательное переполнение!

Коды условий сгруппированы в три блока в таблице: знак-нерелевантный, неподписанный и подписанный. Именование внутри последних двух блоков использует «Выше» и «Ниже» для неподписанных, а «Большой» или «Меньше» для подписания. Таким образом, JB будет «Jump if Below» (без знака), тогда как JL будет «Jump if Less» (подписано).

Доступ к FLAGS напрямую

Вышеупомянутые коды условий полезны для интерпретации предопределенных понятий, но фактические биты флага также доступны непосредственно со следующими двумя инструкциями:

  • LAHF Загрузить регистр AH с помощью флагов
  • SAHF Store AH регистрируется во флагах

С этими инструкциями копируются только определенные флаги. Весь регистр FLAGS / EFLAGS / RFLAGS можно сохранить или восстановить в стеке:

  • PUSHF / POPF Push / pop 16-бит FLAGS в / из стека
  • PUSHFD / POPFD Push / pop 32-разрядные EFLAGS в / из стека
  • PUSHFQ / POPFQ Push / pop 64-разрядные RFLAGS на / из стека

Обратите внимание, что прерывания сохраняют и восстанавливают текущий регистр [R/E]FLAGS автоматически.

Другие флаги

Помимо флагов ALU, описанных выше, регистр FLAGS определяет другие флагов системного состояния:

  • IF Флаг прерывания.
    Это задано с инструкцией STI чтобы глобально разрешить прерывания и очиститься с помощью команды CLI чтобы глобально отключить прерывания.
  • DF Флаг направления.
    Память-память операции , такие как CMPS и MOVS (для сравнения и перемещения между ячейками памяти) автоматически увеличивать или уменьшать регистры индекса в качестве части инструкции. Флаг DF определяет, что происходит: если он очищен командой CLD , они увеличиваются; если они установлены с инструкцией STD , они уменьшаются.
  • TF Флаг ловушки. Это флаг отладки. Установка этого параметра превратит процессор в режим «одноступенчатый»: после выполнения каждой команды он вызывается «Обработчик прерываний с одним шагом», который, как ожидается, будет обрабатываться отладчиком. Нет инструкций по установке или очистке этого флага: вам нужно манипулировать битом, пока он находится в памяти.

Флаги 80286

Чтобы поддерживать новые многозадачные объекты в 80286, Intel добавила дополнительные флаги в регистр FLAGS :

  • IOPL Уровень привилегий ввода-вывода.
    Для защиты многозадачного кода некоторые задачи требовали привилегий для доступа к портам ввода-вывода, в то время как другим пришлось прекратить доступ к ним. Intel представила четырехуровневую шкалу Privilege, причем 00 2 является наиболее привилегированным, а 11 2 - наименее. Если IOPL меньше текущего уровня привилегий, любая попытка доступа к портам ввода-вывода, а также включение или отключение прерываний приведет к сбою общей защиты.
  • NT Вложенная задача.
    Этот флаг был установлен, если одна задача CALL изменила другую задачу, которая вызвала контекстный переключатель. Флаг установки сказал процессору, чтобы сделать контекстный переключатель обратно, когда RET был выполнен.

80386 Флаги

«386 нужны дополнительные флаги для поддержки дополнительных функций, разработанных в процессоре.

  • RF Флаг возобновления.
    В «386» добавлены регистры Debug, которые могут вызывать отладчик при различных аппаратных доступах, таких как чтение, запись или выполнение определенного местоположения memry. Однако, когда обработчик отладки вернулся для выполнения команды, доступ немедленно повторно вызовет обработчик отладки! Или, по крайней мере, это было бы, если бы не флаг Возобновления, который автоматически устанавливается при входе в обработчик отладки и автоматически очищается после каждой инструкции. Если флажок Resume установлен, обработчик Debug не вызывается.
  • VM Виртуальный 8086 Флаг.
    Для поддержки старого 16-битного кода, а также более нового 32-разрядного кода 80386 может запускать 16-разрядные задачи в режиме «Виртуальный 8086» с помощью администратора Virtual 8086. Флаг VM указывал, что эта задача представляет собой задачу Virtual 8086.

80486 Флаги

По мере совершенствования архитектуры Intel она стала быстрее благодаря такой технологии, как кэширование и суперскалярное выполнение. Это должно было оптимизировать доступ к системе, сделав предположения. Чтобы контролировать эти предположения, требуется больше флагов:

  • Флаг проверки соответствия AC Архитектура x86 всегда может обращаться к значениям многобайтовой памяти на любой границе байта, в отличие от некоторых архитектур, которые требовали, чтобы они были выровнены по размеру (4-байтовые значения должны были быть на 4-байтных границах). Тем не менее, это было менее эффективно, так как для доступа к неуравновешенным данным необходимы множественные обращения к памяти. Если был установлен флаг AC , то неприглаженный доступ приведет к возникновению исключения, а не к выполнению кода. Таким образом, код может быть улучшен во время разработки с помощью набора AC , но отключен для производственного кода.

Флаги Pentium

Pentium добавил больше поддержки для виртуализации, а также поддержку инструкции CPUID :

  • VIF Виртуальный флаг прерывания.
    Это виртуальная копия IF этой задачи - должна ли эта задача отключать прерывания, фактически не влияя на глобальные прерывания.
  • VIP Ожидающий флаг виртуального прерывания.
    Это указывает на то, что прерывание было фактически заблокировано VIF , поэтому, когда Task выполняет STI для него может быть поднято виртуальное прерывание.
  • ID . Идентификационный флаг CPUID .
    Разрешить или не разрешать этой Задаче выполнять инструкцию CPUID . Виртуальный монитор может запретить его и «лгать» запрашивающей Задаче, если он выполняет инструкцию.


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow