adstart.asm

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

ASM
617
字号
        mov     ebx,50484152h           ; set ebx to "PHAR"
        sub     eax,eax                 ; set eax to 0
        mov     ah,30h
        int     21h                     ; modifies eax,ebx,ecx,edx
        mov     _osmajor,al
        mov     _osminor,ah
        mov     ecx,eax                 ; remember DOS version number
        shr     eax,16                  ; get top 16 bits of eax
        cmp     ax,'DX'                 ; if top 16 bits = "DX"
        sete    al                      ; then its Pharlap
        jne     not_pharlap             ; if its pharlap
        sub     bl,'0'                  ; - save major version number
        mov     al,bl                   ; - (was in ascii)
        mov     ah,0                    ; - subtype
        mov     bx,14h                  ; - get value of Phar Lap data segment
        jmp     short know_extender     ; else
not_pharlap:                            ; - see if Rational DOS/4G
        mov     dx,78h                  ; - ...
        mov     ax,0FF00h               ; - ...
        int     21h                     ; - ...
        mov     bx,17h                  ; - get writeable code segment for Ergo
        cmp     al,0                    ; - ...
        je      short know_extender     ; - quit if not Rational DOS/4G
        mov     al,1                    ; - indicate Rational 32-bit Extender
        mov     ah,0                    ; - assume zero base subtype
        mov     bx,ds                   ; - just use ds (FLAT model)
        mov      _psp,es                ; - save segment address of PSP
;
know_extender:                          ; endif
        mov     _Extender,al            ; record extender type
        mov     _ExtenderSubtype,ah     ; record extender subtype
;;      mov     es,bx                   ; get access to code segment
;;      mov     es:__saved_DS,ds        ; save DS value

;
;       copy command line into bottom of stack
;
        mov     es, _psp                ; point to PSP
        mov     edx,offset DGROUP:_end
        add     edx,0FH
        and     edx,0FFFFFFF0H
        mov     edi,81H                 ; DOS command buffer es:edi
        sub     ecx,ecx
        mov     cl,es:[edi-1]           ; get length of command
        cld                             ; set direction forward
        mov     al,' '
        repe    scasb
        lea     esi,-1[edi]
        mov     edi,edx
        mov     bx,es
        mov     dx,ds
        mov     ds,bx
        mov     es,dx                   ; es:edi is destination
        je      noparm
        inc     ecx
        rep     movsb
noparm: sub     al,al
        stosb                           ; store NULLCHAR
        mov     al,0                    ; assume no pgm name
        stosb                           ; . . .
        dec     edi                     ; back up pointer 1
        push    edi                     ; save pointer to pgm name
        mov     ds,dx                   ; restore ds
        push    ds                      ; save ds

        cmp     byte ptr  _Extender,1   ; if OS/386 or Rational
        jg      short pharlap           ; then
          mov   dx,PSP_SEG              ; - get PSP segment descriptor
          mov   ds,dx                   ; - ... into ds
          mov   dx,ds:[02ch]            ; - get environment segment into dx
          jmp   short haveenv           ; else
pharlap:mov   dx,ENV_SEG                ; - PharLap environment segment
haveenv:                                ; endif
        mov     es: _Envseg,dx          ; save segment of environment area
        mov     ds,dx                   ; get segment addr of environment area
        sub     ebp,ebp                 ; assume "no87" env. var. not present
        sub     esi,esi                 ; offset 0
        mov     es: _Envptr,esi         ; save offset of environment area
L1:     mov     eax,[esi]               ; get first 4 characters
        or      eax,20202020h           ; map to lower case
        ;cmp    eax,'78on'              ; check for "no87"
        cmp     eax,37386f6eh           ; 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
if      ACAD
 ifdef   EADI
        mov     bp,1                    ; force "no87" env. var as present
 endif
endif   ; ACAD
        mov     __no87,bp               ; set state of "no87" environment var

        mov      _STACKLOW,edi          ; save low address of stack

if      ACAD

ifdef   PADI
        add     ebx,4095                ; round top of stack up a page
        shr     ebx,12                  ; get number of pages
        push    ebx                     ; store for later use
        push    ds
        pop     es
        mov     ah,4Ah                  ; set PADI memory size to smallest #
        int     21h                     ;   of pages ecompassing top of stack

        mov     ebx,phys_adr            ; get phys addr of pg w/ packet buffer
        mov     eax,250Ah
        mov     ecx,1
        int     21h                     ; map pg w/ pkt buf to end of new PADI
                                        ;   memory block, above top of stack
        mov     cbufadr,eax             ; store mapped offset as ptr to buf

        call    map_phys_mem            ; allow 3rd party a chance to map in
                                        ;   phys mem (returns # of pgs mapped)
        pop     ebx                     ; get # of pgs to top of stack
        inc     ebx                     ; add 1 for page mapped to end of seg
        add     ebx,eax                 ; add add'l pgs mapped by 3rd party
        shl     ebx,12                  ; get bottom of heap, in bytes
        mov     _dynend,ebx             ; set top of dynamic memory area
        mov     _curbrk,ebx             ; set bottom of dynamic memory area
else    ; PADI
        add     ebx,4095                ; round it up a page
        shr     ebx,12                  ; get number of pages
        push    ebx                     ; store for later use
        push    ds
        pop     es
        mov     ah,4Ah                  ; set memory size to smallest #
        int     21h                     ;   of pages encompassing top of stack

        call    map_phys_mem            ; allow 3rd party a chance to map in
                                        ;   phys mem (returns # of pgs mapped)
        pop     ebx                     ; Get # of pgs to top of stack
        add     ebx,eax                 ; If so, add it in
        shl     ebx,12                  ; Get bottom of heap, in bytes
        mov     _curbrk,ebx             ; set bottom of dynamic memory area
        mov     _dynend,ebx             ; set top of dynamic memory area
endif   ; PADI
        ;mov    ????,min_mem            ; initial size of heap
else    ; ACAD
        mov      _dynend,ebx            ; set top of dynamic memory area
endif   ; ACAD

        mov     ecx,offset DGROUP:_end  ; end of _BSS segment (start of STACK)
        mov     edi,offset DGROUP:_edata; start of _BSS segment
        sub     ecx,edi                 ; calc # of bytes in _BSS segment
        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 DGROUP:_end  ; 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

if      ACAD
ifndef  PADI
Comment @
        Take information from a structure in AutoCAD, pointed to by
        info_sel:info_off, and store it for use by routines in the
        program loaded by AutoCAD to which this module is linked.
        @
        movzx   eax,word ptr info_sel
        push    eax
        push    info_off
        call    getinitinfo
        add     esp,8
endif
endif

ifdef ADS
        push    es
        mov     cl,3
        mov     ax,2502h
        int     21h
        jc      noi3
        mov     ax,es
        verr    ax
        jnz     noi3
        cmp     ebx,8
        jb      noi3
        sub     ebx,8
        mov     eax,es:[ebx]
        cmp     eax,'DIVW'
        jne     noi3
        mov     eax,es:4[ebx]
        cmp     eax,'!!OE'
        jne     noi3
        int     3
noi3:   pop     es
endif

        sub     ebp,ebp                 ; ebp=0 indicates end of ebp chain
        call    __CMain
_cstart_ endp


if      ACAD
comment @
        For applications which are called as a subroutine from AutoCAD
        (namely AutoLISP), here is the ultimate exit point which returns
        back to AutoCAD.
        @
ifdef   PADI
        public   exit_to_acad
exit_to_acad:
        jmp   rtnaddr                   ; Return to AutoCAD
endif


;       Where we want attempted program exits to go:
ifdef   ADS
child_exit    equ    adsi_child_exit     ; Adhere to ADS naming convention
endif
              extrn  child_exit:near
endif   ; ACAD


__exit   proc near
        pop     eax                     ; get return code
        jmp     short   ok

        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 msg
        mov     edx,offset ConsoleName
        mov     ax,03d01h               ; write-only access to screen
        int     021h
        mov     bx,ax                   ; get file handle
        pop     edx                     ; get address of msg
        mov     esi,edx                 ; get address of msg
        cld                             ; make sure direction forward
L4:     lodsb                           ; get char
        cmp     al,0                    ; end of string?
        jne     L4                      ; no
        mov     ecx,esi                 ; calc length of string
        sub     ecx,edx                 ; . . .
        dec     ecx                     ; . . .
        mov     ah,040h                 ; write out the string
        int     021h                    ; . . .
        pop     eax                     ; get return code
ok:

        push    eax                     ; save return code
        mov     eax,00h                 ; run finalizers
        mov     edx,0fh                 ; less than exit
        call    __FiniRtns              ; call finalizer routines
        pop     eax                     ; restore return code

if      ACAD
        jmp     child_exit              ; do something more appropriate
else    ; ACAD
        mov     ah,04cH                 ; DOS call to exit with return code
        int     021h                    ; back to DOS
endif   ; ACAD

__exit   endp


__null_FPE_rtn proc near
        ret                             ; return
__null_FPE_rtn endp

        public  __GETDS
__GETDS proc    near
public "C",__GETDSStart_
__GETDSStart_ label byte
        mov     ds,cs:my_ds             ; load saved DS value
        ret
public "C",__GETDSEnd_
__GETDSEnd_ label byte
__GETDS endp

_TEXT   ends

        end     _cstart_

⌨️ 快捷键说明

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