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 >
Pascal/Delphi Source File  |  1992-10-16  |  3KB  |  62 lines

  1. unit LongJump;
  2.  
  3. { This unit permits a long jump from deeply nested procedures/functions back }
  4. { to a predetermined starting point.                                         }
  5.  
  6. { Whilst the purists may shudder at such a practice there are times when such}
  7. { an ability can be exceedingly useful.  An example of such a time is in a   }
  8. { BBS program when the carrier may be lost unexpectedly whilst a user is on  }
  9. { line and the requirement is to "back out" to the initialisation reoutines  }
  10. { at the start of the program.                                               }
  11.  
  12. { To use the facility, it is required that a call be made to the SetJump     }
  13. { function at the point to where you wish the execution to resume after a    }
  14. { long jump. When the time comes to return to that point call FarJump.       }
  15.  
  16. { If you are an inexperienced programmer, I do not recommend that this unit  }
  17. { be used for other than experimentation.  Usually there are better ways to  }
  18. { achieve what you want to do by proper planning and structuring.  It is     }
  19. { rare to find a well written program that will need such and ability.       }
  20.  
  21. interface
  22.  
  23. const
  24.   normal = -1;                         { return was not from a LongJump call }
  25. type
  26.   jumptype = record                        { the data need for a return jump }
  27.                 bp,sp,cs,ip : word;
  28.              end;
  29.  
  30. function  SetJump(var JumpData : jumptype): integer;
  31. procedure FarJump(JumpData : jumptype; IDInfo : integer);
  32.  
  33. implementation
  34.  
  35. type
  36.   WordPtr = ^word;
  37.  
  38. function SetJump(var JumpData : jumptype): integer;
  39.   begin                     { store the return address (the old bp register) }
  40.     JumpData.bp := WordPtr(ptr(SSeg,SPtr+2))^;
  41.     JumpData.ip := WordPtr(ptr(SSeg,SPtr+4))^;
  42.     JumpData.cs := WordPtr(ptr(SSeg,SPtr+6))^;
  43.     JumpData.SP := SPtr;
  44.     SetJump := normal;                { show that this is not a FarJump call }
  45.   end;  { SetJump }
  46.  
  47. procedure FarJump(JumpData : jumptype; IDInfo : integer );
  48.   begin
  49.     { change the return address of the calling routine of the stack so that  }
  50.     { a return can be made to the caller of SetJump                          }
  51.     { Use IDInfo as an identifier of the routine the jump occurred from      }
  52.     WordPtr(ptr(SSeg,JumpData.SP))^   := JumpData.bp;
  53.     WordPtr(ptr(SSeg,JumpData.SP+2))^ := JumpData.ip;
  54.     WordPtr(ptr(SSeg,JumpData.SP+4))^ := JumpData.cs;
  55.     inline($8b/$46/$06);                                     { mov ax,[bp+6] }
  56.     inline($8b/$ae/$fa/$ff);                                 { mov bp,[bp-6] }
  57.   end;  { FarJump }
  58.  
  59. end.  { LongJump }
  60.  
  61.  
  62.