home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / CLIBSRC3.ZIP / EXEC.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-06-10  |  15.4 KB  |  493 lines

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