📄 cwl.asm
字号:
;
;Add binary tree type sorting to publics and externs to speed addition and
; searching. Use CARS as a speed test.
;Make DOSSEG work, add command line switch as well.
;Use proper algorythm for LIB searching.
;Stop it writing un-needed data at the end of the program.
;Add a /stub option so can change loaders etc.
;
.386
.model small
.stack 1024
option oldstructs
include ..\cw.inc
include cwl.inc
include ..\strucs.inc
.code
CW_DEBUG_ENTRY_CS_EIP df Main
public CW_DEBUG_ENTRY_CS_EIP
;------------------------------------------------------------------------------
;
;Main entry point.
;
Main proc near
mov ErrorESP,esp ;keep this for un-controled exit.
;
mov esi,offset Copyright ;announce ourselves.
call PrintString
;
;See what's on the command line.
;
call ParseCommandLine
jc System ;Do we understand them?
mov ErrorNumber,1
cmp ObjFiles,0 ;anything specified?
jz System
mov ebp,ObjFiles
cmp d[ebp],0
jz System
;
;Get initial memory for various lists.
;
call InitialGlobalAlloc ;Allocate initial memory for global lists.
jc System
;
;Parse the DEF file.
;
call ParseDefFile
jc System
;
;Do initialisation type stuff.
;
call InitLIBPath ;Setup LIB environment stuff.
jc System
call LoadObjs ;Load all the obj files specified.
jc System
call LoadLibs ;Load all the LIB files specified.
jc System
call GetEXEName ;See if we need a derived EXE file name.
call GetSYMName ;Derive SYM name.
call GetMAPName ;Derive MAP name.
;
call AddInternalPUBDEFs ;Make sure internal PUDEFs are
jc System ;available for WLINK emulation.
;
;Get on with first pass at processing the data.
;
call InitialPassOne ;Deal with specified OBJ's.
jc System
call ResolveEXTDEF ;resolve all EXTDEF's and pull
jc System ;in LIB modules.
;
call SortSEGDEFs ;Sort all the segments into desired order.
jc System
call FindStack ;Find/Create the stack segment.
jc System
call AllocateSegMem ;Work through global segments
jc System ;allocateing memory for them.
;
call SortGROUPs ;Sort the groups.
jc System
call UpdateInternalPUBDEFs ;update internal symbols.
jc System
;
;Update EXPORT values etc.
;
call UpdateEXPORTS
jc System
;
;Now all the modules that are needed should be present so get
;on with the real processing.
;
call ObjPassTwo ;Fill segments & do fixups.
jc System
;
call ApplyGROUPs ;Extend GROUP member limits.
jc System
;
;Time to produce the EXE.
;
call Write3PFile ;Write the output file.
jc System
;
;Lose segment memory to make space for line numbers etc.
;
call ReleaseSegMem
jc System
;
;Now write additional files (MAP/SYM)
;
call WriteMAPFile ;Write the MAP file.
jc System
call WriteSYMFile ;Write the symbols.
jc System
;
mov ErrorNumber,0
jmp System
Main endp
;------------------------------------------------------------------------------
;
;Main exit point.
;
System proc near
mov esp,ErrorESP
cmp ErrorCount,0 ;Any errors yet?
jz @@0
mov esi,offset CarriageReturn
call PrintString
cmp ErrorNumber,0
jnz @@0
mov eax,ErrorCount
mov edi,offset ErrorM32
call Bin2Dec
mov ErrorName,offset ErrorM32_0
mov ErrorNumber,32
@@0: mov eax,ErrorNumber
call PrintError
ret
System endp
;------------------------------------------------------------------------------
;
;Display error message indicated by "ErrorNumber" along with info required for
;particular message. Very crude way of dumping relavent info but...
;
PrintError proc near
pushad
mov esi,ErrorNumber
mov esi,[ErrorList+esi*4]
call PrintString
;
cmp ErrorNumber,3 ;File name needed?
jz @@ShowName
cmp ErrorNumber,4
jz @@ShowName
cmp ErrorNumber,5
jz @@ShowName
cmp ErrorNumber,6
jz @@ShowName
cmp ErrorNumber,7
jz @@ShowName
cmp ErrorNumber,9
jz @@ShowName
cmp ErrorNumber,13
jz @@ShowName
cmp ErrorNumber,15
jz @@ShowName
cmp ErrorNumber,16
jz @@ShowName
cmp ErrorNumber,17
jz @@ShowName
cmp ErrorNumber,18
jz @@ShowName
cmp ErrorNumber,19
jz @@ShowName
cmp ErrorNumber,20
jz @@ShowName
cmp ErrorNumber,22
jz @@ShowName
cmp ErrorNumber,23
jz @@ShowName
cmp ErrorNumber,24
jz @@ShowName
cmp ErrorNumber,26
jz @@ShowName
cmp ErrorNumber,29
jz @@ShowName
cmp ErrorNumber,30
jz @@ShowName
cmp ErrorNumber,32
jz @@ShowName
cmp ErrorNumber,33
jz @@ShowName
cmp ErrorNumber,34
jz @@ShowName
cmp ErrorNumber,35
jz @@ShowName
jmp @@NoName
;
@@ShowName: mov esi,ErrorName
or esi,esi
jnz @@sn0
mov esi,offset NoNameString
@@sn0: call PrintString
;
cmp ErrorNumber,5
jz @@ShowSource
cmp ErrorNumber,6
jz @@ShowSource
cmp ErrorNumber,7
jz @@ShowSource
cmp ErrorNumber,9
jz @@ShowSource
cmp ErrorNumber,13
jz @@ShowSource
cmp ErrorNumber,15
jz @@ShowSource
cmp ErrorNumber,16
jz @@ShowSource
cmp ErrorNumber,17
jz @@ShowSource
cmp ErrorNumber,18
jz @@ShowSource
cmp ErrorNumber,19
jz @@ShowSource
cmp ErrorNumber,20
jz @@ShowSource
cmp ErrorNumber,22
jz @@ShowSource
cmp ErrorNumber,23
jz @@ShowSource
cmp ErrorNumber,26
jz @@ShowSource
cmp ErrorNumber,29
jz @@ShowSource
cmp ErrorNumber,30
jz @@ShowSource
cmp ErrorNumber,33
jz @@ShowSource
cmp ErrorNumber,34
jz @@ShowSource
cmp ErrorNumber,35
jz @@ShowSource
jmp @@NoSource
;
@@ShowSource: cmp ErrorName+4,0
jz @@NoSource
mov esi,offset SpaceString
call PrintString
mov esi,offset ParenOpenString
call PrintString
mov esi,ErrorName+4
call PrintString
mov esi,offset ParenCloseString
call PrintString
@@NoParen1: ;
@@NoSource: cmp ErrorNumber,13
jz @@ShowSymbol
cmp ErrorNumber,15
jz @@ShowSymbol
cmp ErrorNumber,16
jz @@ShowSymbol
cmp ErrorNumber,17
jz @@ShowSymbol
cmp ErrorNumber,18
jz @@ShowSymbol
cmp ErrorNumber,22
jz @@ShowSymbol
cmp ErrorNumber,26
jz @@ShowSymbol
cmp ErrorNumber,29
jz @@ShowSymbol
cmp ErrorNumber,30
jz @@ShowSymbol
cmp ErrorNumber,33
jz @@ShowSymbol
cmp ErrorNumber,34
jz @@ShowSymbol
cmp ErrorNumber,35
jz @@ShowSymbol
jmp @@NoSymbol
;
@@ShowSymbol: cmp ErrorName+8,0
jz @@NoSymbol
mov esi,offset SpaceString
call PrintString
mov esi,ErrorName+8
call PrintString
;
@@NoSymbol: cmp ErrorNumber,29
jz @@NoName
mov esi,offset CarriageReturn
call PrintString
;
@@NoName: inc ErrorCount
mov ErrorNumber,0
mov ErrorName,0
mov ErrorName+4,0
mov ErrorName+8,0
popad
ret
PrintError endp
;------------------------------------------------------------------------------
;
;Work through the EXPORT list setting entry values.
;
UpdateEXPORTS proc near
pushad
;
;Check if there are any EXPORTs to process.
;
mov edi,EXPORTList
mov ebp,[edi]
add edi,4
@@0: or ebp,ebp
jz @@8
pushm edi,ebp
mov edi,[edi]
;
;Work through the list setting values.
;
@@1: mov esi,PUBLICList
mov ebp,[esi]
add esi,4
@@2: or ebp,ebp
jz @@6
mov ebx,[esi] ;point to PUBLIC
cmp PUB.PScope[ebx],0 ;local?
jnz @@5
mov ebx,PUB.PName[ebx] ;point to the name.
movzx ecx,EXPORT.EXP_TextLen[edi]
cmp cl,[ebx] ;right length?
jnz @@5
lea edx,[edi+size EXPORT]
inc ebx
@@3: mov al,[ebx]
mov ah,[edx]
cmp CaseSensitive,0
jnz @@4
call UpperChar
xchg ah,al
call UpperChar
xchg ah,al
@@4: cmp al,ah
jnz @@5
inc ebx
inc edx
dec ecx
jnz @@3
;
;Found the matching PUBLIC so set EXPORT details.
;
mov ebx,[esi]
mov eax,PUB.PValue[ebx]
mov EXPORT.EXP_Offset[edi],eax
mov eax,PUB.PSEG[ebx]
or eax,eax
jnz @@11
;
;Use GROUP index to work out the segment.
;
dec eax
shl eax,2
add eax,4
mov edx,PUB.PObj[ebx]
add eax,Obj.MGroups[edx] ;index to this entry.
mov eax,[eax] ;get global GROUP index.
shl eax,2 ;dword per entry.
add eax,4 ;skip name & count dword.
add eax,GROUPList ;index to this group.
mov eax,[eax] ;point to this group list.
add eax,4+4 ;skip name and count dwords.
mov eax,[eax] ;get base LSEG
;
;Find the target SEGDEF in the local SEGDEF list and fetch
;the base offset.
;
pushm ecx,edi
mov edi,Obj.MSegs[edx] ;point to local SEGDEF's
mov ecx,[edi] ;get number of entries.
add edi,4
@@fl30_0: cmp eax,OSeg.OGSeg[edi] ;right global number?
jz @@fl30_1
add edi,size OSeg
dec ecx
jnz @@fl30_0
jmp @@fl30_2
@@fl30_1: mov ecx,OSeg.OBase[edi] ;get local offset.
add EXPORT.EXP_Offset[edi],ecx
@@fl30_2: popm ecx,edi
jmp @@14
;
;Use SEGDEF index to work out segment.
;
@@11: dec eax
shl eax,4
add eax,4
mov edx,PUB.PObj[ebx]
add eax,Obj.MSegs[edx]
mov edx,OSeg.OBase[eax] ;get local offset.
add EXPORT.EXP_Offset[edi],edx
mov eax,OSeg.OGSeg[eax] ;get global SEGDEF number.
jmp @@14
;
@@14: mov EXPORT.EXP_Seg[edi],ax
jmp @@7
;
;Move to next PUBLIC entry.
;
@@5: add esi,4
dec ebp
jmp @@2
;
;Display a warning about this EXPORT not being found.
;
@@6: mov ErrorNumber,22
mov edi,offset ErrorNameSpace1
mov ErrorName+4,edi
mov eax,DEFLineNumber
call Bin2Dec
call PrintError
;
;Move to next EXPORT entry.
;
@@7: popm edi,ebp
add edi,4
dec ebp
jmp @@0
;
;Make sure this module has a name.
;
@@8: cmp ModuleName,0
jnz @@110
;
;Construct a name from the output file name.
;
mov esi,EXEFiles
mov esi,[esi+4]
;
;Lose any path.
;
mov edi,esi
@@120: inc esi
cmp b[esi-1],0
jz @@130
cmp b[esi-1],"\"
jnz @@120
mov edi,esi
jmp @@120
@@130: ;
;Scan the length.
;
mov esi,edi
xor ecx,ecx
@@140: cmp b[esi],0
jz @@150
cmp b[esi],"."
jz @@150
inc esi
inc ecx
jmp @@140
;
@@150: ;Get some memory for the name.
;
inc ecx
call Malloc
mov ErrorNumber,2
jc @@9
mov ModuleName,esi
xchg esi,edi
dec ecx
mov b[edi],cl
inc edi
rep movsb
;
@@110: clc
jmp @@10
;
@@9_0: popm edi,ebp
@@9: stc
@@10: popad
ret
UpdateEXPORTS endp
;------------------------------------------------------------------------------
;
;Parse DEF file if any specified.
;
ParseDefFile proc near
pushad
cmp DefFiles,0
jz @@8
mov edi,DefFiles
cmp d[edi],0
jz @@8
mov ebp,[edi] ;Get number of files to process.
add edi,4
@@0:
;
;Try and open the file.
;
mov edx,[edi] ;Point to the file name.
mov ErrorName,edx
mov ErrorNumber,3
call OpenFile
jc @@9
;
;Initialise buffered reading for this file.
;
call InitFileBuffer
pushm edi,ebp
;
;Now sit in a loop processing commands.
;
mov DEFLineNumber,0
@@1: mov edi,offset DEFLineBuffer
call ReadBufferLine
mov ErrorNumber,4
jc @@9_0
cmp ecx,-1 ;EOF?
jz @@7
inc DEFLineNumber
or ecx,ecx ;Anything to process?
jz @@1
;
;Check if this is a comment line.
;
cmp b[edi],"#"
jz @@1
;
;Skip white space.
;
@@2: inc edi
cmp b[edi-1]," "
jz @@2
cmp b[edi-1],9
jz @@2
dec edi
;
;See if we understand the command.
;
mov esi,offset DEFCommands
@@3: cmp d[esi],0
jnz @@4
mov esi,edi
mov edi,offset ErrorNameSpace2
mov ErrorName+4,edi
@@3_0: movsb
cmp b[esi-1],0
jz @@3_1
cmp b[esi-1]," "
jz @@3_1
cmp b[esi-1],9
jz @@3_1
jmp @@3_0
@@3_1: mov b[edi-1],0
mov ErrorNumber,7
call PrintError
jmp @@1
;
;See if this is the right command.
;
@@4: mov ebx,[esi] ;point to command string.
push edi
@@5: mov al,[ebx]
call UpperChar
mov ah,al
mov al,[edi]
cmp al," "
jz @@5_0
cmp al,9
jz @@5_0
jmp @@5_1
@@5_0: xor al,al
@@5_1: call UpperChar
cmp al,ah
jnz @@6
or al,al
jz @@11
inc edi
inc ebx
jmp @@5
@@6: pop edi
add esi,4*4
jmp @@3
;
;We have the command so call it's processor.
;
@@11: mov ebx,DEFFiles
mov eax,[ebx]
pushad
call d[esi+4]
popad
pop edi
jc @@9_0
popm edi,ebp
sub edi,ebx
add edi,DEFFiles
mov ebx,DEFFiles
mov ebx,[ebx]
sub ebx,eax
add ebp,ebx
pushm edi,ebp
jmp @@1
;
;Move onto the next DEF file.
;
@@7: popm edi,ebp
add edi,4
dec ebp
jnz @@0
;
@@8: clc
jmp @@10
;
@@9_0: popm edi,ebp
@@9: stc
@@10: popad
ret
ParseDefFile endp
;*******************************************************************************
;
;Process a DEF file INCLUDE command.
;
;On Entry:
;
;EDI - rest of command statement.
;
DEF_IncludeCOM proc near
;
;Skip any remaining white space.
;
@@0: inc edi
cmp b[edi-1]," "
jz @@0
cmp b[edi-1],9
jz @@0
dec edi
;
;Scan the length of the symbol.
;
mov ebx,edi
@@1: cmp b[edi],0
jz @@2
cmp b[edi]," "
jz @@2
cmp b[edi],9
jz @@2
inc edi
jmp @@1
;
;Terminate the name.
;
@@2: mov b[edi],0
;
;Add this entry to the DEF file list.
;
mov edi,ebx
mov esi,offset DEFFiles
call AddFileName2List ;Add this name.
mov ErrorNumber,2
jc @@9
;
@@8: clc
jmp @@10
;
@@9: stc
;
@@10: ret
DEF_IncludeCOM endp
;*******************************************************************************
;
;Process a DEF file NAME command.
;
;On Entry:
;
;EDI - rest of command statement.
;
DEF_NameCOM proc near
push esi
mov esi,edi
call UpperString
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -