📄 cwl.asm
字号:
;
;On Exit:
;
;Carry set on error else,
;
;nothing.
;
AppendToGlobalGROUP proc near
pushad
pushad
;
;Check if we already have this value.
;
mov edi,GROUPList
mov esi,[edi+4+eax*4] ;Point to this entry.
mov ecx,[esi+4] ;Get current entries.
add esi,4+4
@@0: or ecx,ecx
jz @@1
cmp ebp,[esi]
jz @@2
add esi,4
dec ecx
jmp @@0
@@1: clc
jmp @@3
@@2: stc
@@3: popad
jc @@8
mov edi,GROUPList
mov esi,[edi+4+eax*4] ;Point to this entry.
mov ecx,[esi+4] ;Get current entries.
inc ecx
shl ecx,2 ;dword per entry.
add ecx,4+4 ;include header.
call ReMalloc
jc @@9
mov [edi+4+eax*4],esi ;store new address.
mov eax,[esi+4] ;Get current count.
inc d[esi+4] ;Update count.
mov [esi+4+4+eax*4],ebp ;store new value.
@@8: clc
@@9: popad
ret
AppendToGlobalGROUP endp
;------------------------------------------------------------------------------
;
;Find a global SEGDEF that matches input.
;
;On Entry:
;
;EAX - Segment name index (LNAME).
;
;On Exit:
;
;Carry set if not found else,
;
;EAX - SEGDEF list index.
;EBP - Pointer to SEGDEF entry.
;
FindGlobalSEGDEF proc near
pushm ebx,ecx,edx,esi,edi
cmp SEGDEFList,0 ;Got any SEGDEF's yet?
jz @@8
mov esi,SEGDEFList
mov ecx,[esi] ;Get number of entries.
or ecx,ecx
jz @@8 ;No entries yet.
add esi,4
xor edx,edx ;Reset index number.
@@0: mov edi,[esi] ;Point to this SEGDEF.
cmp eax,LSeg.SName[edi] ;Right name index?
jz @@1
add esi,4
inc edx
dec ecx
jnz @@0
jmp @@8
;
@@1: mov eax,edx ;Get SEGDEF index.
mov ebp,edi ;Get SEGDEF pointer.
;
clc
jmp @@9
@@8: stc
@@9: popm ebx,ecx,edx,esi,edi
ret
FindGlobalSEGDEF endp
;------------------------------------------------------------------------------
;
;Add a global SEGDEF to the list.
;
;On Entry:
;
;nothing.
;
;On Exit:
;
;Carry set on error else,
;
;EAX - SEGDEF list index.
;EBP - Pointer to blank SEGDEF entry.
;
AddGlobalSEGDEF proc near
pushm ebx,ecx,edx,esi,edi
mov ecx,size LSeg ;Need memory for actual SEGDEF
call Malloc ;details.
jc @@8
push eax
mov edi,esi
xor al,al
rep stosb ;Clear it all to nothing.
pop eax
mov edi,esi
;
ExpandList SEGDEFList,ListBumpG
jnc @@1
mov esi,edi ;Have to free SEGDEF memory to
call Free ;keep things clean.
jmp @@8
;
@@1: mov esi,SEGDEFList ;Get new list address.
mov eax,[esi] ;Get new entries index number.
inc d[esi]
mov ebp,edi ;Set pointer to LSEG.
mov [esi+4+eax*4],edi ;store new SEGDEF in the list.
;
clc
jmp @@9
@@8: stc
@@9: popm ebx,ecx,edx,esi,edi
ret
AddGlobalSEGDEF endp
;------------------------------------------------------------------------------
;
;Search global LNAME list for specified name.
;
;On Entry:
;
;ESI - Name string includeing length byte.
;
;On Exit:
;
;Carry set if not found else,
;
;EAX - LNAME list index.
;
;All other registers preserved.
;
FindGlobalLNAME proc near
pushm ecx,edx,edi,ebp
mov ebp,LNAMEList
mov ecx,[ebp] ;get number of entries.
or ecx,ecx
jz @@9
add ebp,4
xor edx,edx
@@0: mov edi,[ebp]
movzx eax,b[edi] ;get length of string.
cmp al,[esi] ;check against target.
jnz @@3
or eax,eax ;weed out zero length names.
jz @@4
pushm eax,ecx,esi
inc esi ;skip length bytes.
inc edi
mov ecx,eax ;get length to compare.
;
@@1: ;Case insensitive comparison.
;
mov al,[esi]
call UpperChar
mov ah,al
mov al,[edi]
call UpperChar
cmp al,ah
jnz @@2
inc esi
inc edi
dec ecx
jnz @@1
;
@@2: popm eax,ecx,esi
jz @@4
;
@@3: add ebp,4 ;move to next entry.
inc edx ;update index counter.
dec ecx
jnz @@0 ;keep going till we run out.
jmp @@9
;
@@4: mov eax,edx ;get entry number.
clc
jmp @@10
;
@@9: stc
@@10: popm ecx,edx,edi,ebp
ret
FindGlobalLNAME endp
;------------------------------------------------------------------------------
;
;Add an entry to the global LNAME list.
;
;On Entry:
;
;ESI - Name string includeing length byte.
;
;On Exit:
;
;Carry set on error else,
;
;EAX - LNAME list index.
;
;All other registers preserved.
;
AddGlobalLNAME proc near
pushm ecx,edi
ExpandList LNAMEList,ListBumpG
;
mov edi,LNAMEList
mov ecx,[edi]
inc d[edi] ;update entry counter.
mov [edi+4+ecx*4],esi ;store LNAME pointer.
;
mov eax,ecx
clc
jmp @@10
;
@@9: stc
@@10: popm ecx,edi
ret
AddGlobalLNAME endp
;------------------------------------------------------------------------------
;
;Allocate memory for empty global lists.
;
;On Entry:
;
;nothing.
;
;On Exit:
;
;Carry set on error else,
;
;All registers preserved.
;
InitialGlobalAlloc proc near
pushad
mov ErrorNumber,2
xor eax,eax
mov ecx,4+(ListBumpG*4)
;
call Malloc
jc @@9
mov d[esi],eax
mov ObjList,esi
call Malloc
jc @@9
mov d[esi],eax
mov LibList,esi
call Malloc
jc @@9
mov d[esi],eax
mov LNAMEList,esi
call Malloc
jc @@9
mov d[esi],eax
mov SEGDEFList,esi
call Malloc
jc @@9
mov d[esi],eax
mov GROUPList,esi
call Malloc
jc @@9
mov d[esi],eax
mov PUBLICList,esi
call Malloc
jc @@9
mov d[esi],eax
mov EXTDEFList,esi
call Malloc
jc @@9
mov d[esi],eax
mov RelocationList,esi
call Malloc
jc @@9
mov d[esi],eax
mov IRelocationList,esi
call Malloc
jc @@9
mov d[esi],eax
mov LINEList,esi
call Malloc
jc @@9
mov d[esi],eax
mov LINNUMList,esi
call Malloc
jc @@9
mov d[esi],eax
mov EXPORTList,esi
call Malloc
jc @@9
mov d[esi],eax
mov IMPORTList,esi
call Malloc
jc @@9
mov d[esi],eax
mov IMPORTModules,esi
call Malloc
jc @@9
mov d[esi],eax
mov IMPORTNames,esi
;
clc
jmp @@10
@@9: stc
@@10: popad
ret
InitialGlobalAlloc endp
;------------------------------------------------------------------------------
;
;Find matching PUBDEF entries for all EXTDEF entries. If not already present
;then search LIB files for a module that declares it. If another module is
;used then add it to the list and call ObjPassOne to register it's symbols etc
;before carrying on with the others. New modules will always be added to the
;end of the list so we can be sure of seeing them.
;
;On Entry:
;
;nothing.
;
;On Exit:
;
;Carry set on error else,
;
;All registers preserved.
;
ResolveEXTDEF proc near
pushad
mov edi,EXTDEFList
mov ebp,[edi] ;get number of entries.
or ebp,ebp
jz @@8
add edi,4
@@0: pushm edi,ebp
mov edi,[edi]
mov eax,EXT.EScope[edi]
mov EXTSearchScope,eax
mov eax,EXT.EObj[edi]
mov EXTSearchObj,eax
mov edi,EXT.EName[edi] ;point to the name.
;
;See if this symbol figures in the IMPORT list.
;
cmp EXTSearchScope,0 ;must not be a local EXTERN
jnz @@i9 ;for an IMPORT match.
mov esi,IMPORTList
mov ebp,[esi]
add esi,4
@@i0: or ebp,ebp ;end of the list?
jz @@i9
pushm esi,edi
mov esi,[esi] ;point to IMPORT
mov esi,IMPORT.IMP_IName[esi] ;point to IMPORT internal name string.
xor ecx,ecx
mov cl,[esi]
cmp cl,[edi] ;right length?
jnz @@i3
inc esi
inc edi
@@i1: mov al,[esi]
mov ah,[edi]
cmp CaseSensitive,0
jnz @@i2
call UpperChar
xchg ah,al
call UpperChar
xchg ah,al
@@i2: cmp al,ah
jnz @@i3
inc esi
inc edi
dec ecx
jnz @@i1
;
;Matching IMPORT so update this EXTERN.
;
popm esi,edi
popm edi,ebp
pushm edi,ebp
mov edi,[edi]
mov eax,[esi]
mov EXT.EPub[edi],eax ;save pointer to IMPORT
or EXT.EFlags[edi],1 ;mark it as an IMPORT
jmp @@4
;
;Move to next IMPORT entry.
;
@@i3: popm esi,edi
add esi,4
dec ebp
jmp @@i0
;
;Scan the PUBLIC list.
;
@@i9: mov esi,PUBLICList
mov ebp,[esi]
or ebp,ebp
jz @@5
add esi,4
@@1: pushm esi,edi
mov esi,[esi]
;
;Check if this is a local and if current PUBDEF is same.
;
mov LocalCaseSensitive,0
cmp EXTSearchScope,0
jz @@1_1
cmp PUB.PScope[esi],0
jz @@3
mov eax,PUB.PObj[esi]
cmp eax,EXTSearchObj
jnz @@3
or LocalCaseSensitive,-1
jmp @@1_0
;
@@1_1: cmp PUB.PScope[esi],0
jz @@1_0
cmp EXTSearchScope,0
jz @@3
mov eax,PUB.PObj[esi]
cmp eax,EXTSearchObj
jnz @@3
or LocalCaseSensitive,-1
;
@@1_0: mov esi,PUB.PName[esi]
xor ecx,ecx
mov cl,[edi]
cmp cl,[esi] ;Correct length?
jnz @@3
inc edi
inc esi
@@2: mov al,[esi]
mov ah,[edi]
cmp CaseSensitive,0
jnz @@2_0
cmp LocalCaseSensitive,0
jnz @@2_0
call UpperChar
xchg al,ah
call UpperChar
@@2_0: cmp al,ah
jnz @@3
inc esi
inc edi
dec ecx
jnz @@2
;
;We have a match.
;
popm esi,edi
mov eax,esi
popm edi,ebp
pushm edi,ebp
mov edi,[edi]
mov eax,[eax]
mov EXT.EPub[edi],eax ;save pointer to public.
or PUB.PFlags[eax],1 ;flag public used.
jmp @@4
@@3: popm esi,edi
add esi,4
dec ebp
jnz @@1
;
@@5: ;We need to scan the LIB files to see if anything there can
;resolve this symbol. Should be useing some fancy search
;algorythm but we'll stick with a serial search until speed
;becomes a problem.
;
popm edi,ebp
pushm edi,ebp
mov edi,[edi] ;Point to EXTDEF entry.
mov edi,EXT.EName[edi] ;/
mov esi,LibList
mov ebp,[esi] ;Get number of entries.
add esi,4
or ebp,ebp ;just incase
jz @@l9
@@l0: pushm esi,ebp
mov esi,Lib.LAddress[esi] ;Point to LIB.
movzx ecx,w[esi+7] ;Get number of directory pages.
add esi,[esi+3] ;Get directory offset.
@@l1: pushm ecx,esi
mov ecx,37 ;Maximum entries to look at.
mov edx,esi
@@l2: pushm ecx,esi
movzx eax,b[esi] ;Get public offset
or eax,eax
jz @@l5 ;nothing to look at.
shl eax,1
mov esi,edx
add esi,eax ;Point to public
xor eax,eax
mov al,[esi]
cmp al,[edi] ;Right length?
jnz @@l5
pushm ecx,edi
mov ecx,eax
inc edi
inc esi
@@l3: mov al,[esi]
mov ah,[edi]
cmp CaseSensitive,0
jnz @@l3_0
call UpperChar
xchg ah,al
call UpperChar
@@l3_0: cmp al,ah
jnz @@l4
inc esi
inc edi
dec ecx
jnz @@l3
;
;We found a match.
;
movzx eax,w[esi] ;Get the page number for this module.
popm ecx,edi
popm ecx,esi
popm ecx,esi
popm esi,ebp
mov edx,Lib.LAddress[esi] ;Point to LIB.
movzx edx,w[edx+1] ;Get page length.
add edx,3
mul edx ;Get offset to this OBJ.
add eax,Lib.LAddress[esi]
mov ecx,Lib.LAddress[esi]
add ecx,Lib.LLength[esi]
sub ecx,eax ;Set maximum length.
push edx
lea edx,Lib.LName[esi]
mov esi,eax
call AddObjModule ;add this module to the list.
pop edx
jc @@l99
mov edi,ObjList
mov eax,[edi] ;get number of entries.
dec eax ;Don't count this entry.
lea edi,[edi+4+eax*4]
mov edi,[edi] ;point to new entry.
mov eax,EXTDEFList
mov EXTDEFList+4,eax
mov eax,[eax] ;Get number of entries.
mov EXTDEFList+8,eax
call ObjPassOne ;Extract PUBDEF's and EXTDEF's etc.
jc @@l99
popm edi,ebp
sub edi,EXTDEFList+4
add edi,EXTDEFList
mov eax,EXTDEFList
mov eax,[eax] ;Get number of entries now.
sub eax,EXTDEFList+8 ;Get number of new entries.
add ebp,eax ;Make sure they get seen.
jmp @@0 ;Start again for this entry.
;
@@l4: popm ecx,edi
@@l5: popm ecx,esi
inc esi
dec ecx
jnz @@l2
popm ecx,esi
add esi,512
dec ecx
jnz @@l1
popm esi,ebp
add esi,size Lib
dec ebp
jnz @@l0
;
;Didn't find anything so print a warning.
;
@@l9: mov ErrorNumber,26
mov ErrorName,0
mov ErrorName+4,0
pushm ecx,esi,edi
mov esi,edi
mov edi,offset ErrorNameSpace3
mov ErrorName+8,edi
movzx ecx,b[esi]
inc esi
rep movsb
mov b[edi],0
popm ecx,esi,edi
popm edi,ebp
pushm edi,ebp
pushad
mov edi,[edi] ;Point to EXTDEF entry.
mov esi,EXT.EObj[edi] ;/
push esi
mov esi,Obj.MFileName[esi]
mov ErrorName,esi
pop esi
mov esi,Obj.MName[esi]
or esi,esi
jz @@NoSName
movzx ecx,b[esi]
inc esi
push edi
mov edi,offset ErrorNameSpace2
mov ErrorName+4,edi
rep movsb
mov b[edi],0
pop edi
@@NoSName: ;
mov EXT.EPub[edi],offset DummyPUB ;point to PUBDEF that fits.
;
call PrintError
popad
jmp @@4
;
@@l99: popm edi,ebp
jmp @@9
;
@@4: popm edi,ebp
add edi,4
dec ebp
jnz @@0
;
@@8: clc
jmp @@10
@@9: stc
@@10: popad
ret
ResolveEXTDEF endp
;------------------------------------------------------------------------------
;
;Parse the command line for object file names etc.
;
;On Entry:
;
;nothing.
;
;On Exit:
;
;All registers preserved.
;
ParseCommandLine proc near
push fs
pushad
;
;Get PSP pointer so we can parse things.
;
mov ah,51h ;Get current PSP address so we
int 21h ;can find the environment strings.
mov fs,bx
mov esi,80h
movzx ecx,fs:b[esi] ;Get line length.
inc esi
mov fs:b[esi+ecx],0 ;Terminate the line.
;
;Allocate a new block of memory for the command line.
;
pushm ecx,esi
inc ecx
add ecx,4
call Malloc
mov edi,esi
popm ecx,esi
mov ErrorNumber,2
jc @@9
;
;Copy current command line into new memory.
;
pushm ecx,edi
add edi,4
pushm ds,fs
pop ds
rep movsb
pop ds
popm ecx,edi
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -