Иллюстрированный самоучитель по задачам и примерам Assembler

Реализация рекурсивных процедур

Такой вариант процедуры не требует внимания к параметрам, которые пере-, даются в стеке при вызове рекурсивной процедуры, так как после возврата из нее они попросту не нужны и удаляются из стека. Но стоит нам в процедуре DrawPattern изменить порядок обращения к процедуре Ellipse, как ситуация резко меняется. Рассмотрим второй вариант организации процедуры DrawPattern.

VOID DrawPattern (HWND hwnd.HDC hdc.INT_DWORD x.INT_DWORD y.INTJMRD r,INT_DWORD p)
//DrawPattern – рекурсивная процедура DrawPatten (вариант 2) вывода на экран узора
//из окружностей на псевдоязыке (фрагмент)
//Вход: х и у – координаты центра окружности; r – радиус окружности:
//р – порядок узора, hwnd – дескриптор окна. HDC – контекст устройства.
ПЕРЕМЕННЫЕ
HWND hwnd: HDC hdc;
INT_DWORD hdc .x .y .r.p
НАЧ_ПРОГ
ЕСЛИ (р) ТО //пока р*0
НАЧ_БЛОК_1
//рисуем еще четыре окружности по с центрами по краям этой DrawPattern (hwnd .hdc. х-r. у .r, р-1)
DrawPattern (hwnd .hdc. х. у-r .r. р-1)
DrawPattern (hwnd .hdc. х+r. у, r, р-1)
DrawPattern (hwnd .hdc. х. у+r .r. р-1)
//Ellipse – функция Win32 API для вывода эллипса (окружности), вписанного
//в прямоугольник (квадрат) с координатами правого верхнего угла (x_up .y_up)
//и левого нижнего угла (x_low .y_low):
//Ellipse(HDC hdc. INT_DW0RD x_up. INT_DWORD y_up. INTJMJRD x_low. INT_DWORD yjow)
//так как для рисования нужны координаты прямоугольника, а не центра окружности,
//то преобразуем их при вызове Ellipse:.
Ellipsethdc .x_up-r .y_up-r .x_low+r, y_low+r)
КОН_БЛОК_1 КОН_ПРОГ

Если в первом варианте процедуры DrawPattern – DrawPattern1 окружности рисовались перед очередной рекурсивной передачей управления в процедуру DrawPattern, то во втором варианте это делается в последнюю очередь – во время обратного хода по цепочке вызовов процедуры DrawPattern. Это уже требует наличия локальных переменных в процедуре и их сохранения на период пока осуществляются рекурсивные вызовы процедуры DrawPattern. Приведем соответствующие фрагменты основной программы и функции DrawPattern_2 из DLL-библиотеки maket dll.DLL.

Из этого фрагмента хорошо видно, в чем разница между размещением параметров, передаваемых в рекурсивную процедуру, и локальными переменными этой процедуры. Для доступа к параметрам используются положительные смещения относительно адреса в ВР (это скрыто от нас с помощью директивы ARG), а для доступа к локальным параметрам – отрицательные смещения.

Разница в изображениях возникла из-за разных мест в программе, где вызывается функция InvalidateRect. Попробуйте самостоятельно исправить этот "дефект".

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.