cstrtx32.asm

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

ASM
525
字号
        cld                             ;set direction forward
        mov     al,' '
        sub     esp,ecx                 ;allocate space on stack
        lea     esp,[esp-256]           ;make room for program name
        and     sp,0fffch               ;round down to dword alignment
        repe    scasb
        lea     esi,-1[edi]
        mov     edi,esp                 ;es:edi is destination
        push    ds
        push    es
        pop     ds                      ;ds:esi points to command line
        pop     es
        je      noparm
        inc     ecx
        rep     movsb
noparm: sub     al,al
        stosb                           ; store NULLCHAR
        push    es
        pop     ds                      ;restore ds
        mov     _LpCmdLine,esp          ; save command line address
        mov     _LpPgmName,edi          ; save program name address
        stosb                           ; assume no pgm name
        lds     esi,fword ptr _Envptr   ; load pointer to environment
        dec     edi                     ; back up pointer 1
        push    edi                     ; save pointer to pgm name
        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                           ; load a zero
        inc     esi                     ; point to program name
        inc     esi                     ; . . .

;
;       copy the program name into top of stack
;
L3:     cmp     byte ptr [esi],0        ; end of pgm name ?
        movsb                           ; copy a byte
        jne     L3                      ; until end of pgm name
        push    es
        pop     ds
        pop     esi                     ; restore address of pgm name

        mov     __no87,bp               ; set state of "no87" enironment var

        mov     ecx,offset DGROUP:_end  ; end of _BSS segment (start of STACK)
        mov     _dynend,ecx             ; top of dynamic memory allocation
        push    ecx
        add     ecx,0fffh
        and     cx,0f000h
        mov     _curbrk,ecx             ; current break location
        pop     ecx
        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                   ; ...
;set up stack for DGROUP expansion type memory allocation systems
        mov     ecx,__x32_stack_size
;don't allow smaller than a 4k stack
        mov     eax,4096
        cmp     ecx,eax
        ja short stack_okay
        mov     ecx,eax                 ;use the larger of the two
stack_okay:
        mov     ax,3509h
        mov     ebx,esp
        mov     esi,_curbrk             ;curbrk will be adjusted if required
        int     21h
        jc      insuf_mem
        mov     _curbrk,esi             ;current break point
        mov     esp,ebx                 ;switch to new stack if required
        mov     _STACKLOW,edx           ;lower limit for stack
        mov     _STACKTOP,esp           ; set stack top

        xor     eax,eax
        mov     fs,ax
        mov     gs,ax                   ;makes reloading segs faster

        mov     eax,0FFH                ; run all initalizers
        call    __InitRtns              ; call initializer routines
        mov     eax,_LpCmdLine          ; cmd buffer pointed at by EAX
        sub     ebp,ebp                 ; ebp=0 indicate end of ebp chain
        call    __CMain
__x386_init endp

insuf_mem:
        mov     edx,offset DGROUP:insuf_msg
exit_msg:       ;InitRtns hasn't been called yet so don't call FiniRtns
        mov     ah,9
        int     21h
        mov     ax,4c01h
        int     21h

null_error:     ;a null code pointer has been called
        push    ebp
        mov     ebp,esp
        mov     eax,offset DGROUP:null_msg
        mov     dl,1                    ;error code

; input: EAX - pointer to message to print
;        EDX - exit code

__do_exit_with_msg__:
        push    edx                     ; save return code
        push    eax                     ; save address of msg
        mov     edx,offset DGROUP: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
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                    ; . . .
ifndef __STACK__
        pop     eax                     ; restore return code
endif

;       don't touch AL in __exit, it has the return code
__exit   proc near
ifndef __STACK__
        push    eax                     ; save return code
endif
        mov     eax,00H                 ; run finalizers
        mov     edx,0FH                 ; less than exit
        call    __FiniRtns              ; call finializer routines
        pop     eax                     ; restore return code
        mov     ah,4cH                  ; DOS call to exit with return code
        int     021h                    ; back to DOS
__exit   endp

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

sbrk   proc    near
comment&
        The amount of memory requested is passed in register eax.  We will not
        assume at this time that the amount is page granular but we will
        always allocate page granular quantities anyway.
&
ifdef __STACK__
        mov     eax,ss:[esp]
endif
        add     eax,_curbrk
        jnc     sbrk_enter
        jmp     brk_c

sbrk   endp

comment&
        This is called when it is desired to expand the data segment.  The
        parameter passed in eax is the requested new top of the data segment.
        _curbrk and x386_break are updated.
&
__brk   proc    near
ifdef __STACK__
        mov     eax,ss:[esp+4]
endif
sbrk_enter:
        cmp     eax,__x386_break
        jbe short brk_a                 ;jmp if no action required
        push    ecx
        push    eax
        mov     ecx,eax
        mov     ax,3508h
        int     21h                     ;expand DGROUP block
        jc short brk_b
;eax is the new lowest legal value for esp, ecx is the actual break value.
        mov     _STACKLOW,eax
        mov     __x386_break,ecx
        pop     eax
        pop     ecx
brk_a:
        xchg    eax,_curbrk
        clc                             ; indicate success
        ret
brk_b:  ;insufficient memory
        pop     ecx                     ;pop and discard original eax
        pop     ecx                     ;restore original ecx
brk_c:
        mov     eax,-1
        stc                             ; indicate allocation failure
        ret

__brk  endp

;
;       __Int21 interface to OS int 21h translator
;
        public  __Int21_
        public  __fInt21_

__fInt21_ proc  far
        call    __Int21_
        ret
__fInt21_ endp

__Int21_ proc   near
        cmp     AH,48h                  ; allocate memory?
        je      short AllocMem          ; branch if yes
        cmp     AH,4Eh                  ; DOS Find First?
        je      short FindFirst         ; branch if yes
        cmp     AH,4Fh                  ; DOS Find Next?
        je      short FindNext          ; branch if yes
        int     21h                     ; issue int 21
        ret                             ; return
AllocMem:
        mov     eax,ebx                 ; get length to allocate
        call    sbrk                    ; allocate it
        ret                             ; return
FindFirst:
        push    EDX                     ; save filename address
        mov     EDX,EBX                 ; get DTA address
        mov     AH,1Ah                  ; set DTA address
        int     21h                     ; ...
        pop     EDX                     ; restore filename address
        mov     AH,4Eh                  ; find first
        int     21h                     ; ...
        ret                             ; return
FindNext:
        cmp     AL,0                    ; if not FIND NEXT
        jne     short findret           ; then return
        push    EDX                     ; save EDX
        mov     AH,1Ah                  ; set DTA address
        int     21h                     ; ...
        mov     AH,4Fh                  ; find next
        int     21h                     ; ...
        pop     EDX                     ; restore EDX
findret:ret                             ; return
__Int21_ endp

_TEXT   ends

        end     _cstart_

⌨️ 快捷键说明

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