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 + -
显示快捷键?