📄 cwl.asm
字号:
lea ebx,[ebx+4+eax*4]
mov ebx,[ebx]
xor eax,eax
mov al,ObjPassOneType
and al,not 1 ;lose size bit.
cmp al,LEXTDEF
mov al,-1
jz @@0
xor al,al
@@0: mov EXT.EScope[ebx],eax ;store scope.
mov EXT.EObj[ebx],edi
;
;Skip name.
;
movzx eax,b[esi]
inc eax
add esi,eax
sub edx,eax
;
;Skip the type index.
;
GetIndex
;
jmp @@ed0
;
@@ed9: inc esi
xor edx,edx
jmp ObjPassOneNext
ObjPassOne_EXTDEF endp
;------------------------------------------------------------------------------
;
;Process LNAMES list.
;
ObjPassOne_LNAMES proc near
dec edx ;allow for check sum.
@@l0: call FindGlobalLNAME ;Find this LNAME if it exists.
jnc @@l1
call AddGlobalLNAME ;Add a new LNAME.
mov ErrorNumber,2
jc ObjPassOneError
@@l1: ExpandList Obj.MLNAMES[edi],ListBumpL
mov ErrorNumber,2
jc ObjPassOneError
push esi
mov esi,Obj.MLNAMES[edi]
mov ecx,[esi]
inc d[esi] ;update count.
mov [esi+4+ecx*4],eax ;store new LNAME index.
pop esi
;
movzx eax,b[esi] ;Get length.
inc eax
add esi,eax
sub edx,eax
;
or edx,edx ;end of the list?
jnz @@l0
;
inc esi
xor edx,edx
jmp ObjPassOneNext
ObjPassOne_LNAMES endp
;------------------------------------------------------------------------------
;
;Process segment definition.
;
ObjPassOne_SEGDEF proc near
cmp PharLapFlag,0
jz @@s2
mov ObjPassOneType,SEGDEFL
@@s2: ;
pushm esi,edx
add esi,3
cmp ObjPassOneType,SEGDEFL
jnz @@s0
add esi,2
@@s0: GetIndex
popm esi,edx
dec eax ;make it relative to zero.
shl eax,2 ;dword per entry.
add eax,4 ;skip dword count field.
add eax,Obj.MLnames[edi] ;index into local list.
mov eax,[eax] ;Get global name index.
;
call FindGlobalSEGDEF ;See if we already have this segment.
jnc @@s1
mov ErrorNumber,2
call AddGlobalSEGDEF ;Add a new entry, details to be filled in later.
jc ObjPassOneError
@@s1: mov edx,Obj.MSegs[edi] ;Point to SEGDEF list.
;
;Really aught to be checking that the new segments type matches
;the existing segments type if this isn't first definition but
;we don't bother for now.
;
push esi
mov esi,edx ;Need to make space for another
mov ecx,[esi] ;entry.
inc ecx
shl ecx,4
add ecx,4 ;Include entry count dword.
call ReMalloc
mov edx,esi
pop esi
mov ErrorNumber,2
jc ObjPassOneError
mov Obj.MSegs[edi],edx ;Set SEGDEF pointer again.
mov ebx,[edx]
inc d[edx] ;update number of entries.
shl ebx,4
add edx,4 ;Skip entry count.
add edx,ebx ;Point to new entry.
mov OSeg.OGSeg[edx],eax ;Store global segdef index.
mov OSeg.OLength[edx],0 ;Clear length.
;
;EAX - global SEGDEF index.
;ESI - SEGDEF details.
;EDI - Module details.
;EDX - module SEGDEF entry.
;EBP - global SEGDEF entry.
;ECX - Module length remaining.
;
mov al,[esi]
and al,11100000b
shr al,5
mov LSeg.SAlign[ebp],al ;Set align type.
mov al,[esi]
and al,00011100b
shr al,2
mov LSeg.SCombine[ebp],al ;Set combine type.
mov al,[esi]
and al,00000010b
shr al,1
mov LSeg.SBig[ebp],al ;Set BIG flag.
mov al,[esi]
and al,00000001b
cmp ObjPassOneType,SEGDEFL
jnz @@NoForceP
or al,1
@@NoForceP: mov LSeg.SPage[ebp],al ;Set PAGE flag.
inc esi
;
;Get base position and align it.
;
movzx eax,LSeg.SAlign[ebp] ;Get align type again.
mov ErrorNumber,23
or eax,eax
jz @@BadAlignType
mov ErrorNumber,23
cmp eax,5+1
jnc @@BadAlignType
mov ebx,LSeg.SPosition[ebp] ;get base position.
add ebx,[SEGDEFAlignTable+0+eax*8]
and ebx,[SEGDEFAlignTable+4+eax*8]
mov OSeg.OBase[edx],ebx ;Set local to global base offset.
xchg LSeg.SPosition[ebp],ebx ;set base position.
sub ebx,LSeg.SPosition[ebp]
neg ebx
add LSeg.SLength[ebp],ebx ;update global segments length with align gap.
;
movzx eax,w[esi] ;Get length.
add esi,2
cmp ObjPassOneType,SEGDEFL
jnz @@s6
rol eax,16
mov ax,w[esi] ;Get length +2
rol eax,16
add esi,2
;
@@s6: add LSeg.SLength[ebp],eax
mov OSeg.OLength[edx],eax
add LSeg.SPosition[ebp],eax ;Update base position.
;
GetIndex
dec eax ;make it relative to 0.
shl eax,2 ;dword per entry.
add eax,4 ;skip dword count field.
add eax,Obj.MLnames[edi] ;index into local list.
mov eax,[eax] ;Get global name index.
mov LSeg.SName[ebp],eax ;Store name index.
;
GetIndex
dec eax ;make it relative to zero.
shl eax,2 ;dword per entry.
add eax,4 ;skip dword count field.
add eax,Obj.MLnames[edi] ;index into local list.
mov eax,[eax] ;Get global name index.
mov LSeg.SClass[ebp],eax ;Store class index.
;
pushad
mov edx,eax
shl edx,2
add edx,4 ;Skip count dword.
add edx,LNAMEList
mov edx,[edx] ;Point to class text.
;
;Check for CODE
;
cmp b[edx],4 ;needs at least 4 characters.
jc @@scf0
mov esi,edx
inc esi
mov al,[esi]
inc esi
call UpperChar
shl eax,8
mov al,[esi]
inc esi
call UpperChar
shl eax,8
mov al,[esi]
inc esi
call UpperChar
shl eax,8
mov al,[esi]
inc esi
call UpperChar
cmp eax,"CODE"
jnz @@scf0
or LSeg.SFlags[ebp],1 ;set code bit.
jmp @@scf1
;
;Check for STACK
;
@@scf0: cmp b[edx],5 ;needs at least 5 characters.
jc @@scf1
mov esi,edx
inc esi
mov al,[esi]
inc esi
call UpperChar
shl eax,8
mov al,[esi]
inc esi
call UpperChar
shl eax,8
mov al,[esi]
inc esi
call UpperChar
shl eax,8
mov al,[esi]
inc esi
call UpperChar
cmp eax,"STAC"
jnz @@scf1
mov al,[esi]
call UpperChar
cmp al,"K"
jnz @@scf1
or LSeg.SFlags[ebp],2 ;set stack bit.
;
@@scf1: popad
;
GetIndex
dec eax ;make it relative to zero.
shl eax,2 ;dword per entry.
add eax,4 ;skip dword count field.
add eax,Obj.MLnames[edi] ;index into local list.
mov eax,[eax] ;Get global name index.
mov LSeg.SOverlay[ebp],eax ;Store overlay name index.
;
inc esi ;skip checksum.
xor edx,edx
jmp ObjPassOneNext
;
;Display error message about align type.
;
@@BadAlignType:
pushad
mov eax,Obj.MFileName[edi]
mov ErrorName,eax
mov esi,Obj.MName[edi]
or esi,esi
jz @@brc0
movzx ecx,b[esi]
inc esi
mov edi,offset ErrorNameSpace2
mov ErrorName+4,edi
rep movsb
mov b[edi],0
@@brc0: popad
jmp ObjPassOneError
ObjPassOne_SEGDEF endp
;------------------------------------------------------------------------------
;
;Process group definition.
;
ObjPassOne_GRPDEF proc near
dec edx ;Allow for checksum at the end.
;
GetIndex
dec eax ;make it relative to zero.
shl eax,2 ;dword per entry.
add eax,4 ;skip dword count field.
add eax,Obj.MLnames[edi] ;index into local list.
mov eax,[eax] ;Get global name index.
call FindGlobalGROUP
jnc @@g1
call AddGlobalGROUP
mov ErrorNumber,2
jc ObjPassOneError
;
@@g1: mov ebp,Obj.MGROUPS[edi] ;Get local GROUP pointer.
push esi
mov esi,ebp
mov ecx,[esi] ;Get number of entries.
inc ecx ;Include new entry.
shl ecx,2 ;dword per entry.
add ecx,4 ;include count dword.
call ReMalloc ;Get more memory.
mov ebp,esi
pop esi
mov ErrorNumber,2
jc ObjPassOneError
mov Obj.MGROUPS[edi],ebp ;Set new GROUP pointer.
;
push eax
mov eax,[ebp] ;Get current count.
inc d[ebp] ;Update the count.
add ebp,4 ;skip count dword.
shl eax,2 ;dword per entry.
add ebp,eax ;point to this entry.
pop eax
mov [ebp],eax ;store GROUP list index number.
;
@@g3: or edx,edx ;Done all entries?
jz @@g4
movzx ebp,w[esi] ;Get segment type/index.
sub edx,2
add esi,2
shr ebp,8
dec ebp ;make it relative to zero.
shl ebp,4 ;16 bytes per entry.
add ebp,4 ;skip count dword.
add ebp,Obj.MSegs[edi] ;index to this translation entry.
mov ebp,OSeg.OGSeg[ebp] ;get global SEGDEF number.
call AppendToGlobalGROUP ;Add this entry to the GROUP.
mov ErrorNumber,2
jc ObjPassOneError
jmp @@g3
;
@@g4: inc esi
xor edx,edx
jmp ObjPassOneNext
ObjPassOne_GRPDEF endp
;------------------------------------------------------------------------------
;
;Deal with a MODEND record.
;
ObjPassOne_MODEND proc near
jmp ObjPassOneOK
ObjPassOne_MODEND endp
;------------------------------------------------------------------------------
;
;Show details of an invalid (un-recognised) object record type.
;
;On Entry:
;
;ESI - Record
;EDI - Obj structure.
;
;On Exit:
;
;nothing.
;
ShowInvalidObjRecType proc near
mov edi,offset ErrorM19_N
mov ecx,2
call Bin2Hex
mov ErrorNumber,19
;
cmp Obj.MName[edi],0
jz @@9
mov esi,Obj.MName[edi]
mov edi,offset SYMSpace
movzx ecx,b[esi]
inc esi
rep movsb
mov al," "
stosb
xor al,al
stosb
@@9: ret
ShowInvalidObjRecType endp
;------------------------------------------------------------------------------
;
;Search current PUBDEF list for this name.
;
;On Entry:
;
;ESI - Name to find.
;
;On Exit:
;
;Carry set on error else,
;
;EAX - Global list index.
;
;All other registers preserved.
;
FindGlobalPUBDEF proc near
pushad
mov edx,PUBLICList
mov ebp,[edx] ;Get number of entries.
add edx,4
xor ebx,ebx ;reset index number.
@@0: or ebp,ebp ;Anything left?
jz @@9
mov edi,[edx] ;point to this PUBDEF
;
mov LocalCaseSensitive,0
cmp PUBDEFScope,0
jz @@6
or LocalCaseSensitive,-1
mov eax,PUB.PObj[edi]
cmp eax,PUBDEFObj
jnz @@4
;
@@6: cmp PUB.PScope[edi],0
jz @@5
or LocalCaseSensitive,-1
mov eax,PUB.PObj[edi]
cmp eax,PUBDEFObj
jnz @@4
;
@@5: mov edi,PUB.PName[edi] ;point to name.
xor ecx,ecx
mov cl,[edi] ;Get the length.
cmp cl,[esi] ;right length?
jnz @@4
push esi
inc esi
inc edi
@@1: mov al,[esi]
mov ah,[edi]
inc esi
inc edi
cmp CaseSensitive,0
jnz @@2
cmp LocalCaseSensitive,0
jnz @@2
call UpperChar
xchg ah,al
call UpperChar
@@2: cmp al,ah
jnz @@3
dec ecx
jnz @@1
;
;We found a match.
;
pop esi
mov [esp+28],ebx ;store index.
clc
jmp @@10
;
@@3: pop esi
@@4: add edx,4 ;point to next entry.
inc ebx ;update index.
dec ebp
jmp @@0
;
@@9: stc
@@10: popad
ret
FindGlobalPUBDEF endp
;------------------------------------------------------------------------------
;
;Search current EXTDEF list for this name.
;
;On Entry:
;
;ESI - Name to find.
;
;On Exit:
;
;Carry set on error else,
;
;EAX - Global list index.
;
;All other registers preserved.
;
FindGlobalEXTDEF proc near
pushad
mov edx,EXTDEFList
mov ebp,[edx] ;Get number of entries.
add edx,4
xor ebx,ebx ;reset index number.
@@0: or ebp,ebp ;Anything left?
jz @@9
mov edi,[edx] ;point to this EXTDEF.
xor ecx,ecx
mov cl,[edi] ;Get the length.
cmp cl,[esi] ;right length?
jnz @@4
push esi
inc esi
inc edi
@@1: mov al,[esi]
mov ah,[edi]
inc esi
inc edi
cmp CaseSensitive,0
jnz @@2
call UpperChar
xchg ah,al
call UpperChar
@@2: cmp al,ah
jnz @@3
dec ecx
jnz @@1
;
;We found a match.
;
pop esi
mov [esp+28],ebx ;store index.
clc
jmp @@10
;
@@3: pop esi
@@4: add edx,4 ;point to next entry.
inc ebx ;update index.
dec ebp
jmp @@0
;
@@9: stc
@@10: popad
ret
FindGlobalEXTDEF endp
;------------------------------------------------------------------------------
;
;Add an entry to the global EXTDEF list.
;
;On Entry:
;
;ESI - Name.
;
;On Exit:
;
;Carry set on error else,
;
;EAX - Name index.
;
;All other registers preserved.
;
AddGlobalEXTDEF proc near
pushad
ExpandList EXTDEFList,ListBumpG ;grow the list.
jc @@9
push esi
mov ecx,size EXT
call Malloc
mov edx,esi
pop esi
jc @@9
mov edi,edx
mov ecx,size EXT
xor al,al
rep stosb
mov edi,EXTDEFList
mov eax,[edi]
inc d[edi]
mov [edi+4+eax*4],edx ;store EXT pointer.
mov [esp+28],eax ;store index.
;
mov EXT.EName[edx],esi ;store name pointer.
clc
jmp @@10
;
@@9: stc
@@10: popad
ret
AddGlobalEXTDEF endp
;------------------------------------------------------------------------------
;
;Find a GROUP in the global list.
;
;On Entry:
;
;EAX - GROUP name LNAME index.
;
;On Exit:
;
;Carry set if not found else,
;
;EAX - GROUP list index.
;
FindGlobalGROUP proc near
pushm ebx,ecx,edx,esi,edi,ebp
cmp GROUPList,0 ;Got a list yet?
jz @@8
mov esi,GROUPList ;Point to the list.
mov ecx,[esi] ;Get number of entries.
add esi,4 ;Skip count dword.
or ecx,ecx ;Any entries left?
jz @@8
xor edx,edx
@@0: mov edi,[esi] ;Point to GROUP entry.
cmp eax,[edi] ;Right LNAME index?
jz @@1
add esi,4 ;Move to next entry.
inc edx ;Update index number.
dec ecx
jnz @@0
jmp @@8 ;Didn't find it.
;
@@1: mov eax,edx ;Get the index number.
clc
jmp @@9
@@8: stc
@@9: popm ebx,ecx,edx,esi,edi,ebp
ret
FindGlobalGROUP endp
;------------------------------------------------------------------------------
;
;Add a GROUP to the global list.
;
;On Entry:
;
;EAX - GROUP name LNAME index.
;
;On Exit:
;
;Carry set on error else,
;
;EAX - GROUP list index.
;
AddGlobalGROUP proc near
pushm ebx,ecx,edx,esi,edi,ebp
cmp GROUPList,0
jnz @@0
mov ecx,4 ;Get memory for the initial
call Malloc ;GROUP list.
jc @@9
mov d[esi],0 ;Clear count dword.
mov GROUPList,esi ;Store GROUP pointer.
;
@@0: mov ecx,8 ;Initial GROUP size.
call Malloc
jc @@9
mov edi,esi ;Save pointer to GROUP.
mov d[edi],eax ;Store name index.
mov d[edi+4],0 ;Clear segment count.
;
mov esi,GROUPList ;Point to list.
mov ecx,[esi] ;Get current entries.
inc ecx ;include new entry.
shl ecx,2 ;dword per entry.
add ecx,4 ;include count dword.
call ReMalloc
jnc @@1
mov esi,edi
call Free ;Release GROUP memory.
jmp @@9
;
@@1: mov GROUPList,esi ;store new list address.
mov eax,[esi] ;get new entry number.
inc d[esi] ;update count.
add esi,4 ;skip count dword.
mov ebx,eax
shl ebx,2 ;dword per entry.
add esi,ebx ;point to new entry.
mov [esi],edi ;point to GROUP definition.
clc
;
@@9: popm ebx,ecx,edx,esi,edi,ebp
ret
AddGlobalGROUP endp
;------------------------------------------------------------------------------
;
;Add a segment to a global GROUP definition.
;
;On Entry:
;
;EAX - GROUP list index.
;EBP - Value to add.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -