cstrtx32.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 525 行 · 第 1/2 页
ASM
525 行
cld ;set direction forward
mov al,' '
sub esp,ecx ;allocate space on stack
lea esp,[esp-256] ;make room for program name
and sp,0fffch ;round down to dword alignment
repe scasb
lea esi,-1[edi]
mov edi,esp ;es:edi is destination
push ds
push es
pop ds ;ds:esi points to command line
pop es
je noparm
inc ecx
rep movsb
noparm: sub al,al
stosb ; store NULLCHAR
push es
pop ds ;restore ds
mov _LpCmdLine,esp ; save command line address
mov _LpPgmName,edi ; save program name address
stosb ; assume no pgm name
lds esi,fword ptr _Envptr ; load pointer to environment
dec edi ; back up pointer 1
push edi ; save pointer to pgm name
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 ; load a zero
inc esi ; point to program name
inc esi ; . . .
;
; copy the program name into top of stack
;
L3: cmp byte ptr [esi],0 ; end of pgm name ?
movsb ; copy a byte
jne L3 ; until end of pgm name
push es
pop ds
pop esi ; restore address of pgm name
mov __no87,bp ; set state of "no87" enironment var
mov ecx,offset DGROUP:_end ; end of _BSS segment (start of STACK)
mov _dynend,ecx ; top of dynamic memory allocation
push ecx
add ecx,0fffh
and cx,0f000h
mov _curbrk,ecx ; current break location
pop ecx
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 ; ...
;set up stack for DGROUP expansion type memory allocation systems
mov ecx,__x32_stack_size
;don't allow smaller than a 4k stack
mov eax,4096
cmp ecx,eax
ja short stack_okay
mov ecx,eax ;use the larger of the two
stack_okay:
mov ax,3509h
mov ebx,esp
mov esi,_curbrk ;curbrk will be adjusted if required
int 21h
jc insuf_mem
mov _curbrk,esi ;current break point
mov esp,ebx ;switch to new stack if required
mov _STACKLOW,edx ;lower limit for stack
mov _STACKTOP,esp ; set stack top
xor eax,eax
mov fs,ax
mov gs,ax ;makes reloading segs faster
mov eax,0FFH ; run all initalizers
call __InitRtns ; call initializer routines
mov eax,_LpCmdLine ; cmd buffer pointed at by EAX
sub ebp,ebp ; ebp=0 indicate end of ebp chain
call __CMain
__x386_init endp
insuf_mem:
mov edx,offset DGROUP:insuf_msg
exit_msg: ;InitRtns hasn't been called yet so don't call FiniRtns
mov ah,9
int 21h
mov ax,4c01h
int 21h
null_error: ;a null code pointer has been called
push ebp
mov ebp,esp
mov eax,offset DGROUP:null_msg
mov dl,1 ;error code
; input: EAX - pointer to message to print
; EDX - exit code
__do_exit_with_msg__:
push edx ; save return code
push eax ; save address of msg
mov edx,offset DGROUP: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
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 ; . . .
ifndef __STACK__
pop eax ; restore return code
endif
; don't touch AL in __exit, it has the return code
__exit proc near
ifndef __STACK__
push eax ; save return code
endif
mov eax,00H ; run finalizers
mov edx,0FH ; less than exit
call __FiniRtns ; call finializer routines
pop eax ; restore return code
mov ah,4cH ; DOS call to exit with return code
int 021h ; back to DOS
__exit endp
public __GETDS
__GETDS proc near
public "C",__GETDSStart_
__GETDSStart_ label byte
mov ds,cs:__saved_DS ; load saved DS value
ret ; return
public "C",__GETDSEnd_
__GETDSEnd_ label byte
__GETDS endp
sbrk proc near
comment&
The amount of memory requested is passed in register eax. We will not
assume at this time that the amount is page granular but we will
always allocate page granular quantities anyway.
&
ifdef __STACK__
mov eax,ss:[esp]
endif
add eax,_curbrk
jnc sbrk_enter
jmp brk_c
sbrk endp
comment&
This is called when it is desired to expand the data segment. The
parameter passed in eax is the requested new top of the data segment.
_curbrk and x386_break are updated.
&
__brk proc near
ifdef __STACK__
mov eax,ss:[esp+4]
endif
sbrk_enter:
cmp eax,__x386_break
jbe short brk_a ;jmp if no action required
push ecx
push eax
mov ecx,eax
mov ax,3508h
int 21h ;expand DGROUP block
jc short brk_b
;eax is the new lowest legal value for esp, ecx is the actual break value.
mov _STACKLOW,eax
mov __x386_break,ecx
pop eax
pop ecx
brk_a:
xchg eax,_curbrk
clc ; indicate success
ret
brk_b: ;insufficient memory
pop ecx ;pop and discard original eax
pop ecx ;restore original ecx
brk_c:
mov eax,-1
stc ; indicate allocation failure
ret
__brk endp
;
; __Int21 interface to OS int 21h translator
;
public __Int21_
public __fInt21_
__fInt21_ proc far
call __Int21_
ret
__fInt21_ endp
__Int21_ proc near
cmp AH,48h ; allocate memory?
je short AllocMem ; branch if yes
cmp AH,4Eh ; DOS Find First?
je short FindFirst ; branch if yes
cmp AH,4Fh ; DOS Find Next?
je short FindNext ; branch if yes
int 21h ; issue int 21
ret ; return
AllocMem:
mov eax,ebx ; get length to allocate
call sbrk ; allocate it
ret ; return
FindFirst:
push EDX ; save filename address
mov EDX,EBX ; get DTA address
mov AH,1Ah ; set DTA address
int 21h ; ...
pop EDX ; restore filename address
mov AH,4Eh ; find first
int 21h ; ...
ret ; return
FindNext:
cmp AL,0 ; if not FIND NEXT
jne short findret ; then return
push EDX ; save EDX
mov AH,1Ah ; set DTA address
int 21h ; ...
mov AH,4Fh ; find next
int 21h ; ...
pop EDX ; restore EDX
findret:ret ; return
__Int21_ endp
_TEXT ends
end _cstart_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?