Лекция по программированию

Автор работы: Пользователь скрыл имя, 11 Января 2011 в 19:34, лекция

Краткое описание

Язык ассемблера - это один из самых старых из всех существующих языков программирования. Когда-то это был один из основных языков программирования, без знания которого нельзя было заставить компьютер сделать что-либо полезное. Появились более удобные средства общения с компьютером. Но в отличии от других языков ассемблер не умирал, более того он это не смог сделать в принципе.

Содержимое работы - 1 файл

LECTS.DOC

— 893.00 Кб (Скачать файл)

    Старший байт регистра состояния содержит:

  • Бит занятости B (бит 15), сигнализирующий, свободен ли сопроцессор (B=0) или занят выполнением численной команды (B = 1). Команды сопроцессора, которые используют регистровый стек, требуют, чтобы перед началом их выполнения сопроцессор не был занят. В FPU этот бит дублирует значение флага сигнализации особого случая.
  • Поле TOS "Top-Of-the-Stack" (биты 11-13), которое содержит номер регистра, являющегося логической вершиной стека. При помещении в регистровый стек нового числа это значение уменьшается. Если это поле достигает значения 0, возможны две ситуации: произойдет заворачивание стека на регистры с большими номерами (т.е. R7) или, если заворачивание приведет к затиранию несохраненного значения, возникнет особый случай сопроцессора "переполнение стека".
  • 4 бита кода условия (биты 14, 10, 9, 8), аналогичные флажкам состояния FLAGS у IA-32, отражающие результат арифметических операций. Эти флажки могут быть использованы для условных переходов.

    Младший байт регистра состояния содержит флажки особых случаев сопроцессора: переполнение стека, потеря точности, потеря значащих разрядов, численное переполнение, деление на ноль, денормализация, недействительная операция. Если соответствующий особый случай возник и не был замаскирован (в слове управления), это приведет к генерации центральным процессором особого случая сопроцессора (#16).

    Младшее слово регистра управления содержит биты масок особых случаев. Сопроцессор  допускает индивидуальное маскирование особых случаев. Если тот или иной особый случай замаскирован, при возникновении  соответствующей ситуации сопроцессор выполняет некоторые заранее определенные внутренние действия, которые зачастую приемлемы для большинства применений. Например, если замаскирован особый случай деления на ноль, то выполнение операции 85,32/0 даст результат + ∞.

    Старшее слово регистра управления содержит два поля: управление точностью PC (биты 8 и 9) и управление округлением RC (биты 10 и 11). Биты управления точностью можно  использовать для понижения точности вычислений. По умолчанию используется расширенная точность (PC = 112), можно также использовать двойную точность (PC = 102) и одинарную точность (PC = 002) по стандарту IEEE-754.

    Если  результат численной операции не может быть точно представлен  в выбранном формате, сопроцессор  выполняет округление в соответствии с полем RC (табл. 8.3). По умолчанию RC = 00. В примерах в табл. 7.3 сделана попытка представить числа +2,23 и +2,05 в виде двоичных вещественных чисел с 3-битной дробной частью мантиссы. В этом формате нельзя подобрать точное двоичное значение для этих чисел. Ближайшие к ним представимые числа - +2,00 (+1,000E21) и +2,25 (+1,001E21).

Таблица 8.3. Режимы округления сопроцессоров Intel x87
RC Режим Пример 1

1,000E21 < 2,23E100 < 1,001E21

-1,001E21 < -2,23E100 < -1,000E21

Пример 2

1,000E21 < 2,05E100 < 1,001E21

-1,001E21 < -2,05E100 < -1,000E21

00 Округление  к ближайшему (или четному) 2,23E100 ≈ 1,001E21

-2,23E100 ≈ -1,001E21

2,05E100 ≈ 1,000E21

-2,05E100 ≈ -1,000E21

01 Округление  вниз (к ∞) 2,23E100 ≈ 1,000E21

-2,23E100 ≈ -1,001E21

2,05E100 ≈ 1,000E21

-2,05E100 ≈ -1,001E21

10 Округление  вверх (к +∞) 2,23E100 ≈ 1,001E21

-2,23E100 ≈ -1,000E21

2,05E100 ≈ 1,001E21

-2,05E100 ≈ -1,000E21

11 Округление  к нулю (усечение) 2,23E100 ≈ 1,000E21

-2,23E100 ≈ -1,000E21

2,05E100 ≈ 1,000E21

-2,05E100 ≈ -1,000E21

    Регистр тегов содержит 8 тегов - признаков, характеризующих содержимое соответствующего численного регистра сопроцессора. Тег  может принимать следующие значения:

    00 - в регистре находится действительное число;

    01 - нулевое число в регистре;

    10 - недействительное число (бесконечность,  денормализованное число, нечисло);

    11 - пустой регистр.

    Сопроцессор использует теги, чтобы определить переполнение или опустошение стека. Если при помещении в стек очередного числа окажется, что декрементированный TOS указывает на непустой регистр (соответствующий тег не равен 112), сопроцессор сигнализирует о переполнении стека. Если при извлечении из стека числа окажется, что инкрементированный TOS указывает на пустой регистр (соответствующий тег равен 112), сопроцессор сигнализирует об опустошении стека.

    Указатель команд и указатель данных содержат логические адреса (селектор сегмента и смещение) последней команды  и ее операнда. (это 32-битные регистры у 8087 и 80287 и 48-битные - у 80387 и FPU). Эта информация используется обработчиком особых случаев сопроцессора.

    Для команд сопроцессора выделена группа кодов, начинающаяся с 11011ххх. В ассемблерах  мнемоники команд сопроцессора начинаются с "F": FADD (сложение), FCOM (сравнение), FCOS (косинус), FDIV (деление) и т.п.

    Параллельная  работа ЦП и сопроцессора ставит перед  программистом проблемы синхронизации. Например:

mem   DW    0

      :

     FILD  mem

     INC   mem

     FSQRT

    В данном примере, команда FILD преобразует 16-битное целое число в памяти в формат сопроцессора и сохраняет его в ST, затем целочисленная команда INC увеличивает это значение на 1, после чего сопроцессор вычисляет квадратный корень ST (FSQRT).

    Для внешних сопроцессоров (8087, 80287, 80387) ЦП начнет выполнять команду INC раньше, чем сопроцессор закончит FILD, а, следовательно, в стек сопроцессора может попасть неверное значение. Встроенный блок FPU у IA-32 лишен этого недостатка, т. к. ЦП отслеживает обращения к памяти и не начнет выполнять целочисленную команду, если она обращается к ячейке памяти, с которой в данный момент работает блок FPU. Однако остается нерешенной другая проблема. Если при выполнении инструкции FPU возникает ситуация, соответствующая одному из незамаскированных особых случаев, FPU прекращает выполнение инструкции и сигнализирует об особом случае. Однако соответствующее исключение процессора будет вызвано только при очередном обращении процессора к блоку FPU, а до этого момента целочисленный блок может изменить ячейку памяти, значение которой привело к исключению, так что обработчик исключения не сможет правильно интерпретировать причину особого случая.

    Описанная ситуация говорит о необходимости  использовать в таких случаях  средства синхронизации. Например, команда FWAIT приостанавливает работу целочисленного устройства до тех пор, пока не будет завершена работа выполняемой сопроцессором инструкции или не будет вызвано исключение, если при выполнении последней инструкции FPU возник особый случай. Для этих же целей можно использовать любую другую инструкцию сопроцессора, кроме специальных "неожидающих" инструкций: FNINIT - сброс сопроцессора без ожидания, FNSTCW/FNSTSW - сохранение регистра управления/состояния без ожидания, FNCLEX - сбросить флаги особых случаев без ожидания, FNSAVE/FNSTENV - сохранение состояния (контекста) сопроцессора без ожидания.

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

FILD mem

FSQRT

    INC mem

Команды пересылки данных

    Команды ззагрузки в стек (Fpu LoaD):

  • FLD - загружает из памяти в вершину стека ST(0) вещественное число
  • FILD - загружает из памяти в вершину стека ST(0) целое число
  • FBLD - загружает из памяти в вершину стека ST(0) двоично-десятичное число

    При выполнении этих команд операнд считывается из оперативной памяти, преобразуется в формат с расширенной точностью. Затем поле ST регистра состояния уменьшается на единицу и выполняется запись операнда в численный регистр, определяемый новым значением поля ST. То есть операнд записывается в стек численных регистров, а указатель стека (поле ST) уменьшается на единицу. По своему действию эти команды напоминают команду PUSH центрального процессора.

    Непосредственно перед загрузкой численного регистра проверяется содержимое поля TAG0. Если это содержимое не равно 11 (пустой регистр), в регистре состояния устанавливается флаг IE (недействительная операция) и вырабатывается прерывание (если в регистре управления не установлена маска IM - маска недействительной операции).

    Команды сохранения и извлечения из стека (Fpu STore and Pop):

  • FSTP память -> ST(0), вещественный формат
  • FISTP память -> ST(0), целый формат
  • FBSTP память -> ST(0), десятичный формат

    Эти команды сначала сохраняют вершину  стека в памяти, а потом выталкивают (удаляют) данные из вершины стека. Содержимое численного регистра, номер которого определяется полем ST регистра состояния, преобразуется в необходимый формат и записывается в ячейки оперативной памяти, заданные операндом команды.

После записи содержимое поля ST увеличивается на единицу. Эти действия аналогичны выполняемым командой POP центрального процессора.

    В зависимости от команды (FSTP, FISTP или FBSTP) производится преобразование формата (из расширенного в вещественный, целый  или десятичный, соответственно). В процессе преобразования для команд FSTP и FISTP выполняется округление в соответствии с содержимым поля RC регистра управления. Для команды FBSTP округление всегда выполняется следующим образом - прибавляется число 0.5, затем дробная часть результата отбрасывается.

    Команды копирования данных (Fpu STore):

  • FST память -> ST(0), вещественный формат
  • FIST память -> ST(0), целый формат
  • FBST память -> ST(0), десятичный формат,

    Эти команды пересылают данные из верхушки стека в область памяти, указанную  операндом команды. При этом содержимое указателя стека (поля ST) не изменяется.

    Команда FST в качестве операнда может использовать ссылку на численный регистр ST(i), поэтому  эту команду можно использовать для копирования верхушки стека  в любой другой численный регистр.

    При записи данных в оперативную память выполняется преобразование формата (в вещественный для FST, в целый  для FIST и в десятичный для FBST.

    Команда обмена (Fpu eXCHange):

  • FXCH - обмен содержимым верхушки стека ST(0) и численного регистра, указанного в качестве операнда команды

    Команды загрузки констант:

  • FLDZ 0 -> ST(0) - Загрузить нуль
  • FLD1 1 -> ST(0) - Загрузить единицу
  • FLDPI ( -> ST(0) - Загрузить число ( ("пи")
  • FLDL2T loge10 -> ST(0) - Загрузить loge10
  • FLDL2E log2e -> ST(0) - Загрузить log2e
  • FLDLG2 log102 -> ST(0) - Загрузить log102
  • FLDLN2 loge2 -> ST(0) - Загрузить loge2

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

Арифметические  команды

    Сопроцессор использует шесть основных типов арифметических команд:

  • Fxxx

    Первый операнд  берется из верхушки стека (источник), второй - следующий элемент стека. Результат выполнения команды записывается в стек

  • Fxxx память

    Источник берется  из памяти, приемником является верхушка стека ST(0). Указатель стека ST не изменяется, команда действительна только для операндов с одинарной и двойной точностью

  • Fixxx память

    Аналогично  предыдущему типу команды, но операндами могут быть 16- или 32-разрядные целые  числа 

  • Fxxx ST, ST(i)

Информация о работе Лекция по программированию