?? crt0.asm
字號:
page ,132
title crt0 - C start up routine
;***
;crt0.asm - C start up routine
;
; Copyright (c) 1985-1988, Microsoft Corporation. All rights reserved.
;
;Purpose:
; How startup works in a few words -
;
; The startup and termination is performed by a few modules
;
; crt0.asm DOS 2.x/3.x specific init/term
; crt0msg.asm DOS 2.x/3.x error messages
; (winstart.asm) Windows specific init/term (not included)
;
; crt0dat.asm remainder of shared DOS 3.x init/term
;
; ************* IMPORTANT *****************************************
;
; The "DOSSEG" directive in this module must not be removed or else
; the user will have to link with the "/DOSSEG" linker switch in
; order to get proper segment ordering.
;
; See the C documentation for more information about the /DOSSEG switch.
;
; All assembler modules must be assembled with the /Mx switch, i.e.
;
; masm -Mx crt0,;
;
;*******************************************************************************
;*******************************;*
DOSSEG ;* specifies DOS SEGment ordering *
;*******************************;*
?DF= 1 ; this is special for c startup
.xlist
include version.inc
include cmacros.inc
include msdos.inc
include brkctl.inc
EI_QB = -1 ;[12] interpreter version
EI_EB = 0 ;[12] not EB
OM_DOS5 = 0 ;[12] not an OS/2 version
include stack2.inc ;[12] STACK_SIZE constant
.list
CondEnd MACRO entrypoint ;[12] generate END _astart
END entrypoint ;[12]
ENDM ;[12]
assumesdata macro seg ;;[12] Newer versions of CMACROS reject
assumes seg,DGROUP ;;[12]
endm ;;[12]
page
;===========================================================================
;
; Segment definitions
;
; The segment order is essentially the same as in XENIX.
; This module is edited after assembly to contain a dosseg comment
; record for the linker.
;
;===========================================================================
createSeg _TEXT, code, word, public, CODE, <>
createSeg C_ETEXT,etext, word, public, ENDCODE,<>
createSeg _DATA, data, word, public, DATA, DGROUP
createSeg STACK, stack, para, stack, STACK, DGROUP
defGrp DGROUP ; define DGROUP
codeOFFSET equ offset _TEXT:
dataOFFSET equ offset DGROUP:
page
public __acrtused ; trick to force in startup
__acrtused = 9876h ; funny value not easily matched in SYMDEB
extrn __acrtmsg:abs ; trick to pull in startup messages
sBegin stack
assumesdata ds ;[12]
db STACK_SIZE dup (?) ;[12] default stack size
sEnd
page
externP main ; C main program
externP exit ; exit ( code )
extrn __exit:far ; _exit ( code) (cmacros name conflict)
extrn __amsg_exit:FAR ;[12]
extrn B$terminate:FAR ;[12]
extrn B$Init:FAR ;[12]
sBegin data
extrn _edata:byte ; end of data (start of bss)
extrn _end:byte ; end of bss (start of stack)
externW _psp ; psp:0 (paragraph #)
; these are used by DOS C memory management (not used in Windows)
externW _asizds ;[12] moved these to CDATA.INC
externW _atopsp ;[12]
externW _aexit_rtn ;[12]
externW _abrktb ;[12]
externW _abrktbe ;[12]
externW _abrkp ;[12]
extrn b$nmalloc_start:word ;[12] start of BASIC near malloc buffer
externW _aenvseg ;[12]
externW _acmdseg ;[12]
externW _acmdln ;[12]
sEnd
page
externP _cinit ; run-time initializers
sBegin code
assumes cs,code
assumes ds,nothing
page
;***
;_astart - start of all C programs
;
;Purpose:
; Startup routine to initialize C run-time environment
;
;Entry:
;
;Exit:
; Exits to DOS via exit().
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************
labelNP <PUBLIC,_astart> ; start address of all "C" programs
; check MS-DOS version for 2.0 or later
callos VERSION ; AX must be preserved until later
cmp al,2 ; check for version 2 or later
jae setup ; yes - continue with setup
int 20h ; DOS 1.0 exit program
setup:
mov di,DGROUP
mov si,ds:[DOS_MAXPARA] ; get max. paragraph
sub si,di ; si = # para in data area
cmp si,1000h ; if more than 64K
jb setSP
mov si,1000H ; use full 64K (-16)
setSP:
cli ; turn off interrupts
mov ss,di ; SS = DGROUP
add sp,dataoffset _end-2 ; 2 for _asizds limit
sti ; turn interrupts back on
jnc SPok
assumes ss,DGROUP ;[12] assume it points somewhere
StackOverflow: ;[12]
xor ax,ax ;[12] stack overflow error message (0)
mov SS:[_aexit_rtn],codeoffset B$terminate ;[12] jmp to INT 21, fn 4C
jmp short jmp_amsg_exit ;[12] print message and exit
SPok:
assumesdata ss ;[12]
and sp,not 1 ; make even (if not)
mov [_atopsp],sp ; save top of stack
mov ax,si ; si = # paragraphs
mov cl,4
shl ax,cl
dec ax
mov [_asizds],ax ; save DS size - 1 (in bytes)
; release extra space to DOS
add si,di ; si = DGROUP + # para in DGROUP
mov ds:[DOS_MAXPARA],si ; fix psp:2
mov bx,es ; bx = PSP base
sub bx,si ; bx = - # para used
neg bx
callos setmem ; set memory block size
mov [_psp],ds ; save psp:0
MOV AX,DS:[2CH] ;[12] AX = Handle of Environ Segment
MOV SS:[_aenvseg],AX ;[12]
mov SS:[_acmdseg],DS ;[12] Handle of Command Line Segment
mov SS:[_acmdln],081H ;[12] Offset of Command Line String
; zero data areas (_BSS and c_common)
push ss
pop es
assumesdata es ;[12]
cld ; set direction flag (up)
mov di,dataOFFSET _edata ; beginning of bss area
mov cx,dataOFFSET _end ; end of bss area
sub cx,di
xor ax,ax
rep stosb ; zero bss
; C segmentation conventions set up here (DS=SS and CLD)
push ss ; set up initial DS=ES=SS, CLD
pop ds
assumesdata ds ;[12]
;[12] Initialize C near heap to BASIC near malloc buffer
mov [_aexit_rtn],codeoffset _exit ;[12] call high-level exit()
mov ax,[b$nmalloc_start] ;[12] get top of nmalloc buffer
mov _abrktb.sz,ax ;[12] set near brk end of heap marker
call B$Init ;[12]Do necessary BASIC init Prior to XI
;[12] processing.
; do necessary initialization BEFORE command line processing!
call _cinit ; shared by DOS and Windows
push ss
pop ds ; ds = DGROUP
push ss ;[12]
pop es ;[12]set es=ds
assumesdata ds ;[12]
; call main and exit
xor bp,bp ; mark top stack frame for SYMDEB
call main ; main ( argc , argv , envp )
; use whatever is in ax after returning here from the main program
push ax
call exit ; exit (AX)
; _exit will call terminators
page
;***
;_amsg_exit, _cintDIV - Fast exit fatal errors
;
;Purpose:
; Exit the program with error code of 255 and appropriate error
; message. cintDIV is used for integer divide by zero, amsg_exit
; is for other run time errors.
;
;Entry:
; AX = error message number (amsg_exit only).
;
;Exit:
; calls exit() [cintDIV] or indirect through _aexit_rtn [amg_exit].
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************
labelNP <PUBLIC,_cintDIV>
assumes ds,nothing
assumesdata ss ;[12]
; _cintDIV establishes ds = DGROUP
mov ax,3 ; Integer divide by zero interrupt
mov [_aexit_rtn],codeoffset _exit ; call high-level exit()
; to cause file buffer flushing
jmp_amsg_exit: ;[12]
jmp __amsg_exit ;[12] branch to __amsg_exit in BASIC code
sEnd
CondEnd _astart ;[12] start address if NOT FO_RTM
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -