50 Глава 2

^=====—=======; UNIT F_Jump; {===='==========}

{

+----------------------------------------------------------+

I Модуль содержит макроопределения, позволяющие запомнить \ ¦ любую точку программы с тем, чтобы после обработки ошибки\ \ периода исполнения передать управление в эту точку. I

+_-------„--------------------------------------------------/-

;

INTERFACE type

JumpRec = record

SPsave, {Сохраняет регистр SP} BPsave: Word; {Сохраняет регистр DP} JmpPtr: Pointer (FAR-адрес продолжения}

end; {JumpRec} ^——,-.-.-————————;

Procedure Set Jump(var JumpDest: JumpRec);

{Этот макрос обеспечивает сохранение содержимого регистров SP, BP и IP в записи JumpDest. Запоминается состояние, которое имели регистры в момент вызова макроса. Это обеспечивает последующий возврат процедурой LongJump в точку, непосредственно следующую за вызовом.} InLine ( $5F/

{pop di ,'DI^Ofs(JumpDest) } $07/

{pop es ;ES=Seg(JumpDest) } S26/$89/$25/

{mov es:[di],sp ;помещаем SP в SPsave } $26/$89/$6D/$02/

{mov es:[d.i+2],bp /помещаем BP в BPsave } $E8/$00/$OO/

{call null /помещаем в стек текущий} {null: /адрес командой CALL} $58/

{pop ax ;АХ=текущий адрес } $05/$ОС/$ОО/

{add ax,12 ;смещение команды NEXT } $26/$89/$45/$04/

{mov es:[di+4],ax /сохраняем FAR-адрес } $26/$8C/$4D/$O6) ;

{mov es:[dl+6],cs ;команды NEXT в JmpPtr} {NEXT: ; эта инструкция идет сразу за макросом и связана

с началом очередного оператора Турбо Паскаля} _•———.—————————;

Procedure LongJump(var JumpDest: JumpRec);

{Этот макрос восстанавливает содержимое регистров SP и BP из полей SPsave, BPsavp записи JumpDest и делает