У сопроцессора 80x87 имеется внутренний стек вычислений, ко-
торый может быть глубиной до восьми уровней. Доступ к значению,
находящемуся в стеке сопроцессора 80x87 осуществляется намного
быстрее, чем доступ к переменной в памяти, поэтому для достижения
максимально возможной производительности в Borland Pascal внут-
ренний стек сопроцессора 80x87 используется для хранения времен-
ных результатов и для передачи параметров процедурам и функциям.
Теоретически, слишком сложные выражения вещественного типа
могут вызвать переполнение стека сопроцессора 80x87. Однако этого
не может случиться, поскольку для этого потребовалось бы, чтобы в
выражении получалось более восьми промежуточных результатов.
Более весомая опасность таится во вложенных вызовах функций.
Если такие конструкции составлены некорректно, то они, вполне ве-
роятно, могут привести к переполнению стека сопроцессора 80x87.
Рассмотрим, следующую функцию, в которой с помощью рекурсии
вычисляются числа Фибоначчи:
function Fib(N: integer): extended;
begin
if N = 0 then
Fib := 0.0
else
if N = 1 then
Fib := 1.0
else
Fib := Fib(N-1) + Fib(N-2);
end;
Обращение к данной версии процедуры Fib приведет к перепол-
нению стека сопроцессора 80x87, так как значений N больше, чем 8.
Причина заключается в том, что последний оператор присваивания
требует временного сохранения результата выполнения процедуры Fib
(N-1) в стеке сопроцессора 80x87. Каждое рекурсивное обращение
выделяется одна ячейка стека и на девятом обращении произойдет
переполнение стека. Корректной конструкцией в этом случае будет:
function Fib(N : integer) : extended;
var
F1,F2 : Extended;
begin
if N = 0 then
Fib := 0.0
else
if N = 1
then Fib := 1.0
else
begin
F1 := Fib(N-1); F2 := Fib(N-2);
Fib := F1 + F2;
end;
end;
Временные результаты теперь сохраняются в переменных, для
которых отводится стек процессора 8086. (Стек процессора 8086 ко-
нечно тоже может переполниться, но это обычно требует гораздо
большего числа рекурсивных вызовов).