литература / Пухальский Проектирование микропроцессорных систем 2001
.pdf500 |
Глава 4. Макропроцессоры 8086/8088 и сопроцессор 8087 |
|
FDIVR |
S T (l), ST |
ST = +1.0, S T (l) <— 1 /л/2 = Z |
FSUB |
ST, ST(1) |
S T *~ l~ z , ST(1) = 2 |
FSQRT |
|
s T < - V T : 7 = K t s T (i) = z |
|
|
|
FLD1 |
|
Top <— Top - 1, ST(0) <- +1.0, Tag(0) < - 00, ST(1) = Y, ST(2) = z |
FADD |
ST, ST(2) |
ST « - 1 + г, ST(1) = Y, ST(2) = г |
FSQRT |
|
ST <- VT+7= x, S T (1) = Y, ST(2) = г |
FPATAN |
; ST(1) |
- arctg (Y/X), Tag <— 11, Top <- Top + 1, ST(0) = arctg (Y/X), ST(1) = z |
FADD |
ST, ST |
ST <- 2 • arctg (Y/X) = arccos z ~ 0.78539816339744831 = 71/4, ST(1) = г |
Задача 5. Вычислить значения функции sin х для углов 0 -г- 90° и вывести на экран монито ра один ее период с учетом свойств симметрии функций sin х и cos х в диапазоне углов 0 + 360°
[22]. Решение: |
|
|
|
s_seg |
segment |
STACK |
; Сегмент стека |
|
db |
16 dup ( ‘Stack SP’) ; Размер стека равен 128 байт |
|
s_seg |
ends |
|
|
d_seg |
segment |
|
Сегмент данных |
angle |
dw |
0 |
Начальное значение угла |
temp |
dw |
? |
Вспомогательная ячейка |
cnst |
dd |
180.0 |
Константа преобразования |
scale |
dw |
100 |
Коэффициент масштабирования |
pos |
dw |
0 |
|
shft |
db |
0 |
|
buf |
dw |
91 dup (?) |
Массив результатов |
coir |
db |
1 |
Задание цвета кривой |
d_seg |
ends |
|
Конец сегмента данных |
c_seg |
segment |
|
Сегмент кода |
|
assume |
CS : c_j>egt DS -: d_seg, SS : s_seg |
|
Start: mov |
ax, d_seg |
Инициализация сегментного регистра |
|
- |
mov |
ds, ax |
|
|
LEA |
BX, buf |
Загрузка адреса буфера buf |
|
M OV |
SI,0 |
Индекс для значений синуса |
L3: |
M OV |
AX, angle |
Выборка значения угла |
|
CMP |
AX, 45 |
45° — граничное условие |
|
JG |
L I |
Если угол > 45°, то переход |
|
JMP |
L2 |
Если нет, то продолжение |
LI: |
NEG |
AX |
АХ < - 0 - АХ |
|
ADD |
AX, 90 |
А Х <— А Х + 90 |
L2: |
M OV |
temp, A X |
M(temp) <— А Х |
|
FINIT |
|
Инициализация N D C P |
|
FLDPI |
|
Запись числа л: в регистр стека |
|
FLD |
cnst |
Запись числа cnst в регистр стека |
|
FDIV |
|
Деление числа cnst на к |
|
FILD |
temp |
Загрузка округленного целочисленног |
|
FM UL |
|
Умножение на предыдущее число |
|
FPTAN |
|
Вычисление тангенса произведения |
|
M OV |
AX, angle |
Проверка значения угла |
|
|
4.7. Система команд арифметического сопроцессора 8087 |
501 |
|
|
СМР |
AX, 45 |
Если < 45°, то синус |
|
|
JG |
COS |
Если > 45°, то косинус |
|
|
JMP |
SIN |
|
|
|
FXCH |
S T (I) |
ST(0) <-» ST(1), если функция косинуса |
|
|
FM UL |
ST, ST |
|
|
|
FXCII |
ST(1) |
S T(0 )^>S T (1 ) |
|
|
FLD |
ST |
Начало вычислений синуса или косинуса |
|
|
FM UL |
ST, ST |
|
|
|
FADD |
ST, ST(2) |
|
|
|
FSQRT |
|
|
|
|
FDIVP |
ST(1), ST |
|
|
|
FIMUL |
scale |
|
|
|
F1STP |
buf [SI] |
Запись результата из регистра стека в память |
|
|
ADD |
SI, 2 |
Переход к следующему значению синуса |
|
|
ADD |
angle, 1 |
Увеличение значения угла |
|
|
CM P |
angle, 90 Цикл для значений угла 0 -s- 90° |
|
|
|
JLE |
L3 |
|
|
|
зд точек рассчитанной кривой на экран графического монитора |
|
||
|
M OV |
АН, 0 |
Установка графического режима экрана |
|
|
M OV |
AL, 12/г |
A L =12/i — 640 х 480 точек, 16 цветов (КСМ) |
|
|
INT |
10/1 |
INT ЮЛ, функция BIOS 00/i (установка видеорежима) |
|
|
LEA |
ВХ, buf |
Загрузка адреса массива buf |
|
L8: |
M OV |
ST, 0 |
Начало массива |
|
|
M OV |
АХ, pos |
Пересылка значения угла в регистр A L |
|
|
CMP |
АХ, 180 |
Угол > 180°? |
|
|
JLE |
L4 |
Если нет, то первый или второй квадрант |
|
|
SUB |
АХ, 180 |
Коррекция значения угла, если оно больше или равно |
|
L4: |
CMP |
АХ, 90 |
Угол > 90°? |
|
|
JLE |
L5 |
Если да, то квадрант 2 |
|
|
NEG |
АХ |
Изменение знака |
|
|
ADD |
АХ, 180 |
Коррекция значения угла, если оно больше или равно |
|
L5: |
ADD |
SI. АХ |
Суммарное смешение в регистре АХ |
|
|
SHL |
SI, 1 |
Индекс для отсчета слов (х2) |
|
|
M OV |
AL, byte ptr Z>«/[SI] ; Выборка значения и запись в массив buf |
|
|
|
CMP |
pos, 180 |
Если угол > 180°, то сделать смещение на экране |
|
|
JGE |
L6 |
|
|
|
NEG |
A L |
Иначе изменить знак |
|
|
ADD |
AL, 100 |
Коррекция значения прибавлением 100 |
|
|
JMP |
L l |
Смещение точки на экране |
|
L6: |
ADD |
AL, 99 |
|
|
L7: |
M OV |
shft, A L |
Запись смещения в ячейку shft |
|
|
M OV |
AH, QCh |
Вывод изображения точки |
|
|
M OV |
AL, coir |
A L — номер цветового регистра от 0 до 15 |
|
|
M OV |
CX, pos |
СХ — графический столбец |
|
|
ADD |
CX, 140 |
|
|
|
M OV |
DH, 1 |
; DX — графическая строка |
|
|
M OV |
DL, shft |
|
|
502 |
Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087 |
|
|||
IN T |
10/i |
; INT ЮЛ, функция BIOS QCh (запись пиксела) |
|
||
ADD |
pos, 1 |
; Переход к следующему углу |
|
|
|
CMP |
pos, 360 |
; Выведены 360 точек? |
|
|
|
JLE |
L8 |
; Если нет, то повторить |
|
|
|
дание иажатия клавиши для возврата в DOS и |
|
|
|||
переключения монитора в текстовый режим |
|
|
|||
M OV |
AH, 7 |
; Чтение регистра клавиатуры с ожиданием ввода |
|
||
1NT |
21/z |
; INT 21Л, функция DOS 07Л |
|
|
|
M OV |
pos, 0 |
|
|
|
|
MOV |
shft, 0 |
|
|
|
|
INC |
coir |
; Изменение цвета кривой |
|
|
|
AND |
coir, OF/i |
|
|
|
|
JNZ |
color |
|
|
|
|
MOV |
AH, 0 |
; Установка видеорежима монитора |
|
|
|
MOV |
AL, 3 |
; A L = 03 — текстовый режим 80 х 25 знаков, 16 цветов |
|||
INT |
lO/i |
; INT ЮЛ, функция BIOS 00h (установка видеорежима) |
|||
mov |
ah, 4CA |
; Выход из программы и возврат управления в DOS |
|||
int |
21h |
; INT 21Л, функция DOS 4C/i |
|
|
|
ends |
|
|
|
|
|
end |
Start |
|
|
|
|
|
|
|
Программа выполняет вычисления в веществен |
||
|
|
|
ном формате, но для построения изображения на экра |
||
|
|
|
не монитора используются целые числа. Для этого ве |
||
|
|
|
щественные числа округляются до целых и пересыла |
||
|
|
|
ются в память. Изображение на экране монитора функ |
||
|
|
|
ции sin х для углов 0 -*■360° показано на рис. 4.44. |
||
|
|
|
Для вывода изображения на экран монитора ис |
||
|
|
|
пользованы функции BIOS'. |
|
|
|
|
|
INT 10й, функция BIOS 00h — |
установка графи |
|
|
|
|
ческого и текстового видеорежимов, |
|
|
Рис. 4.44. Экран монитора при |
INT ЮЛ, функция BIOS ОСИ — |
запись в видеобу- |
|||
выполнении программы задачи 5 |
фСр точки заданного цвета (регистр A L) в указанную |
||||
|
|
|
графическую позицию (регистры СХ и DX). |
||
Цвет каждого пиксела определяется числом, загруженным в регистр A L : |
|
||||
0 — черный, |
4 — красный, |
8 — серый, |
12 — розовый, |
||
1 — синий, |
5 — фиолетовый, |
9 — голубой, |
13 — светло-фиолетовый, |
||
2 — зеленый, |
6 — коричневый, |
10 — салатовый, |
14 — желтый, |
||
3 — бирюзовый, 7 — белый, |
11 — светло-бирюзовый, |
15 — ярко-белый. |
|||
Программа транслируется в ехе-фапл, который выполняется на любом персональном ком |
|||||
пьютере IBM PC. |
|
|
|
|
|
Команда F2XM1. Эта команда выполняет операцию |
|
|
|||
|
|
ST |
2 ST - 1, 0 < ST < 2 ' 1, |
|
|
где ST — содержимое регистра, находящегося в вершине стека. Вычисление 2 ST - 1 вместо 2 sr
позволяет получать точные нормализованные результаты даже при значениях ST близких
504 |
|
Гшва 4. Микропроцессоры 8086/8088 и сопроцессор 8087 |
|
||
|
M OV |
AX, 2 |
; A X <r- 2 |
|
|
|
SAL |
AX, CL |
; AX <— A X x 2 C1' = 2 £t/ + 1 |
|
|
|
FM UL |
ST, ST(1) |
; ST <- (2fu/4)2, ST(1) = 2™ 4 |
|
|
|
FST |
ST(1) |
; ST = (10FU!A) 2, S T (I) <r- (10 FUtA) 2 |
|
|
|
DEC |
AX |
; A X <— A X - 1 |
|
|
Exp: |
FM UL |
ST, ST(1) |
; ST <- ST x (2 Fm) \ ST(1) = (2 FUIA) 2 |
|
|
|
DEC |
AX |
; A X f - AX - 1 |
|
|
|
JNZ |
Exp |
|
|
|
|
JMP |
short Sign |
; ST <— 10 +x, ST(1) = (2 F m ) 2 |
|
|
; Вычисление значения 10 при U < 0.5 |
|
|
|||
Below: F2XM1 |
|
; ST <- 2 L’ - 1 = 10+x- 1 |
|
||
|
FLD1 |
|
; T o p * - T o p - i, S T (0 )< - 1, Tag(0) <— 00, S T (1 )= |
10+* - |
|
|
FADDP |
|
; ST(1) « - 10 +*, T a g ir-M , Top <- Top + 1 ,S T (0 )= |
!0 +* |
|
Sign: |
M OV |
AX, buf_F |
; A X <- M (buf_F) |
|
|
|
AND |
АН, 80Л |
; Анализ знака числа ± U |
|
|
|
JZ |
FIN |
|
|
|
|
FLD I |
; Top < - Top - 1, ST(0) < - |
1, ST(0) < - 1, Tag(0) < - 00, ST(1) = 10 |
||
|
FDIV |
ST, ST(1) |
; S T < - l/ 1 0 +* = |
10“*, S T (1 )= 10+\ ST(2) = (2 ™ |
) 2 |
FIN: |
|
|
|
|
|
Если команду FLDL2T заменить командой FLDL2E, то вышеприведенная программа бу дет вычислять значение показательной функции е ±х. Если же команду FLDL2T заменить ко мандой FLD1, то будет вычисляться значение показательной функции 2 ±х. Примеры вычисле ний:
10+a-U 1,9952623149688829е+23, |
К Г 213 = 5,0118723362727147е-24; |
13154108760,016079, |
е~1У1= 7,6021874096073512е-И; |
2 +23-3= 10327587,874940477, |
2 23 3 = 9,682803110554637е-08. |
Вышеприведенный алгоритм вычисления показательных функций весьма сложен и неэф фективен. Для вычисления показательных функций в любом диапазоне значений аргумента X
можно использовать и другие алгоритмы, в частности, алгоритм, основанный на применении
команды округления FRNDINT. В этом случае следует последовательно выполнить действия:
1) округлить число X до ближайшего целого Y (команда FRNDINT в режиме округления по умолчанию — RC = 00 в слове управления CW\ см. рис. 4.40) и вычислить разность
Z = X - Y, что обеспечивает выполнение условия |Z |< 1/2; следовательно, будет выполняться соотношение
2 х = 2 г ■2 z, где Н— целое, |Z|< 1/2;
2) вычислить значение 2 2 - I при Z > 0 или 2 ~z - 1 при Z < 0 (команда F2XM1); во втором
случае значение 2 z - 1 находится по формуле
2 г - 1 = - (2 " z - 1)/2
3) вычислить значение 2 z = 2 z - l + l , a затем значение функции 2 х - 2 Y ■2 z (команда
FSCALE).
Задача 7. Написать программу для решения задачи 6 (вычисление значения показательной функции 10 ±х как при 0 < \U\ < 0.5, так и при \U\ > 0.5, U ~ X х log210), с использованием выше описанного алгоритма. Решение:
506 |
Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087 |
Задача 8. Написать программу вычисления значений показательной функции Х ±у при лю бых значениях модуля )±У х Iog2X| (как при значениях 0 < |±К х log2 Х| < 0.5, так и при значени ях |± Y х log2X| > 0.5), Решение:
|
|
|
; В сегменте данных |
|
п_Х |
dq |
17.53 |
; Число X (только положительные числа) |
|
n_Y |
dq |
-13.47 |
; Число Y (числа любого знака) |
|
buf_F |
dw |
‘FF’ |
; 4646/г |
|
|
|
|
; В сегменте кода |
|
|
FINIT |
n_Y |
; Инициализация NDCP (все регистры стека освобождаются) |
|
|
FLD |
; Тор <- Тор - |
1, ST(0) <-• M (n_Y) = Y, Tag(0) <- 00 |
|
|
FLD |
n_X |
; Top <- Top - |
1, ST(0) ^ M{n_X) = X, Tag(0) <- 00, ST(1) = Y |
|
FYL2X |
|
; ST(1) <- Y x log2 X = U, Top <- Top + 1, ST(0) = U |
|
; Далее повторяется программа задачи 1 |
|
|||
|
FST |
|
ST(1) <- ST = U, T a g(l) <- 00, ST - U |
|
|
FRNDINT |
|
ST <— Y — округленное до целого число ST = U, S T (1 ): U |
|
|
FXCH |
|
ST о ST(1), ST = U, ST(1) = Y |
|
|
|
|
и т. д. (программа задачи 7) |
Примеры вычислений;
17.53+13 47 = 56720808123666196, 17.53 " 13 47 = 1.7630214256111064e-17,
Задача 9. Вычислить значение десятичного логарифма log10X = log2A71og210. Решение:
|
|
; В сегменте данных |
п_Х dq |
79583.243 |
; Число X (только положительные числа) |
|
|
; В сегменте кода |
FINIT |
|
; Инициализация ND CP (все регистры стека освобождаются) |
FLD 1 |
|
; 7ор <- Тор - 1, ST(0) <- 1, Tag(0) <- 00 |
FLD |
п_Х |
; Top ^ T o p - 1, ST(0) <- M (n_X) = X, Tag(0) 00, ST(1) = 1 |
FYL2X |
|
; ST( 1) <- log2 X, Top <- Top + 1, ST(0) = log2 X |
FLDL2T |
|
; Top <r- Top - 1, ST(0) f - log210, Tag(0) <- 00, ST(1) = \og2X |
FDIVP |
|
; ST(1) <- log2 X /log2 10 = logioX, Top <- Top + 1, |
|
|
ST(0) = log10X = 4.9008216325774979 |
Команда FYL2XP1. Эта команда выполняет операции над двумя числами X и Y:
ST(1) <- У ■log2 (X + 1) = ST(1) • log2 (ST + 1),
Tag <-11, TOP <- TOP + 1, ST(0) = Y ■log2 (X + 1),
где X - ST и Y= ST(1) — исходные операнды (удаляются), ST и ST(0) — исходная и следующая вершины стека. Для исходных операндов должны удовлетворяться условия
0 < |ST| < (2 - V 2) / 2, — < ST(1) < + о о .
Команда FYL2XP1 обеспечивает большую точность по сравнению с командой FYL2X при вычислении логарифмов чисел, близких к 1 — задать в нормализованном малом числе е можно больше значащих разрядов, чем в нормализованном числе 1 + в.
Для вычисления гиперболических функций используются формулы [23]:
508 |
Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087 |
Команды FENI/FNENI и FDISI/FNDISI. Эти команды выполняют операции над разрядом
М в слове управления CW:
(M )cvv <— 0 — разрешение запросов прерываний (команда FENI/FNENI),
(M)cw <— 1 — запрет запросов прерываний (команда FDISI/FNDISI),
т. е. управляют разрешением и запретом вызова процедур обработки особых случаев.
Команды FSTCW/FNSTCW dst и FLDCW src. Эти команды выполняют операции:
M(dst) <r~ CW; M(dst) — переменная типа WORD,
CW <— M (src) — переменная типа WORD.
Команда FSTCW dst осуществляет передачу в память текущего слова управления CW , де лая его доступным для М П 8086 — с помощью логических команд можно изменить слово управления CW , а затем командой FLDCW загрузить его в регистр CW с целью задания нового режима работы NDCP.
Если в слове состояния SW какой-либо незамаскированный флаг особого случая установ лен в 1, то загрузка нового слова управления CW при значении разряда М = 0 приводит к гене рированию запроса прерывания (сигнал 1NTI — см. рис. 4.31) перед выполнением следующей команды. Поэтому перед загрузкой нового слова управления CW рекомендуется сбрасывать флаги особых случаев в слове состояния.
Команда FSTSW/FNSTSW dst. Эта команда выполняет операцию
M(dst) <— SW\ M(dst) — переменная типа WORD.
Команда FSTSW dst осуществляет передачу в память текущего слова состояния SW, делая его доступным для М П 8086 с целью выполнения ветвления программы с помощью команд условных переходов (см. задачу 6 на с. 503 — команда FCOM и далее) или для обработки за маскированных особых случаев (без использования прерываний).
Команда FCLEX/FNCLEX. Эта команда выполняет операцию
(BAR/PEAJE/OE/23E/DE/IE)sw <— 0 — сброс особых случаев в слове состояния SW.
Если какие-либо особые случаи не замаскированы, то процедура обработки особых случа ев перед возвратом в прерванную программу должна выполнить команду FCLEX/FNCLEX — в
противном случае сразу же будет сформирован новый запрос прерывания.
Команды FSTENV/FNSTENV dst и FLDENV src. Эти команды выполняют операции:
M(dst) <г- Environment — 7 слов среды N D C P ,
Environment M (src) — 7 слов среды NDCP.
Команда FSTENV/FNSTENV делает доступной для М П 8086 наиболее важную информа цию о состоянии N D C P (см. рис. 4.42). Эта информация используется для обработки незамас кированных особых случаев в вызываемых по прерыванию процедурах обработки особых слу чаев. При выполнении команды FSTENV/FNSTENV маски всех особых случаев в слове управ ления CW устанавливаются в единицу, а разряд М остается неизменным. Среда N D C P обычно сохраняется в стеке М П 8086, как и полное состояние N D C P (см. пример 5).
Команда FLDENV src осуществляет загрузку среды N D C P из памяти. Если в слове управ ления CW разряд М = 0, то загрузка среды с незамаскированным особым случаем вызовет нег медленный запрос прерывания.
4.7. Система команд арифметического сопроцессора 8087 |
509 |
Команды FSAVE/FNSAVE dst и FRSTOR src . Эти команда выполняют операции:
M(dst) <— State — 47 слов полного состояния NDCP (команда FSAVE/FNSAVE dst),
State <— M(src) — 47 слов полного состояния NDCP (команда FRSTOR src),
т. е. производят сохранение в памяти и загрузку из памяти полного состояния NDCP (94 байта) в формате, приведенном на рис. 4.43. При выполнении команды FSAVE/FNSAVE автоматиче ски производится инициализация NDCP, аналогичная воздействию команды FINIT. Альтерна тивную мнемонику FNSAVE использовать нельзя, если разрешены прерывания в МП 8086.
Команды FSAVE/FNSAVE и FRSTOR обычно используется в тех случаях, когда NDCP необходимо переключить на выполнение другой задачи, например, процедуры обработки пре рывания с применением команд NDCP по запросу прерывания от внешнего устройства. В таких случаях для сохранения полного состояния NDCP удобно использовать стек МП 8086, адресуя его с помощью указателя базы ВР (см. табл. 4.9).
Сопроцессор по завершении выполнения команды FRSTOR немедленно реагирует на но вое состояние — выдает значение сигнала INT = 1, если какой-либо флаг особых случаев в за груженном слове состояния не замаскирован.
Пример 5 (оформление процедуры обработки внешнего прерывания INT type при имита ции прерывания командой CALL):
sjseg |
segment STACK |
Сегмент стека |
|||
|
dw |
64 dup (?) |
Резервирование 128 байт для стека |
||
s_seg ends |
|
|
|
|
|
d_seg segment |
|
|
; Сегмент данных |
||
n_X |
dq |
79583.243 |
Число X |
|
|
n_Y |
dq |
3943.1938 |
Число Y |
|
|
n_Z |
dq |
1936.4339 |
Число Z |
|
|
buf_P dq |
‘PP’ |
|
0000000000005050ft |
||
d_seg ends |
|
|
Конец сегмента данных |
||
c_seg segment |
|
|
Сегмент кода |
|
|
|
assume |
CS : c_seg, DS : d_seg, SS : s_seg, ES : d_seg |
|||
start: mov |
ax, d_seg ; Инициализация сегментного регистра DS |
||||
|
mov |
ds, ax |
|
|
|
|
mov |
es, ax |
|
ES = DS |
|
|
FINIT |
|
|
Инициализация ND CP (все регистры стека освобождаются) |
|
|
FLD1 |
|
|
ТОР <- ТОР - |
1, ST(0) < - 1, Tag(0) <е- 00 |
|
FLD |
n_X |
|
ТОР <- ТОР - |
1, ST(0) <- М (п_Х ) = X, Tag(0) <- 00, ST(1) = 1 |
|
FYL2X |
|
|
ST(1) <- log2X, TOP TOP + 1, ST(0) = log2X |
|
|
CALL |
IN TR |
; Имитация вызова процедуры обработки внешнего прерывания IN T type |
||
|
FLDL2T |
|
|
TOP <- TOP - |
1, ST(0) <- log210, Tag(0) <- 00, ST(1) = \og2X |
|
FDIVP |
|
|
ST(1) < - log2 X / Iog210 = logmX, TOP <- TOP + 1, |
|
|
|
|
|
ST(0) = logioX = 4.9008216325774979 |
|
|
|
|
|
Продолжение основной программы |
|
|
JMP |
FIN |
|
Конец основной программы |
|
INTR proc |
near |
|
Имитщ>уемая процедура обработки внешнего прерывания IN T type |
||
|
PUSH |
А Х |
|
Сохранение состояния основной программы. Предполагается, что |
|
|
PUSH |
ВХ |
; в основной программе и процедуре обработки внешнего прерывания |
||
|
PUSH |
СХ |
; эти регистры используются |