home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
t
/
tcsel003.zip
/
LONGJUMP.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-10-16
|
3KB
|
62 lines
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 }