dllstart.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 452 行 · 第 1/2 页

ASM
452
字号
        mov     dx,78h                  ; - see if Rational DOS/4G
        mov     ax,0FF00h               ; - ...
        int     21h                     ; - ...
        cmp     al,0                    ; - ...
        je      error_exit              ; - quit if not Rational DOS/4G
        mov     ax,gs                   ; - get segment address of kernel
        cmp     ax,0                    ; - if not zero
        je      short rat9              ; - then
        mov     __D16Infoseg,ax         ; - - remember it
rat9:                                   ; - endif
        mov     ax,DPMIGetSegmentBaseAddress ; - check data segment base
        mov     bx,ds                   ; - set up data segment
        int     31h                     ; - DPMI call
        mov     al,X_RATIONAL           ; - asssume Rational 32-bit Extender
        mov     ah,XS_RATIONAL_ZEROBASE ; - extender subtype
        or      dx,cx                   ; - if base is non-zero
        jz      rat10                   ; - then
        mov     ah,XS_RATIONAL_NONZEROBASE; - Rational non-zero based data
rat10:                                  ; - endif
        mov     _psp,es                 ; - save segment address of PSP
        mov     cx,es:[02ch]            ; - get environment segment into cx

        mov     _Extender,al            ; record extender type
        mov     _ExtenderSubtype,ah     ; record extender subtype

        assume  es:DGROUP

        xor     esi,esi
        mov     ebx,ds
        mov     es,ebx                  ; get access to code segment
        mov     es:__saved_DS,ds        ; save DS value
        mov     _Envptr,esi             ; save address of environment strings
        mov     _Envseg,cx              ; save segment of environment area
        push    esi                     ; save address of environment strings
;
;       copy command line into bottom of private stack
;
        mov     edi,81h
        mov     es,_psp                 ; point to PSP
        mov     edx,offset _end - STACK_SIZE
        add     edx,0FH
        and     dl,0F0H
        sub     ecx,ecx
;        mov     cl,es:[edi-1]          ; get length of command
        mov     cl,0
        cld                             ; set direction forward
        mov     al,' '
        repe    scasb
        lea     esi,-1[edi]
        mov     edi,edx
        mov     ebx,es
        mov     edx,ds

        assume  ds:nothing

        mov     ds,ebx
        mov     es,edx                   ; es:edi is destination
        je      noparm
        inc     ecx
        rep     movsb
noparm: sub     al,al
        stosb                           ; store NULLCHAR
        stosb                           ; assume no pgm name
        pop     esi                     ; restore address of environment strings
        dec     edi                     ; back up pointer 1
        push    edi                     ; save pointer to pgm name
        push    edx                     ; save ds(stored in dx)
        mov     ds,es:_Envseg           ; get segment addr of environment area
        sub     ebp,ebp                 ; assume "no87" env. var. not present
L1:     mov     eax,[esi]               ; get first 4 characters
        or      eax,20202020h           ; map to lower case
        cmp     eax,'78on'              ; check for "no87"
        jne     short L2                ; skip if not "no87"
        cmp     byte ptr 4[esi],'='     ; make sure next char is "="
        jne     short L2                ; no
        inc     ebp                     ; - indicate "no87" was present
L2:     cmp     byte ptr [esi],0        ; end of string ?
        lodsb
        jne     L2                      ; until end of string
        cmp     byte ptr [esi],0        ; end of all strings ?
        jne     L1                      ; if not, then skip next string
        lodsb
        inc     esi                     ; point to program name
        inc     esi                     ; . . .
;
;       copy the program name into bottom of stack
;
L3:     cmp     byte ptr [esi],0        ; end of pgm name ?
        movsb                           ; copy a byte
        jne     L3                      ; until end of pgm name
        pop     ds                      ; restore ds
        pop     esi                     ; restore address of pgm name
        mov     ebx,esp                 ; end of stack in data segment

        assume  ds:DGROUP

        mov     __no87,bp               ; set state of "no87" enironment var
        mov     _STACKLOW,edi           ; save low address of stack
        mov     _dynend,ebx             ; set top of dynamic memory area

        mov     ecx,offset _end - STACK_SIZE ; end of _BSS segment (start of STACK)
        mov     edi,offset _edata       ; start of _BSS segment
        sub     ecx,edi                 ; calc # of bytes in _BSS segment
        cmp     _Extender,X_RATIONAL    ; if not Rational DOS extender
        jne     short zerobss           ; then zero whole BSS
        cmp     ecx,1000h               ; if size of BSS <= 4K
        jbe     short zerobss           ; then just zero it
        mov     ecx,1000h               ; only zero first 4K under Rational
                                        ; DOS extender will zero rest of pages
zerobss:mov     dl,cl                   ; save bottom 2 bits of count in edx
        shr     ecx,2                   ; calc # of dwords
        sub     eax,eax                 ; zero the _BSS segment
        rep     stosd                   ; ...
        mov     cl,dl                   ; get bottom 2 bits of count
        and     cl,3                    ; ...
        rep     stosb                   ; ...

        mov     eax,offset _end - STACK_SIZE ; cmd buffer pointed at by EAX
        add     eax,0FH
        and     al,0F0H
        mov     _LpCmdLine,eax          ; save command line address
        mov     _LpPgmName,esi          ; save program name address
        mov     eax,0FFH                ; run all initalizers
        call    __InitRtns              ; call initializer routines
        sub     ebp,ebp                 ; ebp=0 indicate end of ebp chain
        mov     ___Argc,0               ; call DLL init code
        call    __CMain
__DLLstart_ endp

;       don't touch AL in __exit, it has the return code

__exit  proc    far
        public  "C",__exit
ifdef __STACK__
        pop     eax                     ; get return code into eax
endif
        jmp     exit_code_eax

error_exit:
        or      eax,-1                  ; exit code -1
        jmp     error_exit_code_eax

        public  __do_exit_with_msg__

; input: ( char *msg, int rc )  always in registers

__do_exit_with_msg__:
        push    edx                     ; save return code
        push    eax                     ; save address of msg
        mov     edx,offset ConsoleName
        mov     ax,03d01h               ; write-only access to screen
        int     021h
        mov     bx,ax                   ; get file handle
        pop     edx                     ; restore address of msg
        mov     esi,edx                 ; get address of msg
        cld                             ; make sure direction forward
nextc:  lodsb                           ; get char
        cmp     al,0                    ; end of string?
        jne     nextc                   ; no
        mov     ecx,esi                 ; calc length of string
        sub     ecx,edx                 ; . . .
        dec     ecx                     ; . . .
        mov     ah,040h                 ; write out the string
        int     021h                    ; . . .
        pop     eax                     ; restore return code
exit_code_eax:
        or      eax,eax
        je      L13
error_exit_code_eax:
        push    eax                     ; save return code
        mov     eax,00H                 ; run finalizers
        mov     edx,0FH                 ; less than exit
        call    __FiniRtns              ; call finializer routines

L10:
        mov     HeapEntry.offs,0
        mov     HeapEntry.segm,0
L11:
        mov     eax,offset HeapEntry
ifdef __STACK__
        push    eax
        call    _heapwalk
        add     esp,4
else
        call    _heapwalk
endif
        or      eax,eax
        jne     L12
        cmp     HeapEntry.flags,0
        jne     L11
        mov     eax,HeapEntry.offs
        add     eax,4
ifdef __STACK__
        push    eax
        call    free
        add     esp,4
else
        call    free
endif
        jmp     L10
L12:
        call    _heapshrink
        pop     eax                     ; restore return code
L13:
        mov     si,DGROUP
        mov     ds,esi
        lss     esp,caller_stack
        ret
__exit  endp

        public  __GETDS
        align   4
__GETDS proc    near
public "C",__GETDSStart_
__GETDSStart_ label byte
        mov     ds,cs:__saved_DS        ; load saved DS value
        ret
public "C",__GETDSEnd_
__GETDSEnd_ label byte
__saved_DS  dw  0               ; save area for DS for interrupt routines
__GETDS endp

_TEXT   ends

        end __DLLstart_

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?