Руководство по языку B.Pascal 7

       

У сопроцессора 80x87 имеется внутренний


У сопроцессора 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 ко- нечно тоже может переполниться, но это обычно требует гораздо большего числа рекурсивных вызовов).


Содержание раздела