[Back to MISC SWAG index] [Back to Main SWAG index] [Original]
Unit LongJump;
{ This Unit permits a long jump from deeply nested Procedures/Functions back }
{ to a predetermined starting point. }
{ Whilst the purists may shudder at such a practice there are times when such}
{ an ability can be exceedingly useful. An example of such a time is in a }
{ BBS Program when the carrier may be lost unexpectedly whilst a user is on }
{ line and the requirement is to "back out" to the initialisation reoutines }
{ at the start of the Program. }
{ to use the facility, it is required that a call be made to the SetJump }
{ Function at the point to where you wish the execution to resume after a }
{ long jump. When the time comes to return to that point call FarJump. }
{ if you are an inexperienced Programmer, I do not recommend that this Unit }
{ be used For other than experimentation. Usually there are better ways to }
{ achieve what you want to do by proper planning and structuring. It is }
{ rare to find a well written Program that will need such and ability. }
Interface
Const
normal = -1; { return was not from a LongJump call }
Type
jumpType = Record { the data need For a return jump }
bp,sp,cs,ip : Word;
end;
Function SetJump(Var JumpData : jumpType): Integer;
Procedure FarJump(JumpData : jumpType; IDInfo : Integer);
Implementation
Type
WordPtr = ^Word;
Function SetJump(Var JumpData : jumpType): Integer;
begin { store the return address (the old bp register) }
JumpData.bp := WordPtr(ptr(SSeg,SPtr+2))^;
JumpData.ip := WordPtr(ptr(SSeg,SPtr+4))^;
JumpData.cs := WordPtr(ptr(SSeg,SPtr+6))^;
JumpData.SP := SPtr;
SetJump := normal; { show that this is not a FarJump call }
end; { SetJump }
Procedure FarJump(JumpData : jumpType; IDInfo : Integer );
begin
{ change the return address of the calling routine of the stack so that }
{ a return can be made to the caller of SetJump }
{ Use IDInfo as an identifier of the routine the jump occurred from }
WordPtr(ptr(SSeg,JumpData.SP))^ := JumpData.bp;
WordPtr(ptr(SSeg,JumpData.SP+2))^ := JumpData.ip;
WordPtr(ptr(SSeg,JumpData.SP+4))^ := JumpData.cs;
Inline($8b/$46/$06); { mov ax,[bp+6] }
Inline($8b/$ae/$fa/$ff); { mov bp,[bp-6] }
end; { FarJump }
end. { LongJump }
[Back to MISC SWAG index] [Back to Main SWAG index] [Original]