; INIT code
;This file will call all funcs within the _INIT_ segment for any init it
;may require.
; For Borland and Watcom:
;Each entire in the segment must be as follows
; db 0 ;this must be zero (else it will not be called)
; db ? ;this is the priority of the func. 0=highest 0xff=lowest
; dd ? ;offset of rountine to call
; For Micro$oft C++:
;Each entire in the segment must be as follows
; dd ? ;offset of rountine to call
;Borland INIT segments
_INIT_ segment word public use32 'INITDATA'
bc_init_start:
_INIT_ ends
_INITEND_ segment word public use32 'INITDATA'
bc_init_end:
_INITEND_ ends
_EXIT_ segment word public use32 'EXITDATA'
bc_exit_start:
_EXIT_ ends
_EXITEND_ segment word public use32 'EXITDATA'
bc_exit_end:
_EXITEND_ ends
;Watcom INIT segments
XIB segment word public use32 'DATA'
wc_init_start:
XIB ends
XIE segment word public use32 'DATA'
wc_init_end:
XIE ends
CONST2 SEGMENT word PUBLIC USE32 'DATA'
wc_exit_start:
CONST2 ends
CONST2END SEGMENT word PUBLIC USE32 'DATA'
wc_exit_end:
CONST2END ends
;option dotname ;need to allow . for MS segment names
;Micro$oft INIT segments (these are stupid!)
.CRT$XCU SEGMENT DWORD PUBLIC USE32 'DATA'
mc_init_start:
.CRT$XCU ENDS
.CRT$XCUEND SEGMENT DWORD PUBLIC USE32 'DATA'
mc_init_end:
.CRT$XCUEND ENDS
.code
call_init proc private ;(this code striped from BCv5.0 c0s.obj)
;dos4gwint3
mov esi,offset bc_init_start
mov edi,offset bc_init_end
call i__15
mov esi,offset wc_init_start
mov edi,offset wc_init_end
call i__15
mov esi,offset mc_init_start
mov edi,offset mc_init_end
i__13:
cmp esi,edi
jnz i__14
ret
i__14:
call dword ptr[esi]
add esi,4
jmp i__13
i__15:
mov ax,0100H
mov edx,edi
mov ebx,esi
i__16:
cmp ebx,edi
je i__18
cmp byte ptr [ebx],0ffH
je i__17
mov cl,byte ptr [ebx+1]
xor ch,ch
cmp cx,ax
jae i__17
mov ax,cx
mov edx,ebx
i__17:
add ebx,0006H
jmp i__16
i__18:
cmp edx,edi
je i__20
mov ebx,edx
mov byte ptr [ebx],0ffH
call dword ptr [ebx+2]
jmp i__15
i__20:
ret
call_init endp
call_exit proc private
;dos4gwint3
mov esi,offset bc_exit_start
mov edi,offset bc_exit_end
call e__15
;Watcom seems to mix two segments together. CONST2 contains the
;destructors but...it seems after that there is addition crap not needed
;So far what I have seen is that each destructor has 4 bytes preceding
;them, in each case the 1st byte was always '4'. I just continue until I
;the 1st byte is not '4'. It may though accidently in the future, I hope
;this never happens
mov esi,offset wc_exit_start
mov edi,offset wc_exit_end
e__13:
cmp bptr[esi],4 ;WC deconstructor?
jnz e__13b
cmp esi,edi
jnz e__14
e__13b:
ret
e__14:
call dword ptr[esi+4]
add esi,12
jmp e__13
ret
;There is no M$C uninit segment. They must uninit somehow else, how?
; I don't know but I know it does work !?
e__15:
mov ax,0100H
mov edx,edi
mov ebx,esi
e__16:
cmp ebx,edi
je e__18
cmp byte ptr [ebx],0ffH
je e__17
mov cl,byte ptr [ebx+1]
xor ch,ch
cmp cx,ax
jae e__17
mov ax,cx
mov edx,ebx
e__17:
add ebx,0006H
jmp e__16
e__18:
cmp edx,edi
je e__20
mov ebx,edx
mov byte ptr [ebx],0ffH
call dword ptr [ebx+2]
jmp e__15
e__20:
ret
call_exit endp