Аппаратное обеспечение персонального компьютера© Александр Фролов, Григорий ФроловТом 33, М.: Диалог-МИФИ, 1997, 304 стр. Система команд сопроцессораВозможны три формата команд сопроцессора, аналогичные форматам команд центральных процессоров фирмы Intel. Это команды с обращением к оперативной памяти, команды с обращением к одному из численных регистров и команды без операндов, заданных явным образом. Команды с обращением к памяти могут занимать от двух до четырех байт, в зависимости от способа адресации операнда, находящегося в памяти (рис. 10.15). Рис. 10.15. Формат команд с обращением к памяти Первые пять бит соответствуют команде центрального процессора ESC. Поля КОП1 и КОП2 определяют выполняемую команду, то есть содержат код операции. Поля MOD и R/M вместе с полями "Смещение1" и "Смещение2" задают адрес операнда в памяти аналогично тому, как это происходит в процессорах. Однако есть и отличия, связанные с возможностью адресации численных регистров сопроцессора. Ниже мы покажем зависимость способа адресации от содержимого полей MOD и R/M:
Если в таблице указаны значения смещения disp8 или disp16, это означает, что в команде присуствует один или два байта смещения, соответственно. Если поле MOD содержит значение 11, возможна адресация численных регистров ST0...ST1. При этом команда не содержит байтов смещения. Формат команды с обращением к численному регистру приведен на рис. 10.16. Рис. 10.16. Формат команд с обращением к численному регистру Видно, что это есть частный случай предыдущей команды, в которой поле MOD содержит значение 11 и отсутствуют байты смещения. Самый простой формат имеют команды без явного обращения к операндам (рис. 10.17). Рис. 10.17. Формат команд без явного обращения к операндам Разумеется, если вы составляете программу для сопроцессора на языке ассемблера, вы можете использовать мнемоническое обозначение команд. Все мнемоники команд сопроцесора начинаются с буквы F, поэтому их легко отличить от команд процессоров. Все команды сопроцессора можно разделить на несколько групп: · команды пересылки данных; · арифметические команды; · команды сравнений чисел; · трансцендентные команды; · управляющие команды Команды пересылки данных предназначены для загрузки чисел из оперативной памяти в численные регитры, записи данных из численных регистров в оперативную память, копирования данных из одного численного регистра в другой. Арифметические команды выполняют такие операции, как сложение, вычитание, умножение, деление, извлечение квадратного корня, нахождение частичного остатка, округление и так далее. Команды сравнения сравнивают вещественные и целые числа, выполняют анализ чисел. Трансцендентные команды предназначены для вычисления различных тригонометрических, логорифмических, показательных и гиперболических функций - sin, cos, tg и тому подобных. Последняя группа команд - управляющие команды. Они обеспечивают установку режима работы арифметического сопроцессора, его сброс и инициализацию, перевод сопроцессора в защищенный режим работы и так далее. Следующие разделы будут посвящены детальному описанию различных групп команд сопроцессора. Команды пересылки данныхПриведем описание команд, предназначенных для пересылки данных. Запись в стекFLD ST(0) <- память, вещественный формат FILD ST(0) <- память, целый формат FBLD ST(0) <- память, десятичный формат Команды FLD, FILD, FBLD загружают в вершину стека вещественное, целое и десятичное числа, соответственно. При выполнении этих команд операнд считывается из оперативной памяти, преобразуется в формат с расширенной точностью. Затем поле ST регистра состояния уменьшается на единицу и выполняется запись операнда в численный регистр, определяемый новым значением поля ST. То есть операнд записывается в стек численных регистров, а указатель стека (поле ST) уменьшается на единицу. По своему действию эти команды напоминают команду PUSH центрального процессора. Непосредственно перед загрузкой численного регистра проверяется содержимое поля TAG0. Если это содержимое не равно 11 (пустой регистр), в регистре состояния устанавливается флаг IE (недействительная операция) и вырабатывается прерывание (если в регистре управления не установлена маска IM - маска недействительной операции). Извлечение из стекаFSTP память -> ST(0), вещественный формат FISTP память -> ST(0), целый формат FBSTP память -> ST(0), десятичный формат Команды извлечения чисел из стека выполняют действие, обратное только что описанному. Содержимое численного регистра, номер которого определяется полем ST регистра состояния, преобразуется в необходимый формат и записывается в ячейки оперативной памяти, заданные операндом команды. После записи содержимое поля ST увеличивается на единицу. Эти действия аналогичны выполняемым командой POP центрального процессора. В зависимости от команды (FSTP, FISTP или FBSTP) производится преобразование формата (из расширенного в вещественный, целый или десятичный, соответственно). В процессе преобразования для команд FSTP и FISTP выполняется округление в соответствии с содержимым поля RC регистра управления. Для команды FBSTP округление всегда выполняется следующим образом - прибавляется число 0.5, затем дробная часть результата отбрасывается. Копирование данныхFST память -> ST(0), вещественный формат FIST память -> ST(0), целый формат FBST память -> ST(0), десятичный формат, (только 80387, 80486, Pentium) Эти команды пересылают данные из верхушки стека в область памяти, указанную операндом команды. При этом содержимое указателя стека (поля ST) не изменяется. Команда FST в качестве операнда может использовать ссылку на численный регистр ST(i), поэтому вы можете использовать эту команду для копирования верхушки стека в любой другой численный регистр. При записи данных в оперативную память выполняется преобразование формата (в вещественный для FST, в целый для FIST и в десятичный для FBST. Для сопроцессора 80286 вместо отсутствующей команды FBST можно выполнить следующие две команды, которые приведут к такому же результату: FLD ST(0) FBSTP dec_number ОбменFXCH ST(i) -> ST(0), ST(0) -> ST(i) Команда выполняет обмен содержимым верхушки стека ST(0) и численного регистра, указанного в качестве операнда команды. Загрузка константFLDZ 0 -> ST(0) - Загрузить нуль FLD1 1 -> ST(0) - Загрузить единицу FLDPI p -> ST(0) - Загрузить число p ("пи") FLDL2T loge10 -> ST(0) - Загрузить loge10 FLDL2E log2e -> ST(0) - Загрузить log2e FLDLG2 log102 -> ST(0) - Загрузить log102 FLDLN2 loge2 -> ST(0) - Загрузить loge2 Загрузка констант выполняется намного быстрее специальными командами, нежели командами загрузки данных из оперативной памяти. Арифметические командыСопроцессор использует шесть основных типов арифметических команд:
Строка "xxx" может принимать следующие значения:
Кроме основных арифметических команд имеются дополнительные арифметические команды:
По команде FSQRT вычисленное значение квадратного корня записывается в верхушку стека ST(0). Команда FSCALE изменяет порядок числа, находящегося в ST(0). По этой команде значение порядка числа ST(0) складывается с масштабным коэффициентом, который должен быть предварительно записан в ST(1). Действие этой команды можно представить следующей формулой: ST(0) = ST(0) * 2n, где -215 <= n <= +215 В этой формуле n - это ST(1). Команда FPREM вычисляет остаток от деления делимого ST(0) на делитель ST(1). Знак результата равен знаку ST(0), а сам результат получается в вершине стека ST(0). Действие команды заключается в сдвигах и вычитания, аналогично ручному делению "в столбик". После выполнения команды флаг C2 регистра состояния может принимать следующие значения:
Команда RNDINT округляет ST(0) в соответствии с содержимым поля RC управляющего регистра. Команда FABS вычисляет абсолютное значение ST(0). Аналогично, команда FCHS изменяет знак ST(0) на противоположный. Команды сравнений чиселВ центральном процессоре команды условных переходов выполняются в соответствии с установкой отдельных битов регистра флагов процессора. В арифметическом сопроцессоре существуют специальные команды сравнений, по результатам выполнения которых устанавливаются биты кодов условий в регистре состояния:
Команда FCOM вычитает содержимое операнда, размещенного в оперативной памяти, из верхушки стека ST(0). Результат вычитания никуда не записывается и указатель верхушки стека ST не изменяется. Обозначим операнд команды сравнения как "x". В следующей таблице приведем значения битов кодов условия после выполнения команды "FCOM x":
Последняя комбинация возникает при попытке сравнения нечисел, неопределенностей или бесконечностей, а также в некоторых других случаях. Команда FICOM работает с 16- или 32-разрядными числами, в остальном она аналогична команде FCOM. Команды FCOMP и FICOMP аналогичны, соответственно, командам FCOM и FICOM, за исключением того, что после выполнения операнд извлекается из стека. Команда FCOMPP выполняет те же действия, что и FCOM, но она после выполнения извлекает из стека оба операнда, участвовавших в сравнении. Для сравнения операнда с нулем предназначена команда FTST. После ее выполнения коды условий устанавливаются в соответствии со следующей таблицей:
Команда FXAM анализирует содержимое ST(0). После ее выполнения устанавливаются коды условий, по которым можно судить о знаке числа, о его конечности или бесконечности, нормализованности и так далее. Бит C1 содержит знак анализируемого числа:
С помощью бита C0 можно определить, является число конечным или бесконечным:
Для конечных чисел дальнейшая классификация может проводиться по содержимому кодов условий C2 и C3:
Аналогично, для бесконечных чисел коды условий C2 и C3 имеют следующие значения:
С помощью команды "FSTSW AX" программа может переписать содержимое регистра состояния сопроцессора в регистр AX центрального процессора. Далее содержимое регистра AH можно переписать в регистр флагов центрального процессора при помощи команды SAHF. Биты кодов условий сопроцессора отображаются на регистр флагов центрального процессора таким образом, что для анализа кодов условий можно использовать команды условных переходов. Например, в следующем фрагменте программы выполняется переход к метке error, если операнды несравнимы: .286 . . . fcom fstsw ax sahf je error Трансцендентные командыТрансцендентные команды предназначены для вычисления таких функций, как тригонометрические (sin, cos, tg,...), обратные тригонометрические (arcsin, arccos,...), показательные (xy, 2x, 10x, ex), гиперболические (sh, ch, th,...), обратные гиперболические (arsh, arch, arcth,...). В следующей таблице приведены все трансцендентные команды сопроцессора:
Команда FPTAN вычисляет частичный тангенс ST(0), размещая в стеке такие два числа x и y, что y/x = tg(ST(0)). После выполнения команды число y располагается в ST(0), а число x включается в стек сверху (то есть записывается в ST(1)). Аргумент команды FPTAN должен находится в пределах: 0 <= ST(0) <= pi/4 Пользуясь полученным значением частичного тангенса, можно вычислить другие тригонометрические функции по следующим формулам: sin(z) = 2*(y/x) / (1 + (y/x)2) cos(z) = (1 - (y/x)2) / (1 + (y/x)2) tg(z/2) = y/x; ctg(z/2) = x/y; cosec(z) = (1 + (y/x)2) / 2*(y/x) sec(z) = (1 + (y/x)2) / (1 - (y/x)2) В этой таблице z - значение, находившееся в ST(0) до выполнения команды FPTAN, x и y - значения в регистрах ST(0) и ST(1), соответственно. Команда FPATAN вычисляет частичный арктангенс: z=arctg(ST(0)/ST(1))=arctg(x/y). Перед выполнением команды числа x и y располагаются в ST(0) и ST(1), сответственно. Аргументы команды FPATAN должен находится в пределах: 0 < y < x Результат записывается в ST(0). Команда FYL2X вычисляет выражение y*log2(x), операнды x и y размещаются, соответственно, в ST(0) и ST(1). Операнды извлекаются из стека, а результат записывается в стек. параметр x должен быть положительным числом. Пользуясь результатом выполнения этой команды, можно вычислить следующим образом логарифмические функции: log2(x) = FYL2(x) loge(x) = loge(2) * log2(x) = FYL2X(loge(2), x) = = FYL2X(FLDLN2, x) log2(x) = log10(2) * log2(x) = FYL2X (log10(2), x) = = FYL2X(FLDLG2, x) Функция FYL2XP1 вычисляет выражение y*log2(x+1), где x соответствует ST(0), а y - ST(1). Результат записывается в ST(0), оба операнда выталкиваются из стека и теряются. На операнд x накладывается ограничение: 0 < x < 1 - 1/sqrt(2) Команда F2XM1 вычисляет выражение 2x-1, где x - ST(0). Результат записывается в ST(0), параметр должен находится в следующих пределах: 0 <= x <= 0,5 Команда FCOS вычисляет cos(x). Параметр x должен находится в ST(0), туда же записывается результат выполнения команды. Команда FSIN аналогична команде FCOS, но вычисляет значение косинуса ST(0). Команда FSINCOS вычисляет одновременно значения синуса и косинуса параметра ST(0). Значение синуса записывается в ST(1), косинуса - в ST(0). На этом мы закончим описание трансцендентных команд сопроцессора и перейдем к управляющим командам. Управляющие командыУправляющие команды предназначены для работы с нечисловыми регистрами сопроцессора. Некоторые команды имеют альтернативные варианты. Мнемоники этих команд могут начинаться с FN или с F. Первый вариант соответствует командам "без ожидания". Для таких команд процессор не проверяет, занят ли сопроцессор выполнением команды, то есть бит занятости B не проверяется. Численные особые случаи также игнорируются. Варианты команд "с ожиданием" действуют также, как и обычные команды сопроцессора. Приведем список управляющих команд сопроцессора: FNSTCW (FSTCW) Записать управляющее слово FLDCW Загрузить управляющее слово FNSTSW (FSTSW) Записать слово состояния FNSTSW AX (FSTSW AX) Записать слово состояния в AX, нет в сопроцессоре 8087 FNCLEX (FCLEX) Сбросить особые случаи FNINIT (FINIT) Инициализировать сопроцессор FNSTENV (FSTENV) Записать среду FLDENV Загрузить среду FNSAVE (FSAVE) Записать полное состояние FRSTOR Восстановить полное состояние FINCSTP Увеличить указатель стека на 1 FDECSTP Уменьшить указатель стека на 1 FFREE Освободить регистр FNOP Холостая команда, нет операции FSETPM Установить защищенный режим работы Команда FNSTCW записывает содержимое управляющего регистра в оперативную память. Команда FLDCW загружает управляющий регистр данными из оперативной памяти и обычно используется для изменения режима работы сопроцессора. Команда FNSTSW записывает содержимое регистра состояния в оперативную память. Команда FNSTSW AX записывает содержимое этого регистра в регистр AX центрального процессора для его последующего анализа командами условных переходов. Сопроцессор 8087 не имеет варианта команды FSTSW AX, поэтому приходится вначале записывать регистр состояния в память, а затем в регистр флагов процессора 8086. Команда FNCLEX сбрасывает флаги особых случаев в регистре состояния сопроцессора. Кроме того, сбрасываются биты ES и B. Команда FNINIT инициализирует регистр состояния, управляющий регистр и регистр тегов в соответствии со следующей таблицей:
Команда FNSTENV записывает в память содержимое всех регистров, кроме численных, в формате, показанном на рис. 10.18. Рис. 10.18. Формат записи в память содержимого всех регистров командой FNSTENV Команда FLDENV предназначена для загрузки регистров, сохраненных ранее командой FNSTENV. Обе эти команды полезны в программах обработки особых случаев. Команды FNSAVE и FRSTOR действуют аналогично командам FNSTENV и FLDENV, но они дополнительно сохраняют и восстанавливают содержимое численных регистров. Формат области сохранения регистров, занимающей 94 байта, приведен на рис. 10.19. Рис. 10.19. Формат записи в память содержимого всех регистров командами FNSAVE и FRSTOR Команды FINCSTP и FDECSTP увеличивают и уменьшают на 1 указатель стека SP, соответственно. Команда FFREE ST(i) помечает численный регистр ST(i) как пустой, записывая в соответствующее поле регистра тегов значение 11. Команда FNOP не производит никаких действий. Команда FSETPM переводит сопроцессор в защищенный режим работы. |