home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 2.ddi / CLIB2.ZIP / EXEC.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-06-07  |  13.8 KB  |  467 lines

  1. ;[]-----------------------------------------------------------------[]
  2. ;|      EXEC.ASM -- Execute a program with Overlay                   |
  3. ;|                                                                   |
  4. ;|      Turbo-C Run Time Library        Version 3.0                  |
  5. ;|                                                                   |
  6. ;|      Copyright (c) 1987,1988,1990 by Borland International Inc.   |
  7. ;|      All Rights Reserved.                                         |
  8. ;[]-----------------------------------------------------------------[]
  9.  
  10.         INCLUDE RULES.ASI
  11.  
  12. ;       Segments Definitions
  13.  
  14. Header@
  15.  
  16. ;       External References
  17.  
  18. extrn        __IOERROR:near
  19. extrn        __envseg:word
  20.  
  21. ExtSym@        _psp, WORD, __CDECL__
  22. ExtSym@     _version, WORD, __CDECL__
  23.  
  24.         ;* Miscellaneous equates */
  25.  
  26. ExeSignature    equ    05A4Dh
  27.  
  28.     ;/* Data for the Loader */
  29.  
  30. LdDesc        STRUC
  31. LdErrorMsg    db      'Exec failure.',00Dh,00Ah
  32. LdStack        db      80H dup(?)      ;Loader stack
  33. LdPSP        dw      ?               ;PSP address
  34. LdPathName    db      80 dup(?)       ;File to be loaded
  35. LdAX        dw      ?               ;Parse file name results
  36. LdExeSignature    dw      ?               ;EXE header buffer
  37. LdLength    dw      ?
  38. LdNbPages    dw      ?
  39. LdNbItems    dw      ?
  40. LdHdrSize    dw      ?
  41. LdMin        dw      ?
  42. LdMax        dw      ?
  43. LdSS        dw      ?
  44. LdSP        dw      ?
  45. LdCheckSum    dw      ?
  46. LdIP        dw      ?
  47. LdCS        dw      ?
  48. LdLoadAddr    dw      ?               ;Load Overlay interface block
  49. LdRelocFactor    dw      ?               ;Relocation factor to be used
  50. LdDesc        ENDS
  51.  
  52.         SUBTTL  Loader program
  53.         PAGE
  54. ;/*                                                      */
  55. ;/*------------------------------------------------------*/
  56. ;/*                                                      */
  57. ;/*     Loader Program                                   */
  58. ;/*     --------------                                   */
  59. ;/*                                                      */
  60. ;/*------------------------------------------------------*/
  61. ;/*                                                      */
  62. CSeg@
  63. LoaderDatas    db      size LdDesc dup (0)
  64. _Loader     PROC    NEAR        ;CX = EnvSeg, DX = End of Memory
  65.  
  66.         ;/* Setup segment registers */
  67.  
  68.                 xor     di, di
  69.                 mov     ax, cs
  70.                 mov     ds, ax
  71.                 mov     es, ax
  72.                 cli
  73.                 mov     ss, ax
  74.                 lea     sp, [di+LdPSP]
  75.         sti
  76.  
  77.         ;/* Load The Program */
  78.  
  79.                 push    cx
  80.                 push    dx
  81.                 mov     ax, 4B03h
  82.                 lea     bx, [di+LdLoadAddr]
  83.                 lea     dx, [di+LdPathName]
  84.                 int     21h
  85.                 pop     dx
  86.                 pop     cx
  87.                 jb      LoadError
  88.                 xor     di, di
  89.         cli
  90.                 mov     ss, [di+LdSS]
  91.                 mov     sp, [di+LdSP]
  92.         sti
  93.                 mov     bp, sp
  94.                 xor     ax, ax
  95.                 push    ax              ;Return to MSDOS for .COM
  96.                 mov     ax, [di+LdPSP]
  97.                 mov     ds, ax
  98.                 mov     es, ax
  99.                 mov     es:[2h], dx      ;Set End of Program into PSP
  100.                 mov     es:[2ch], cx     ;Set EnvSeg into PSP
  101.                 mov     ax, cs:[di+LdAX] ;AX = validity of FCBs
  102.                 jmp     dword ptr cs:[LdIP]
  103.  
  104.         ;/* Fatal Error if unable to load the program */
  105.  
  106. LoadError       label   near
  107.                 mov     ah, 040h
  108.                 mov     bx, 2
  109.                 mov     cx, LdStack - LdErrorMsg
  110.                 xor     dx, dx
  111.         int    21h        ;Error message on stderr
  112.                 mov     ax, 4C02h
  113.                 int     21h             ;exit(2)
  114. _Loader         ENDP
  115. LoaderSize      equ     ($ - LoaderDatas + 15) / 16
  116. wLoaderSize     equ     LoaderSize * 8
  117. LoaderVector    dd      _Loader - LoaderDatas
  118.         SUBTTL  Loader program
  119.         PAGE
  120. ;/*                                                      */
  121. ;/*------------------------------------------------------*/
  122. ;/*                                                      */
  123. ;/* int _exec(pathP, cmdP, envP);                        */
  124. ;/*     char    *pathP;                                  */
  125. ;/*     char    *cmdP;                                   */
  126. ;/*     char    *envP;                                   */
  127. ;/*                                                      */
  128. ;/*------------------------------------------------------*/
  129. ;/*                                                      */
  130.  
  131. pathP           equ     4
  132.  
  133. IF LDATA
  134. cmdP            equ     pathP + 4
  135. envP            equ     cmdP + 4
  136. ELSE
  137. cmdP            equ     pathP + 2
  138. envP            equ     cmdP + 2
  139. ENDIF
  140.  
  141. FileHandle      equ     2
  142. MemSize         equ     FileHandle + 2
  143. EnvSize         equ     MemSize + 2
  144. EnvAddr         equ     EnvSize + 4
  145. OldEnv          equ     EnvAddr + 2
  146.  
  147. OldEnvSave    dw    ?
  148. UseOldEnv    db    1            ;flag, defaults to true
  149.  
  150.         public    __exec
  151. __exec        proc    near
  152.                 push    bp
  153.                 mov     bp, sp
  154.                 sub     sp, OldEnv
  155.         cld
  156.                 push    si
  157.                 push    ds
  158.                 push    di
  159.                 push    es
  160.  
  161. IFDEF    __HUGE__
  162. ExtSym@ DGROUP@, WORD, __PASCAL__
  163.         mov    ds, cs:DGROUP@@         ; Get DS if we're huge
  164. ENDIF
  165.         mov    ax,__envseg        ;save old environment
  166.         mov    cs:OldEnvSave,ax
  167.  
  168.         ;/* Open the file to be loaded */
  169.  
  170.                 mov     ax, 3d00h
  171.                 pushDS_
  172.                 LDS_    dx, [bp+pathP]
  173.                 int     21h
  174.                 popDS_
  175.                 mov     [bp-FileHandle], ax
  176.                 jnb     CopyCmdLine
  177.                 jmp     ExecExit
  178.  
  179.         ;/* Copy the command line into the PSP */
  180.  
  181. CopyCmdLine     label   near
  182. IFDEF   __HUGE__
  183.                 mov     ax, seg _psp@
  184.                 mov     ds, ax
  185. ENDIF
  186.                 mov     es, _psp@
  187.                 mov     LoaderDatas.LdPSP, es
  188.                 mov     ax, es:[2ch]
  189.                 mov     [bp-OldEnv], ax
  190.                 mov     di, 080h
  191.                 pushDS_
  192.                 LDS_    si, [bp+cmdP]
  193.                 lodsb
  194.                 mov     dx, si           ;Save cmdP for parse
  195.                 stosb
  196.                 xor     cx, cx
  197.                 mov     cl, al
  198.                 inc     cx
  199.             rep     movsb
  200.  
  201.         ;/* Parse the command line for FCBs */
  202.  
  203.                 mov     ax, 2901h
  204.                 mov     si, dx
  205.                 mov     di, 05ch
  206.                 int     21h             ;Build FCB 1 in PSP
  207.                 mov     byte ptr LoaderDatas.LdAX, al
  208.                 mov     ax, 2901h
  209.                 mov     di, 06ch
  210.                 int     21h             ;Build FCB 2 in PSP
  211.                 mov     byte ptr LoaderDatas.LdAX+1, al
  212.                 popDS_
  213.  
  214.         ;/* Get the maximum memory block size */
  215.  
  216.                 mov     ah, 4Ah
  217.                 mov     bx, -1
  218.                 int     21h
  219.                 cmp     byte ptr _version@, 3
  220.                 jnb     GetMaxMem
  221.                 sub     bx, 280h
  222.  
  223. GetMaxMem       label   near
  224.                 mov     [bp-MemSize], bx
  225.  
  226.         ;/* Compute environment size */
  227.  
  228. IF LDATA
  229.                 mov     ax, [bp+envP]
  230.                 mov     dx, [bp+envP+2]
  231. ELSE
  232.                 mov     ax, [bp+envP]
  233.                 or      ax, ax
  234.                 mov     dx, ds
  235.                 jnz     DoWeHaveAnEnv
  236.                 cwd
  237. ENDIF
  238.  
  239. DoWeHaveAnEnv   label   near
  240.                 mov     bx, ax
  241.                 or      bx, dx
  242.                 jnz     WeHaveAnEnv
  243.                 xor     ax, ax
  244.                 mov     di, ax
  245.                 jmp     short SetEnvSize
  246.  
  247. WeHaveAnEnv     label   near
  248.                 mov     es, dx
  249.                 mov     di, ax
  250.                 push    di
  251.                 mov     cx, -1
  252.                 xor     ax, ax
  253.  
  254. GetEnvSize      label   near
  255.             repnz   scasb
  256.                 cmp     es:[di], al
  257.                 jne     GetEnvSize
  258.                 dec     cx
  259.                 add     di, 3
  260.             repnz   scasb        ;/* EnvSize += PathSize */
  261.                 dec     cx
  262.                 mov     ax, cx
  263.                 neg     ax
  264.                 pop     di
  265.  
  266. SetEnvSize      label   near
  267.                 mov     [bp-EnvAddr], di
  268.                 mov     [bp-EnvAddr+2], es
  269.                 add     ax, 15
  270.                 mov     cx, 4
  271.                 shr     ax, cl
  272.                 mov     [bp-EnvSize], ax
  273.  
  274.         mov    si,__envseg    ;get the arena header for the environ
  275.         dec    si
  276.         mov    es,si
  277.         cmp    ax,word ptr es:[03]    ;can we use the orig environ?
  278.         jbe    SavePath
  279.  
  280.         dec    cs:UseOldEnv        ;set to false
  281.                 inc     ax
  282.         sub     [bp-MemSize], ax    ;Reserve space for Env
  283.  
  284.         ;/* Save the pathname of the file to be loaded */
  285. SavePath    label    near
  286.                 LDS_    si, [bp+pathP]
  287.                 push    cs
  288.                 pop     es
  289.                 lea     di, LoaderDatas.LdPathName
  290.  
  291. CopyPathName    label   near
  292.                 lodsb
  293.                 stosb
  294.                 or      al, al
  295.                 jnz     CopyPathName
  296.  
  297.         ;/* Process the file according to its type */
  298.  
  299.                 mov     bx, [bp-FileHandle]
  300.                 mov     ax, [si-5]
  301.                 or      ah, ' '
  302.                 push    cs
  303.                 pop     ds
  304.                 mov     di, offset LoaderDatas
  305.                 cmp     ax, 'c.'
  306.                 jne     EXEFile
  307.                 jmp     COMFile
  308.  
  309.         ;/* Here comes all Exec Error */
  310.  
  311. ExecError       label   near
  312.                 push    ax
  313.                 mov     ah, 3eh
  314.                 mov     bx, [bp-FileHandle]
  315.                 int     21h
  316.                 pop     ax
  317.                 jmp     ExecExit
  318.  
  319.         ;/* This file must be an .EXE file */
  320.  
  321. EXEFile         label   near
  322.                 mov     ah, 3fh
  323.                 mov     cx, LdLoadAddr - LdExeSignature
  324.                 lea     dx, [di+LdExeSignature]
  325.                 int     21h
  326.                 jb      ExecError
  327.                 cmp     [di+LdExeSignature], ExeSignature
  328.                 mov     ax, 11
  329.                 jne     ExecError
  330.                 mov     ax, [di+LdNbPages]
  331.                 xor     dx, dx
  332.                 mov     dl, ah
  333.                 mov     ah, al
  334.                 xor     al, al
  335.                 shl     ax, 1
  336.                 rcl     dx, 1            ;DX:AX = NbPages * 512
  337.                 add     ax, [di+LdLength]
  338.                 adc     dx, 0
  339.                 mov     cx, 4
  340.  
  341. EXECompute      label   near
  342.                 shr     dx, 1
  343.                 rcr     ax, 1
  344.                 loop    EXECompute
  345.                 inc     ax
  346.                 sub     ax, [di+LdHdrSize]
  347.                 add     ax, [di+LdMin]
  348.                 xchg    bx, ax
  349.                 mov     ax, [di+LdPSP]
  350.                 add     ax, 16
  351.                 add     [di+LdCS], ax
  352.                 add     [di+LdSS], ax
  353.                 xchg    ax, bx
  354.                 jmp     short IsItEnough
  355.  
  356.         ;/* The file to be loaded is .COM file */
  357.  
  358. COMFile         label   near
  359.                 mov     ax, 4202h
  360.                 xor     cx, cx
  361.                 xor     dx, dx
  362.                 int     21h
  363.                 mov     cx, 4
  364.  
  365. COMCompute      label   near
  366.                 shr     dx, 1
  367.                 rcr     ax, 1
  368.                 loop    COMCompute
  369.                 inc     ax
  370.                 xchg    bx, ax
  371.                 mov     ax, [di+LdPSP]
  372.                 mov     [di+LdCS], ax
  373.                 mov     [di+LdIP], 0100h
  374.                 mov     [di+LdSS], ax
  375.                 add     ax, 16
  376.                 xchg    ax, bx
  377.  
  378. IsItEnough      label   near    ;AX = Pgm requirements, BX = Pgm Load Addr
  379.                 mov     [di+LdLoadAddr], bx
  380.                 mov     [di+LdRelocFactor], bx
  381.                 add     ax, LoaderSize
  382.                 cmp     ax, [bp-MemSize]
  383.                 mov     ax, 8
  384.                 jna     $+5
  385.                 jmp     ExecError
  386.  
  387.         ;/* Close the file before load it */
  388.  
  389.                 mov     ah, 3eh
  390.                 mov     bx, [bp-FileHandle]
  391.                 int     21h
  392.  
  393.         ;/* Takes all the memory above the current program */
  394.  
  395.                 mov     es, [di+LdPSP]
  396.                 mov     ah, 4ah
  397.                 mov     bx, [bp-MemSize]
  398.                 int     21h
  399.                 jnb     $+5
  400.                 jmp     ExecError
  401.  
  402.         ;/* Move the Loader before loading the overlay */
  403.  
  404.                 add     bx, [di+LdPSP]
  405.                 mov     dx, bx                   ;Save end of memory
  406.                 sub     bx, LoaderSize+1
  407.                 mov     word ptr LoaderVector+2, bx
  408.                 mov     es, bx
  409.                 mov     cx, wLoaderSize
  410.                 mov     si, offset LoaderDatas
  411.                 xor     di, di
  412.             rep     movsw
  413.  
  414.         ;/* Copy the environment */
  415.  
  416.         mov    es, [bp-OldEnv]
  417.         mov    cx, [bp-EnvSize]
  418.         cmp    cs:UseOldEnv,0
  419.         jne    ReUseEnv
  420.  
  421.         mov    ah, 48h
  422.         mov    bx, cx
  423.         int    21h
  424.         jb    ExecExit
  425.         jmp    short CopyEnv
  426.  
  427. ReUseEnv:    mov    ax, cs:OldEnvSave
  428. CopyEnv:    mov    es, ax
  429.         xor    di, di
  430.         lds    si, [bp-EnvAddr]
  431.         add    cx, cx
  432.         add    cx, cx
  433.         add    cx, cx
  434.         rep    movsw
  435.         push    es
  436.  
  437.     ;/* Free the old environment space */
  438.  
  439.         cmp    cs:UseOldEnv,0
  440.         jne    ReadyToOverlay
  441.         mov    es, cs:OldEnvSave
  442.         mov    ah, 49h
  443.         int    21h
  444.  
  445.         ;/* Jump to Loader and overlay the current program */
  446.  
  447. ReadyToOverlay  label   near
  448.         pop    cx
  449.                 jmp     LoaderVector
  450.  
  451.         ;/* All error conditions set _doserrno and errno */
  452.  
  453. ExecExit        label   near
  454.                 pop     es
  455.                 pop     di
  456.                 pop     ds
  457.                 pop     si
  458.                 push    ax
  459.                 call    __IOERROR
  460.                 mov     sp, bp
  461.                 pop     bp
  462.                 ret
  463.         endp
  464.               
  465. CSegEnd@
  466.         END
  467.