cstrt086.asm

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

ASM
538
字号
        sub     cx,ax                   ; calc # of paragraphs available
        cmp     dx,cx                   ; compare with what we need
        jb      enuf_mem                ; if not enough memory
_Not_Enough_Memory_:
        mov     bx,1                    ; - set exit code
        mov     ax,offset NoMemory      ;
        mov     dx,cs                   ;
        call    __fatal_runtime_error_  ; - display msg and exit
enuf_mem:                               ; endif

        mov     ax,es                   ; point to data segment
;
; This will be done by the call to _nheapgrow() in cmain.c
;if _MODEL and (_BIG_DATA or _HUGE_DATA)
;        cmp     cx,1000h                ; if more than 64K available
;        jbe     lessthan64k             ; then
;        mov     cx,1000h                ; - keep 64K for data segment
;lessthan64k:                            ; endif
;        mov     dx,cx                   ; get # of paragraphs to keep
;endif
        mov     bx,dx                   ; get # of paragraphs in data segment
        shl     bx,1                    ; calc # of bytes
        shl     bx,1                    ; ...
        shl     bx,1                    ; ...
        shl     bx,1                    ; ...
        jne     not64k                  ; if 64K
        mov     bx,0fffeh               ; - set _curbrk to 0xfffe
not64k:                                 ; endif
        mov     es:_curbrk,bx           ; set top of memory owned by process
        mov     bx,dx                   ; get # of paragraphs in data segment
        add     bx,ax                   ; plus start of data segment
        mov     ax,es:_psp              ; get segment addr of PSP
        mov     es,ax                   ; place in ES
;
;       free up memory beyond the end of the stack in small data models
;               and beyond the 64K data segment in large data models
;
        sub     bx,ax                   ; calc # of para's we want to keep
        mov     ah,4ah                  ; "SETBLOCK" func
        int     21h                     ; free up the memory
mem_setup:
;
;       copy command line into bottom of stack
;
        mov     di,ds                   ; point es to PSP
        mov     es,di                   ; ...
        mov     di,81H                  ; DOS command buffer _psp:80
        mov     cl,-1[di]               ; get length of command
        mov     ch,0
        cld                             ; set direction forward
        mov     al,' '
        repe    scasb
        lea     si,-1[di]

ifdef __TINY__
        mov     dx,cs
else
        mov     dx,DGROUP
endif
        mov     es,dx                   ; es:di is destination
        mov     di,es:_STACKLOW
        mov     es:_LpCmdLine+0,di      ; stash lpCmdLine pointer
        mov     es:_LpCmdLine+2,es      ; ...
        je      noparm
        inc     cx
        rep     movsb
noparm: sub     al,al
        stosb                           ; store NULLCHAR
        mov     al,0                    ; assume no pgm name
        stosb                           ; . . .
        dec     di                      ; back up pointer 1
;
;       get DOS version number
;
        mov     ah,30h
        int     21h
        mov     es:_osmajor,al
        mov     es:_osminor,ah
        mov     cx,di                   ; remember address of pgm name
        cmp     al,3                    ; if DOS version 3 or higher
        jb      nopgmname               ; then
;
;       copy the program name into bottom of stack
;
        mov     ds,ds:2ch               ; get segment addr of environment area
        sub     si,si                   ; offset 0
        xor     bp,bp                   ; no87 not present!
L0:     mov     ax,[si]                 ; get first part of environment var
        or      ax,2020H                ; lower case
        cmp     ax,"on"                 ; if first part is 'NO'
        jne     L1                      ; - then
        mov     ax,2[si]                ; - get second part
        cmp     ax,"78"                 ; - if second part is '87'
        jne     L1                      ; - then
        inc     bp                      ; - - set bp to indicate NO87
L1:     cmp     byte ptr [si],0         ; end of string ?
        lodsb
        jne     L1                      ; until end of string
        cmp     byte ptr [si],0         ; end of all strings ?
        jne     L0                      ; if not, then skip next string
        lodsb
        inc     si                      ; - point to program name
        inc     si                      ; - . . .
L2:     cmp     byte ptr [si],0         ; - end of pgm name ?
        movsb                           ; - copy a byte
        jne     L2                      ; - until end of pgm name
nopgmname:                              ; endif
        mov     si,cx                   ; save address of pgm name
        mov     es:_LpPgmName+0,si      ; stash LpPgmName pointer
        mov     es:_LpPgmName+2,es      ; ...

        mov     ax,es:_psp              ; get segment addr of PSP
        mov     es,ax                   ; place in ES
        mov     bx,sp                   ; end of stack in data segment

        assume  ds:DGROUP
ifdef __TINY__
        mov     dx,cs
else
        mov     dx,DGROUP
endif
        mov     ds,dx
        mov     es,dx
        mov     __no87,bp               ; set state of "NO87" environment var
        mov     _STACKLOW,di            ; save low address of stack

        mov     cx,offset DGROUP:_end   ; end of _BSS segment (start of STACK)
        mov     di,offset DGROUP:_edata ; start of _BSS segment
        sub     cx,di                   ; calc # of bytes in _BSS segment
        mov     al,0                    ; zero the _BSS segment
        rep     stosb                   ; . . .

        cmp     word ptr __get_ovl_stack,0 ; if program not overlayed
        jne     _is_ovl                 ; then
        mov     ax,offset __null_ovl_rtn; - set vectors to null rtn
        mov     __get_ovl_stack,ax      ; - ...
        mov     __get_ovl_stack+2,cs    ; - ...
        mov     __restore_ovl_stack,ax  ; - ...
        mov     __restore_ovl_stack+2,cs; - ...
        mov     __close_ovl_file,ax     ; - ...
        mov     __close_ovl_file+2,cs   ; - ...
_is_ovl:                                ; endif
        xor     bp,bp                   ; set up stack frame
if _MODEL and _BIG_CODE
        push    bp                      ; ... for new overlay manager
        mov     bp,sp                   ; ...
endif
        ; DON'T MODIFY BP FROM THIS POINT ON!
        mov     ax,offset __null_FPE_rtn; initialize floating-point exception
        mov     word ptr __FPE_handler,ax       ; ... handler address
        mov     word ptr __FPE_handler+2,cs     ; ...

        mov     ax,0FFh                 ; run all initalizers
        call    __InitRtns              ; call initializer routines
        call    __CMain
_cstart_ endp

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

__exit  proc near
        public  "C",__exit
ifdef __TINY__
        jmp     ok
else
        push    ax
        mov     dx,DGROUP
        mov     ds,dx
        cld                             ; check lower region for altered values
        lea     di,__nullarea           ; set es:di for scan
        mov     es,dx
        mov     cx,NUM_VAL
        mov     ax,INIT_VAL
        repe    scasw
        pop     ax                      ; restore return code
        je      ok
;
; low memory has been altered
;
        mov     bx,ax                   ; get exit code
        mov     ax,offset NullAssign    ; point to msg
        mov     dx,cs                   ; . . .
endif

        public  __do_exit_with_msg__

; input: DX:AX - far pointer to message to print
;        BX    - exit code

__do_exit_with_msg__:
        mov     sp,offset DGROUP:_end+80h; set a good stack pointer
        push    bx                      ; save return code
        push    ax                      ; save address of msg
        push    dx                      ; . . .
ifndef __TINY__
        mov     dx,_TEXT
        mov     ds,dx
endif
        mov     dx,offset ConsoleName
        mov     ax,03d01h               ; write-only access to screen
        int     021h
        mov     bx,ax                   ; get file handle
        pop     ds                      ; restore address of msg
        pop     dx                      ; . . .
        mov     si,dx                   ; get address of msg
        cld                             ; make sure direction forward
L3:     lodsb                           ; get char
        cmp     al,0                    ; end of string?
        jne     L3                      ; no
        mov     cx,si                   ; calc length of string
        sub     cx,dx                   ; . . .
        dec     cx                      ; . . .
        mov     ah,040h                 ; write out the string
        int     021h                    ; . . .
        pop     ax                      ; restore return code
ok:
if _MODEL and _BIG_CODE
        mov     dx,DGROUP               ; get access to DGROUP
        mov     ds,dx                   ; . . .
        cmp     byte ptr __ovlflag,0    ; if MS Overlay Manager present
        je      no_ovl                  ; then
        push    ax                      ; - save return code
        mov     al,__intno              ; - get interrupt number used
        mov     ah,25h                  ; - DOS func to set interrupt vector
        lds     dx,__ovlvec             ; - get previous contents of vector
        int     21h                     ; - restore interrupt vector
        pop     ax                      ; - restore return code
no_ovl:                                 ; endif
endif
        push    ax                      ; save return code
        mov     ax,00h                  ; run finalizers
        mov     dx,0fh                  ; less than exit
        call    __FiniRtns              ; do finalization
        pop     ax                      ; restore return code
        mov     ah,04cH                 ; DOS call to exit with return code
        int     021h                    ; back to DOS
__exit  endp


;
;       set up addressability without segment relocations for emulator
;
public  __GETDS
__GETDS proc    near
        push    ax                      ; save ax
ifdef __TINY__
;       can't have segment fixups in the TINY memory model
        mov     ax,cs                   ; DS=CS
else
        mov     ax,DGROUP               ; get DGROUP
endif
        mov     ds,ax                   ; load DS with appropriate value
        pop     ax                      ; restore ax
        ret                             ; return
__GETDS endp


__null_FPE_rtn proc far
        ret                             ; return
__null_FPE_rtn endp

__null_ovl_rtn proc far
        ret                             ; return
__null_ovl_rtn endp


_TEXT   ends

        end     _cstart_

⌨️ 快捷键说明

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