title start up code for assembly langauge include asm.inc dosseg NULL segment para public 'BEGDATA' NULL ends public psp,startup,dgroup_segment,top_of_stack,initterm,xcbegin,xcend XIB segment word public 'DATA' ; these segments contain a list of xibegin label word ; procedure addresses that the XIB ends ; start-up code calls before main XI segment word public 'DATA' XI ends XIE segment word public 'DATA' xiend label word XIE ends XPB segment word public 'DATA' ; these segments contain a list of xpbegin label word ; procedure addresses that the XPB ends ; start-up code calls before XP segment word public 'DATA' ; returning control to ms-dos. they XP ends ; are called only on a full exit. XPE segment word public 'DATA' ; xpend label word XPE ends XCB segment word public 'DATA' ; these segments contain a list of xcbegin label word ; procedure addresses that the XCB ends ; start-up code calls before XC segment word public 'DATA' ; returning control to ms-dos. they XC ends ; are ALWAYS called regardless of how XCE segment word public 'DATA' ; the program terminates. xcend label word XCE ends DGROUP group XIB,XI,XIE,XPB,XP,XPE,XCB,XC,XCE .data psp dw 0 dgroup_segment dw 0 .data? extb _edata,_end top_of_stack dw ? .code extn set_argc_argv,ms_dos,main,exit_program ;; initterm ; ; entry SI initializer or terminator list ; DI end of list ; may use AX,BX,CX,DX,DI,SI,DS,ES ; initterm proc movx ds,DGROUP_SEGMENT ; call list of initializers or iit1: cmp si,di ; terminators jae iit2 ; if end of list lodsw or ax,ax jz iit1 ; if NULL address pushm di,si,ds call ax popm ds,si,di jmp iit1 iit2: ret initterm endp ;; startup ; ; entry AX offset stack ; ES program segment prefix ; SS DGROUP ; exit BP 0 ; may use AX,BX,CX,DX,DI,SI,DS,ES ; startup proc cld movx bp,0 ; BP=0 in TIGHT model mov ax,ss ; compensate for Microsoft LINK bug mov dx,DGROUP ; where SS is wrong segment sub ax,dx jbe sta1 ; if SS is DGROUP, must be OPTLINK mov cl,4 ; else MS-LINK, fix stack pointer shl ax,cl mov ss,dx add sp,ax sta1: mov top_of_stack[bp],sp mov psp[bp],es mov ax,sp ; compute number of paragraphs add ax,15 ; in program mov cl,4 shr ax,cl mov bx,ss add bx,ax sub bx,psp[bp] mov ah,4Ah ; shrink program memory block for call ms_dos ; dynamic storage system mov dgroup_segment[bp],ss mov al,0 ; zero BSS segment mov cx,offset DGROUP:_end movx es,DGROUP_SEGMENT mov di,offset DGROUP:_edata sub cx,di rep stosb call set_argc_argv ; process command line lea di,xiend ; call initializers lea si,xibegin call initterm movx ds,DGROUP_SEGMENT ; call user's program movx es,DGROUP_SEGMENT call main lea di,xpend ; call on-exit routines lea si,xpbegin ; (must call on-exits before call initterm ; terminators!) lea di,xcend ; call terminators lea si,xcbegin call initterm jmp exit_program startup endp end startup