dllstart.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 452 行 · 第 1/2 页
ASM
452 行
mov dx,78h ; - see if Rational DOS/4G
mov ax,0FF00h ; - ...
int 21h ; - ...
cmp al,0 ; - ...
je error_exit ; - 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,DPMIGetSegmentBaseAddress ; - 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; - Rational non-zero based data
rat10: ; - endif
mov _psp,es ; - save segment address of PSP
mov cx,es:[02ch] ; - get environment segment into cx
mov _Extender,al ; record extender type
mov _ExtenderSubtype,ah ; record extender subtype
assume es:DGROUP
xor esi,esi
mov ebx,ds
mov es,ebx ; 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 private stack
;
mov edi,81h
mov es,_psp ; point to PSP
mov edx,offset _end - STACK_SIZE
add edx,0FH
and dl,0F0H
sub ecx,ecx
; mov cl,es:[edi-1] ; get length of command
mov cl,0
cld ; set direction forward
mov al,' '
repe scasb
lea esi,-1[edi]
mov edi,edx
mov ebx,es
mov edx,ds
assume ds:nothing
mov ds,ebx
mov es,edx ; 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)
mov ds,es:_Envseg ; get segment addr of environment area
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
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 _end - STACK_SIZE ; end of _BSS segment (start of STACK)
mov edi,offset _edata ; start of _BSS segment
sub ecx,edi ; calc # of bytes in _BSS segment
cmp _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 _end - STACK_SIZE ; 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
mov ___Argc,0 ; call DLL init code
call __CMain
__DLLstart_ endp
; don't touch AL in __exit, it has the return code
__exit proc far
public "C",__exit
ifdef __STACK__
pop eax ; get return code into eax
endif
jmp exit_code_eax
error_exit:
or eax,-1 ; exit code -1
jmp error_exit_code_eax
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
nextc: lodsb ; get char
cmp al,0 ; end of string?
jne nextc ; 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
exit_code_eax:
or eax,eax
je L13
error_exit_code_eax:
push eax ; save return code
mov eax,00H ; run finalizers
mov edx,0FH ; less than exit
call __FiniRtns ; call finializer routines
L10:
mov HeapEntry.offs,0
mov HeapEntry.segm,0
L11:
mov eax,offset HeapEntry
ifdef __STACK__
push eax
call _heapwalk
add esp,4
else
call _heapwalk
endif
or eax,eax
jne L12
cmp HeapEntry.flags,0
jne L11
mov eax,HeapEntry.offs
add eax,4
ifdef __STACK__
push eax
call free
add esp,4
else
call free
endif
jmp L10
L12:
call _heapshrink
pop eax ; restore return code
L13:
mov si,DGROUP
mov ds,esi
lss esp,caller_stack
ret
__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
public "C",__GETDSEnd_
__GETDSEnd_ label byte
__saved_DS dw 0 ; save area for DS for interrupt routines
__GETDS endp
_TEXT ends
end __DLLstart_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?