home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 2.ddi / CLIB2.ZIP / SETJMP.CAS < prev    next >
Encoding:
Text File  |  1990-06-07  |  6.2 KB  |  239 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - setjmp.cas
  3.  *
  4.  * function(s)
  5.  *    setjmp - nonlocal goto
  6.  *    longjmp - performs a nonlocal goto
  7.  *-----------------------------------------------------------------------*/
  8.  
  9. /*[]------------------------------------------------------------[]*/
  10. /*|                                                              |*/
  11. /*|     Turbo C Run Time Library - Version 3.0                   |*/
  12. /*|                                                              |*/
  13. /*|                                                              |*/
  14. /*|     Copyright (c) 1987,1988,1990 by Borland International    |*/
  15. /*|     All Rights Reserved.                                     |*/
  16. /*|                                                              |*/
  17. /*[]------------------------------------------------------------[]*/
  18.  
  19. #pragma inline
  20. #include <asmrules.h>
  21. #include <setjmp.h>
  22.  
  23. /* leaves current FPU stack pointer in a word at SS:bx */
  24. /* preserves all registers but bx, cx */
  25.  
  26. /*-----------------------------------------------------------------------*
  27.  
  28. Name        setjmp - nonlocal goto
  29.  
  30. Usage        #include <setjmp.h>
  31.         int setjmp(jmp_buf jmpb);
  32.  
  33. Prototype in    setjmp.h
  34.  
  35. Description    Saves    current    context    information    (register,  stack
  36.         position, and segment values)  in the jmp_buf structure and
  37.         then returns to the caller.
  38.  
  39.         Setjmp returns 0 when called directly. The caller of setjmp
  40.         may be  "returned to" again  by longjmp, when  the function
  41.         result will never be zero.
  42.  
  43.         The jmp_buf contains  the entire context necessary for  a C
  44.         task, including  all segments and  the complete flag  word.
  45.         Only  the  AX,BX,CX,DX,ES  registers are lost, but then the
  46.         caller  of setjmp  does not expect them  to be  preserved
  47.         through a function call.
  48.  
  49.         On entry, the stack frame looks like:
  50.  
  51.         top    old BP
  52.             DI
  53.             SI
  54.         #if defined (__HUGE__)
  55.             DS
  56.         #endif
  57.             IP
  58.         #if (LPROG)
  59.             CS
  60.         #endif
  61.             jmpb OFFSET
  62.         #if (LDATA)
  63.             jmpb SEGMENT
  64.         #endif
  65.  
  66. Return value    setjmp returns 0 when it is initially called.
  67.  
  68. *------------------------------------------------------------------------*/
  69. int _CType setjmp(jmp_buf jmpb)
  70. {
  71. asm    pushf
  72. asm    pop    bx        /* save flags in bx */
  73.  
  74. asm    mov    dx, es        /* save es */
  75.  
  76. #if    LDATA
  77. asm    LES    di, jmpb
  78. #else
  79. asm    mov    di, jmpb
  80. asm    push    DS
  81. asm    pop    ES
  82. #endif
  83.  
  84. asm    mov    cx, di
  85. asm    cld
  86. asm    lea    ax, jmpb
  87.  
  88. #if defined(__PAS__)
  89. #if    LPROG
  90. asm    add    ax,4
  91. #else
  92. asm    inc    ax    
  93. asm    inc    ax    
  94. #endif
  95. #endif
  96.  
  97. asm    stosw            /* sp */
  98. asm    mov    ax, SS
  99. asm    stosw            /* SS */
  100.  
  101.     /* Save the Floating Point Unit */
  102. #ifdef __DEEP_STACK__ 
  103. #if defined(__MEDIUM__) || defined(__LARGE__) || defined(__HUGE__)
  104. asm     push    ds
  105. asm     mov     ax,_EMUSEG
  106. asm     mov     ds,ax
  107. asm     call    dword ptr ds:[0]
  108. asm     pop     ds
  109. #else
  110. asm     push    cs              /* simulate far call */
  111. asm     call    ds:[___fpustate]
  112. asm    mov    ax, SS:[bx]
  113. asm    stosw            /* FPU */
  114. #endif
  115. #else
  116. asm    xchg    ax,bx
  117. asm    stosw            /* flags */
  118. #endif
  119.  
  120. #if    LPROG
  121. asm    mov    ax, W1(jmpb-cPtrSize)    /* large code */
  122. #else
  123. asm    mov    ax, CS
  124. #endif
  125.  
  126. asm    stosw            /* CS */
  127. asm    mov    ax, W0(jmpb-cPtrSize)
  128. asm    stosw            /* IP */
  129.  
  130. asm    mov    ax, [bp]
  131. asm    stosw            /* BP */
  132. asm    xchg    ax, cx
  133. asm    stosw            /* DI */
  134. asm    mov    ax, dx
  135. asm    stosw            /* ES */
  136. asm    xchg    ax, si
  137. asm    stosw            /* SI */
  138.  
  139. #if defined(__HUGE__)
  140. asm    pop    ax
  141. asm    push    ax        /* caller's DS */
  142. #else
  143. asm    mov    ax, ds
  144. #endif
  145.  
  146. asm    stosw            /* DS */
  147. asm    mov    es, dx        /* restore ES */
  148.     return 0;
  149. }
  150.  
  151.  
  152. /*-----------------------------------------------------------------------*
  153.  
  154. Name        longjmp - performs a nonlocal goto
  155.  
  156. Usage        #include <setjmp.h>
  157.         void longjmp(jmp_buf jmpb, int retval);
  158.  
  159. Prototype in    setjmp.h
  160.  
  161. Description    Restores context information (register, stack position, and
  162.         segment  values)  from  the  jmp_buf  structure, which must
  163.         previously  have  been  saved  there  by  setjmp,  and then
  164.         returns to  the original caller  of setjmp with  val as the
  165.         return value  as if returning  from setjmp. The  difference
  166.         between  a  setjmp  return  and  a  longjmp  is that setjmp
  167.         returns zero, longjmp returns "val". Val can never be zero:
  168.         if zero argument is supplied, 1 is substituted.
  169.  
  170.         Longjmp never returns to its own caller. If the contents of
  171.         jmpb  are not  set, or  if  the  context therein  is for  a
  172.         function which  is not now  active (if it  has finished and
  173.         returned) then  the result will  generally be to  crash the
  174.         program.  The safest  styles of  use of  the setjmp/longjmp
  175.         pair are to effect a  return  upward through several nested
  176.         procedure layers  to a parent procedure  designed to handle
  177.         exceptions, or  to place both  setjmp and longjmp  within a
  178.         single scheduler/event handler lexical block.
  179.  
  180. Return value    longjmp  cannot return  the value  0; if  passed 0  in val,
  181.         longjmp will return 1.
  182.  
  183. *------------------------------------------------------------------------*/
  184. void _CType longjmp(jmp_buf jmpb, int retval)
  185. {
  186.     /* sneaky way to do if (retval==0) retval=1; */
  187. asm    mov    dx, retval
  188. asm    cmp    dx, 1        /* generates carry if dx=0    */
  189. asm    adc    dx, 0        /* if was 0, now it's 1     */
  190. asm    LDS_    si, jmpb
  191. asm    cld
  192.  
  193.     /* Change context begins with changing stack */
  194. asm    lodsw            /* sp */
  195. asm    cli
  196. asm    mov    ss, [si]        /* SS */
  197. asm    mov    sp, ax
  198. asm    sti
  199. asm    lodsw            /* skip SS */
  200.  
  201.     /* Restore the Floating Point Unit */
  202. #ifdef __DEEP_STACK__ 
  203. #if defined(__MEDIUM__) || defined(__LARGE__) || defined(__HUGE__)
  204. asm     push    ds
  205. asm     mov     ax,_EMUSEG
  206. asm     mov     ds,ax
  207. asm     call    dword ptr ds:[0]
  208. asm     pop     ds
  209. #else
  210. asm     push    cs              /* simulate far call */
  211. asm     call    ds:[___fpustate]
  212. asm    lodsw            /* FPU */
  213. asm    mov    SS:[bx], ax
  214. #endif
  215. #else
  216. asm    lodsw            /* flags */
  217. #endif
  218.  
  219.     /* Build the return-link to the caller of setjmp */
  220. asm    push    ax        /* flags */
  221. asm    lodsw            /* CS */
  222. asm    push    ax
  223. asm    lodsw            /* IP */
  224. asm    push    ax
  225.  
  226.     /* Restore other working registers */
  227. asm    lodsw            /* BP */
  228. asm    xchg    bp, ax
  229. asm    lodsw            /* DI */
  230. asm    xchg    di, ax
  231. asm    lodsw            /* ES */
  232. asm    mov    es, ax
  233. asm    lodsw            /* SI */
  234. asm    mov    ds, [si]
  235. asm    xchg    si, ax
  236. asm    xchg    ax, dx          /* put result in ax */
  237. asm    iret            /* return to original caller of setjmp */
  238. }
  239.