cstrt386.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 425 行 · 第 1/2 页
ASM
425 行
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
sub esi,esi ; offset 0 for environment strings
mov edi,81H ; DOS command buffer es:edi
shr eax,16 ; get top 16 bits of eax
cmp ax,'DX' ; if top 16 bits = "DX"
jne not_pharlap ; then its pharlap
sub bl,'0' ; - save major version number
mov al,bl ; - (was in ascii)
mov ah,XS_NONE ; - extender subtype
push eax ; - save version number
mov es,_psp ; - point to PSP
mov ebx,es:[5Ch] ; - get highest addr used
add ebx,000000FFFh ; - round up to 4K boundary
and ebx,0FFFFF000h ; - ...
mov _curbrk,ebx ; - set first available memory locn
shr ebx,12 ; - calc. # of 4k pages
mov ax,ds ; - set ES=data segment
mov es,ax ; - ...
mov ah,4Ah ; - shrink block to minimum amount
int 21h ; - ...
pop eax ; - restore version number
mov bx,ds ; - get value of Phar Lap data segment
mov cx,ENV_SEG ; - PharLap environment segment
jmp short know_extender ; else
not_pharlap: ; - assume DOS/4G or compatible
mov dx,78h ; - see if Rational DOS/4G
mov ax,0FF00h ; - ...
int 21h ; - ...
cmp al,0 ; - ...
je short know_extender ; - 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,6 ; - 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; - DOS/4G non-zero based data
rat10: ; - endif
mov _psp,es ; - save segment address of PSP
mov cx,es:[02ch] ; - get environment segment into cx
jmp short know_extender ; else
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
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 stack
;
mov es,_psp ; point to PSP
mov edx,offset DGROUP:_end
add edx,0FH
and dl,0F0H
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
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)
;fixme-start
;mov ds,es:_Envseg ; get segment addr of environment area
db 26h ; force ES segment override
mov ds,_Envseg ; get segment addr of environment area
;fixme-end
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"
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
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 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
cmp byte ptr _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 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
sub ebp,ebp ; ebp=0 indicate end of ebp chain
call __CMain
_cstart_ endp
; don't touch AL in __exit, it has the return code
__exit proc near
public "C",__exit
ifdef __STACK__
pop eax ; get return code into eax
endif
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 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
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 ; restore return code
ok:
push eax ; save return code
mov eax,00H ; run finalizers
mov edx,0FH ; less than exit
call __FiniRtns ; call finializer routines
pop eax ; restore return code
mov ah,04cH ; DOS call to exit with return code
int 021h ; back to DOS
__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 ; return
__saved_DS dw 0 ; DS save area for interrupt routines
public "C",__GETDSEnd_
__GETDSEnd_ label byte
__GETDS endp
_TEXT ends
end _cstart_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?