adstart.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 617 行 · 第 1/2 页
ASM
617 行
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
shr eax,16 ; get top 16 bits of eax
cmp ax,'DX' ; if top 16 bits = "DX"
sete al ; then its Pharlap
jne not_pharlap ; if its pharlap
sub bl,'0' ; - save major version number
mov al,bl ; - (was in ascii)
mov ah,0 ; - subtype
mov bx,14h ; - get value of Phar Lap data segment
jmp short know_extender ; else
not_pharlap: ; - see if Rational DOS/4G
mov dx,78h ; - ...
mov ax,0FF00h ; - ...
int 21h ; - ...
mov bx,17h ; - get writeable code segment for Ergo
cmp al,0 ; - ...
je short know_extender ; - quit if not Rational DOS/4G
mov al,1 ; - indicate Rational 32-bit Extender
mov ah,0 ; - assume zero base subtype
mov bx,ds ; - just use ds (FLAT model)
mov _psp,es ; - save segment address of PSP
;
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
;
; copy command line into bottom of stack
;
mov es, _psp ; point to PSP
mov edx,offset DGROUP:_end
add edx,0FH
and edx,0FFFFFFF0H
mov edi,81H ; DOS command buffer es:edi
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
mov al,0 ; assume no pgm name
stosb ; . . .
dec edi ; back up pointer 1
push edi ; save pointer to pgm name
mov ds,dx ; restore ds
push ds ; save ds
cmp byte ptr _Extender,1 ; if OS/386 or Rational
jg short pharlap ; then
mov dx,PSP_SEG ; - get PSP segment descriptor
mov ds,dx ; - ... into ds
mov dx,ds:[02ch] ; - get environment segment into dx
jmp short haveenv ; else
pharlap:mov dx,ENV_SEG ; - PharLap environment segment
haveenv: ; endif
mov es: _Envseg,dx ; save segment of environment area
mov ds,dx ; get segment addr of environment area
sub ebp,ebp ; assume "no87" env. var. not present
sub esi,esi ; offset 0
mov es: _Envptr,esi ; save offset of environment area
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
if ACAD
ifdef EADI
mov bp,1 ; force "no87" env. var as present
endif
endif ; ACAD
mov __no87,bp ; set state of "no87" environment var
mov _STACKLOW,edi ; save low address of stack
if ACAD
ifdef PADI
add ebx,4095 ; round top of stack up a page
shr ebx,12 ; get number of pages
push ebx ; store for later use
push ds
pop es
mov ah,4Ah ; set PADI memory size to smallest #
int 21h ; of pages ecompassing top of stack
mov ebx,phys_adr ; get phys addr of pg w/ packet buffer
mov eax,250Ah
mov ecx,1
int 21h ; map pg w/ pkt buf to end of new PADI
; memory block, above top of stack
mov cbufadr,eax ; store mapped offset as ptr to buf
call map_phys_mem ; allow 3rd party a chance to map in
; phys mem (returns # of pgs mapped)
pop ebx ; get # of pgs to top of stack
inc ebx ; add 1 for page mapped to end of seg
add ebx,eax ; add add'l pgs mapped by 3rd party
shl ebx,12 ; get bottom of heap, in bytes
mov _dynend,ebx ; set top of dynamic memory area
mov _curbrk,ebx ; set bottom of dynamic memory area
else ; PADI
add ebx,4095 ; round it up a page
shr ebx,12 ; get number of pages
push ebx ; store for later use
push ds
pop es
mov ah,4Ah ; set memory size to smallest #
int 21h ; of pages encompassing top of stack
call map_phys_mem ; allow 3rd party a chance to map in
; phys mem (returns # of pgs mapped)
pop ebx ; Get # of pgs to top of stack
add ebx,eax ; If so, add it in
shl ebx,12 ; Get bottom of heap, in bytes
mov _curbrk,ebx ; set bottom of dynamic memory area
mov _dynend,ebx ; set top of dynamic memory area
endif ; PADI
;mov ????,min_mem ; initial size of heap
else ; ACAD
mov _dynend,ebx ; set top of dynamic memory area
endif ; ACAD
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
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
if ACAD
ifndef PADI
Comment @
Take information from a structure in AutoCAD, pointed to by
info_sel:info_off, and store it for use by routines in the
program loaded by AutoCAD to which this module is linked.
@
movzx eax,word ptr info_sel
push eax
push info_off
call getinitinfo
add esp,8
endif
endif
ifdef ADS
push es
mov cl,3
mov ax,2502h
int 21h
jc noi3
mov ax,es
verr ax
jnz noi3
cmp ebx,8
jb noi3
sub ebx,8
mov eax,es:[ebx]
cmp eax,'DIVW'
jne noi3
mov eax,es:4[ebx]
cmp eax,'!!OE'
jne noi3
int 3
noi3: pop es
endif
sub ebp,ebp ; ebp=0 indicates end of ebp chain
call __CMain
_cstart_ endp
if ACAD
comment @
For applications which are called as a subroutine from AutoCAD
(namely AutoLISP), here is the ultimate exit point which returns
back to AutoCAD.
@
ifdef PADI
public exit_to_acad
exit_to_acad:
jmp rtnaddr ; Return to AutoCAD
endif
; Where we want attempted program exits to go:
ifdef ADS
child_exit equ adsi_child_exit ; Adhere to ADS naming convention
endif
extrn child_exit:near
endif ; ACAD
__exit proc near
pop eax ; get return code
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 msg
mov edx,offset ConsoleName
mov ax,03d01h ; write-only access to screen
int 021h
mov bx,ax ; get file handle
pop edx ; get 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 ; get return code
ok:
push eax ; save return code
mov eax,00h ; run finalizers
mov edx,0fh ; less than exit
call __FiniRtns ; call finalizer routines
pop eax ; restore return code
if ACAD
jmp child_exit ; do something more appropriate
else ; ACAD
mov ah,04cH ; DOS call to exit with return code
int 021h ; back to DOS
endif ; ACAD
__exit endp
__null_FPE_rtn proc near
ret ; return
__null_FPE_rtn endp
public __GETDS
__GETDS proc near
public "C",__GETDSStart_
__GETDSStart_ label byte
mov ds,cs:my_ds ; load saved DS value
ret
public "C",__GETDSEnd_
__GETDSEnd_ label byte
__GETDS endp
_TEXT ends
end _cstart_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?