home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / START16.PAK / C0D.ASM < prev    next >
Assembly Source File  |  1995-08-29  |  15KB  |  427 lines

  1. ;[]------------------------------------------------------------[]
  2. ;|      C0D.ASM -- Start Up Code For Windows DLLs               |
  3. ;[]------------------------------------------------------------[]
  4.  
  5. ;
  6. ;       C/C++ Run Time Library - Version 6.5
  7. ;       Copyright (c) 1991, 1994 by Borland International
  8. ;       All Rights Reserved.
  9.  
  10.                 locals
  11.  
  12.                 __C0__ = 1
  13. include         RULES.ASI
  14.  
  15.                 ASSUME CS:_TEXT, DS:DGROUP
  16.  
  17.                 public  __acrtused              ;satisfy MS for now
  18. __acrtused      equ     0
  19.  
  20.  
  21.                 extrn LIBMAIN:far       ;the C routine to be called
  22.                 extrn LOCALINIT:far     ;Windows heap init routine
  23.                 extrn LOCKSEGMENT:far
  24.                 extrn UNLOCKSEGMENT:far
  25.                 extrn GETWINFLAGS:far
  26.                 extrn __WEP:far
  27.                 extrn __cexit:DIST
  28. ifdef    __LARGE__
  29. ifndef    _BUILDRTLDLL
  30.                 extrn FREELIBRARY:far
  31.                 extrn __LockDLL:DIST
  32. endif
  33. endif
  34.                 extrn __setupio:near    ;required!
  35.  
  36.                 public LibEntry         ;Entry point for the DLL
  37.                 publicdll WEP
  38.  
  39. NULL            segment
  40.                 db      16 dup (0)              ;Windows
  41.                 db       4 dup (0)              ;destructor count
  42.                 db       2 dup (0)              ;exception list
  43.                 db       4 dup (0)              ;exception vptr
  44.                 db       6 dup (0)              ;reserved
  45.                 db       2 dup (0)              ;VBX control jump vector
  46.                                                 ;MUST be at SS:20h
  47.                 db       2 dup (0)              ;reserved
  48.                 ends
  49.  
  50. _CVTSEG         segment
  51.                 public __RealCvtVector
  52. __RealCvtVector label word
  53.                 ends
  54.  
  55. _SCNSEG         segment
  56.                 public __ScanTodVector
  57. __ScanTodVector label word
  58.                 ends
  59.  
  60. _FPSEG          segment
  61.                 public __FPVector
  62. __FPVector      dd      0
  63.                 ends
  64.  
  65. _DATA           segment
  66.                 public _errno
  67. _errno          dw      0
  68.                 public __protected
  69. __protected     dw      0
  70.                 public __8086
  71. __8086          dw      0
  72.                 public __8087
  73. __8087          dw      0
  74.                 public __version
  75. __version       label word
  76.                 public __osversion
  77. __osversion     label word
  78.                 public __osmajor
  79. __osmajor       db      0
  80.                 public __osminor
  81. __osminor       db      0
  82.                 public __osmode         ;Used for OS/2 protected mode by MS,
  83. __osmode        db      0               ;currently set to 0 under Windows
  84.                 public __hInstance
  85. __hInstance     dw      0
  86.                 public __WinAllocFlag   ;Used by malloc for additional flags
  87. __WinAllocFlag  dw      2000h           ;to pass to GlobalAlloc (used in DLLs)
  88.                                         ;default value is GMEM_SHARE
  89.                 public __LockWIN87EM    ;Used do lock down WIN87EM to avoid
  90. __LockWIN87EM   dw      1               ;DLL unload ordering problem
  91.  
  92. ifdef    __LARGE__
  93. ifndef    _BUILDRTLDLL
  94.                 public __LockRTLHandle
  95. __LockRTLHandle dw      0               ;Handle of RTLDLL (locked)
  96. endif
  97. endif
  98.  
  99.             public  __abend
  100. __abend        label   word
  101. _abend          dw      1               ;If LibEntry is called gets set to
  102.                                         ;normal state (0).  If it is 1 then
  103.                                         ;exit routines are not performed
  104.                                         ;Gets set to 1 if DLL is terminated
  105.                                         ;by a call to abort() or _exit().
  106.  
  107. CopyRight       db      'Borland C++ - Copyright 1994 Borland Intl.',0
  108.                 ends
  109.  
  110. _TEXT           segment
  111.  
  112. LibEntry        proc far
  113.                 mov     __hInstance, di ;save SI and DI
  114.                 push    si
  115.  
  116.                 push    di              ;handle of the module instance
  117.                 push    ds              ;library data segment
  118.                 push    cx              ;heap size
  119.                 push    es              ;command line segment
  120.                 push    si              ;command line offset
  121.  
  122.                 ;if we have some heap then initialize it
  123.                 jcxz    @@Init          ;jump if no heap specified
  124.  
  125.                 ;call the Windows function LocalInit() to set up the heap
  126.                 ;LocalInit((LPSTR)start, WORD cbHeap);
  127.  
  128.                 push    ds              ;Heap segment
  129.                 xor     ax,ax
  130.                 push    ax              ;Heap start offset in segment
  131.                 push    cx              ;Heap end offset in segment
  132.                 call    LOCALINIT
  133.                 xchg    ax,cx
  134.                 jcxz    @@JmpExit       ;quit if it failed
  135.                 jmp     short @@Init
  136. @@JmpExit:      jmp     @@Exit
  137.  
  138. @@Init:
  139.  
  140. IF LDATA EQ false
  141.                 mov     ax,-1
  142.                 push    ax
  143.                 call    LOCKSEGMENT
  144. ENDIF
  145.  
  146.                 ;Clear _BSS, uninitialized data area
  147.  
  148.                 xor     ax, ax
  149.                 push    ds
  150.                 pop     es
  151.                 mov     di,offset DGROUP:BeginBSS
  152.                 mov     cx,offset DGROUP:EndBSS
  153.                 sub     cx,di
  154.                 cld
  155.                 rep
  156.                 stosb
  157.  
  158. ;Determine DOS version
  159.  
  160.                 mov     ah, 30h
  161.                 int     21h
  162.                 mov     __version, ax   ; save minor and major revision
  163.  
  164. ;Determine whether we are in protected mode
  165.  
  166.                 call    GETWINFLAGS
  167.                 test    ax,1            ; WF_PMODE = 1
  168.                 jz      @@realmode      ; Note:  GETWINFLAGS returns a long,
  169.                                         ; so if WF_PMODE changed it could be
  170.                                         ; in the high word.
  171.                 mov     __protected, 8  ; Eight is for convenience.
  172. @@realmode:
  173.  
  174. ;Test for 8087 presence
  175.  
  176.                 test    ax,0400h        ; WF_8087 = 0x0400
  177.                 jz      @@no8087
  178.                 mov     __8087, 1
  179. @@no8087:
  180.                 and     ax,08h+04h+02h  ; WF_CPU486|WF_CPU386|WF_CPU286 
  181.                 shr     ax,1            ; Convert to 4 or 2 or 1 or 0
  182.                 test    ax,0004h        ; Have 4, 486 done
  183.                 jnz     @@NoAdjust
  184.                 or      ax,ax           ; Have 0, 8086 done
  185.                 jz      @@NoAdjust      
  186.                 inc     ax              ; Have 2 or 1, need 3 or 2
  187. @@NoAdjust:
  188.                 mov     __8086,ax       ; Set CPU Type
  189.  
  190. ;Call our initialization functions, including C++ static constructors.
  191.  
  192.                 mov     ax,ds
  193.                 mov     es,ax
  194.                 mov     si,offset DGROUP:InitStart      ;si = start of table
  195.                 mov     di,offset DGROUP:InitEnd        ;di = end of table
  196.  
  197.                 call    Initialize
  198.                 mov     _abend, 0                       ; Set LibEntry called
  199.  
  200.                 ;invoke the C routine to do any special initialization
  201. @@Main:         call    LIBMAIN         ;invoke the 'C' routine (result in AX)
  202.                 or  ax, ax
  203.  
  204. ifdef    __LARGE__
  205. ifndef    _BUILDRTLDLL
  206.                 jz  @@LibMainRet
  207.  
  208.                 push    ax
  209.                 call    __LockDLL
  210.                 mov __LockRTLHandle, ax
  211.                 pop ax
  212. @@LibMainRet:
  213. endif
  214. endif
  215.                 mov     di, __hInstance ;restore SI and DI
  216.                 pop     si
  217.                 ret
  218.  
  219. @@Exit:         mov ax, 0               ;set return code
  220.                 pop si                  ;remove arguments to LIBMAIN
  221.                 pop es                  ;  since we didn't call it.
  222.                 pop cx
  223.                 pop ds
  224.                 pop di
  225.                 pop si                  ;restore saved SI.  DI is restored
  226.                 ret                     ;  by removing arguments to LIBMAIN
  227.                 endp
  228.  
  229. ;---------------------------------------------------------------------------
  230. ;       _cleanup()      call all #pragma exit cleanup routines.
  231. ;       _checknull()    check for null pointer zapping copyright message
  232. ;       _terminate(exitcode, quick)     exit program with error code
  233. ;       _restorezero()  restore interrupt vectors
  234. ;
  235. ;       These functions are called by exit(), _exit(), _cexit(),
  236. ;       and _c_exit().
  237. ;---------------------------------------------------------------------------
  238.  
  239. ;       Call cleanup routines
  240.  
  241. __cleanup       PROC    DIST
  242.                 PUBLIC  __cleanup
  243.  
  244.                 mov     ax,ds
  245.                 mov     es,ax
  246.                 push    si
  247.                 push    di
  248.                 mov     si,offset DGROUP:ExitStart
  249.                 mov     di,offset DGROUP:ExitEnd
  250.                 call    Cleanup
  251.                 pop     di
  252.                 pop     si
  253.                 ret
  254. __cleanup       ENDP
  255.  
  256. ;       Check for null pointers before exit.  NO-OP on Windows.
  257.  
  258. __checknull     PROC    DIST
  259.                 PUBLIC  __checknull
  260.                 ret
  261. __checknull     ENDP
  262.  
  263. ;       Restore grabbed interrupt vectors.  NO-OP on Windows.
  264.  
  265. __restorezero     PROC    DIST
  266.                 PUBLIC  __restorezero
  267.                 ret
  268. __restorezero     ENDP
  269.  
  270. ;       Exit to DOS
  271. ;
  272. ; Usage:        void _terminate(int exitcode, int quick);
  273.  
  274. __terminate     PROC    DIST
  275.                 PUBLIC  __terminate
  276.  
  277.                 mov     bp,sp
  278.                 mov     al,[bp+cPtrSize]        ; get exitcode
  279.                 mov     ah,4ch
  280.                 int     21h
  281.                 ret
  282.                 endp
  283.  
  284. WEP             proc    windows pascal far nParam:WORD
  285.                 push    si
  286.                 push    di
  287.  
  288.                 cmp     _abend, 0
  289.                 jne     @@error
  290.                 push    nParam
  291.                 call    __WEP
  292.                 push    ax
  293.                 call    __cexit         ; perform cleanup without exiting
  294.  
  295. @@unlock:
  296.  
  297. ifdef    __LARGE__
  298. ifndef    _BUILDRTLDLL
  299.         mov    ax, __LockRTLHandle
  300.         or    ax, ax
  301.         jz    @@RTLNotLocked
  302.         push    ax
  303.         call    FreeLibrary
  304. @@RTLNotLocked:
  305. endif
  306. endif
  307.  
  308. IF LDATA EQ false
  309.                 mov     ax,-1
  310.                 push    ax
  311.                 call    UNLOCKSEGMENT
  312. ENDIF
  313.  
  314.                 pop     ax
  315.                 pop     di
  316.                 pop     si
  317.                 ret
  318.  
  319. @@error:
  320.                 push    1
  321.                 jmp     @@unlock
  322.  
  323.                 endp
  324.  
  325. ;       Return default data segment in AX
  326.  
  327. __GetDGROUP     PROC    FAR
  328.                 PUBLIC  __GetDGROUP
  329.                 mov     ax, DGROUP
  330.                 ret
  331.                 endp
  332.  
  333. ;------------------------------------------------------------------
  334. ;  Loop through a startup/exit (SE) table,
  335. ;  calling functions in order of priority.
  336. ;  ES:SI is assumed to point to the beginning of the SE table
  337. ;  ES:DI is assumed to point to the end of the SE table
  338. ;  First 64 priorities are reserved by Borland
  339. ;------------------------------------------------------------------
  340. PNEAR           EQU     0
  341. PFAR            EQU     1
  342. NOTUSED         EQU     0ffh
  343.  
  344. SE              STRUC
  345. calltype        db      ?                       ; 0=near,1=far,ff=not used
  346. priority        db      ?                       ; 0=highest,ff=lowest
  347. addrlow         dw      ?
  348. addrhigh        dw      ?
  349. SE              ENDS
  350.  
  351. Initialize      proc near
  352. @@Start:        mov     ax,100h                 ;start with lowest priority
  353.                 mov     dx,di                   ;set sentinel to end of table
  354.                 mov     bx,si                   ;bx = start of table
  355.  
  356. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  357.                 je      @@EndOfTable            ;yes, exit the loop
  358.                 cmp     es:[bx.calltype],NOTUSED;check the call type
  359.                 je      @@Next
  360.                 mov     cl, es:[bx.priority]    ;move priority to CX
  361.                 xor     ch, ch
  362.                 cmp     cx,ax                   ;check the priority
  363.                 jae     @@Next                  ;too high?  skip
  364.                 mov     ax,cx                   ;keep priority
  365.                 mov     dx,bx                   ;keep index in dx
  366. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  367.                 jmp     @@TopOfTable
  368.  
  369. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  370.                 je      @@Done                  ;yes, quit
  371.                 mov     bx,dx                   ;bx = highest priority item
  372.                 cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  373.                 mov     es:[bx.calltype],NOTUSED;wipe the call type
  374.                 push    es                      ;save es
  375.                 je      @@NearCall
  376.  
  377. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  378.                 pop     es                      ;restore es
  379.                 jmp     short @@Start
  380.  
  381. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  382.                 pop     es                      ;restore es
  383.                 jmp     short @@Start
  384.  
  385. @@Done:         ret
  386.                 endp
  387.  
  388. Cleanup         proc near
  389. @@Start:        mov     ah,0                    ;start with highest priority
  390.                 mov     dx,di                   ;set sentinel to end of table
  391.                 mov     bx,si                   ;bx = start of table
  392.  
  393. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  394.                 je      @@EndOfTable            ;yes, exit the loop
  395.                 cmp     es:[bx.calltype],NOTUSED;check the call type
  396.                 je      @@Next
  397.                 cmp     es:[bx.priority],ah     ;check the priority
  398.                 jb      @@Next                  ;too low?  skip
  399.                 mov     ah,es:[bx.priority]     ;keep priority
  400.                 mov     dx,bx                   ;keep index in dx
  401. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  402.                 jmp     @@TopOfTable
  403.  
  404. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  405.                 je      @@Done                  ;yes, quit
  406.                 mov     bx,dx                   ;bx = highest priority item
  407.                 cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  408.                 mov     es:[bx.calltype],NOTUSED;wipe the call type
  409.                 push    es                      ;save es
  410.                 je      @@NearCall
  411.  
  412. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  413.                 pop     es                      ;restore es
  414.                 jmp     short @@Start
  415.  
  416. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  417.                 pop     es                      ;restore es
  418.                 jmp     short @@Start
  419.  
  420. @@Done:         ret
  421.                 endp
  422.  
  423.                 ends
  424.                 end LibEntry
  425.