loadle.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 2,013 行 · 第 1/4 页
ASM
2,013 行
mov ecx,es:[esi] ;get number of entries.
add DWORD PTR es:[esi+4],4+2 ;correct module name pointer.
add esi,4+4
load1_exp0:
push ecx
push esi
push edx
mov esi,es:[esi] ;point to this entry.
xor ebp,ebp
xchg bp,WORD PTR es:[esi+4] ;get & clear ordinal.
dec ebp
load1_exp1: mov bh,es:[edx] ;get bundle count.
or bh,bh
jz load1_bad_entry
mov bl,es:[edx+1] ;get bundle type.
add edx,2
mov edi,edx ;point to object number incase we need it.
xor eax,eax
mov al,0
cmp bl,0
jz load1_exp2
add edx,2 ;skip object number.
mov al,3
cmp bl,1
jz load1_exp2
mov al,5
cmp bl,2
jz load1_exp2
mov al,5
cmp bl,3
jz load1_exp2
mov al,7
cmp bl,4
jz load1_exp2
jmp load1_bad_entry
load1_exp2: ;
load1_exp3: or bh,bh
jz load1_exp1 ;end of this bundle.
or ebp,ebp ;our ordinal?
jz load1_exp4
add edx,eax ;next entry.
dec ebp
dec bh
jmp load1_exp3
;
load1_exp4: or bl,bl
jz load1_bad_entry
dec bl
jz load1_exp_16bit
dec bl
IFDEF DEBUG4X
jz load1_bad_fixup1
ENDIF
jz load1_bad_fixup
dec bl
jz load1_exp_32bit
dec bl
jz load1_bad_entry
jmp load1_bad_entry
;
load1_bad_entry:
pop edx
pop esi
pop ecx
IFDEF DEBUG4X
push eax
push ebx
push ecx
push edx
push ds
push cs
pop ds
cmp bl,4
jae debugf2ae10
mov edx,OFFSET debugf2textl10
jmp debugf2loop2
debugf2ae10:
mov edx,OFFSET debugf2textae10
debugf2loop2:
cmp BYTE PTR ds:[edx],0
je debugf2b
mov ecx,1
mov bx,1
mov ah,40h
int 21h
inc edx
jmp debugf2loop2
debugf2b:
mov edx,OFFSET debugf2textcrlf
push cs
pop ds
mov ecx,2
mov bx,1
mov ah,40h
int 21h
pop ds
pop edx
pop ecx
pop ebx
pop eax
jmp debugf2out
debugf2textl10 DB '<10',0
debugf2textae10 DB '>=10',0
debugf2textcrlf DB 13,10
debugf2out:
jmp load1_bad_fixup2
ENDIF
jmp load1_bad_fixup
;
load1_exp_16bit: movzx eax,WORD PTR es:[edi] ;get the object number.
dec eax
shl ax,3
add ax,w[load1_Segs]
mov es:[esi+4],ax
movzx eax,WORD PTR es:[edx+1] ;get the offset.
mov es:[esi],eax
jmp load1_exp8
;
load1_exp_32bit: movzx eax,WORD PTR es:[edi]
dec eax
push eax
shl eax,2
mov ebx,eax
add ebx,ebx
shl eax,2
add ebx,eax
add ebx,d[load1_ObjMem]
mov ebx,es:LE_OBJ.LE_OBJ_Base[ebx]
pop eax
shl ax,3
add ax,w[load1_Segs]
mov es:[esi+4],ax
mov eax,es:[edx+1]
add eax,ebx
mov es:[esi],eax
; jmp load1_exp8 ; MED 02/03/2003, superfluous
;
load1_exp8:
pop edx
pop esi
pop ecx
add esi,4
dec ecx
jnz load1_exp0
;
mov esi,edx
sys RelMemLinear32
;
;Read program objects.
;
load1_NoEntries:
mov ebp,d[LE_Header.LE_ObjNum+LEHeader] ;number of objects.
mov esi,d[load1_ObjMem]
load1_load0:
mov eax,es:LE_OBJ.LE_OBJ_Flags[esi] ;get objects flags.
and eax,LE_OBJ_Flags_FillMsk ;isolate fill type.
cmp eax,LE_OBJ_Flags_Zero ;zero filled?
jnz load1_load1
;
;Zero this objects memory.
;
mov ecx,es:LE_OBJ.LE_OBJ_Size[esi] ;get objects virtual length.
mov edi,es:LE_OBJ.LE_OBJ_Base[esi]
xor eax,eax
push ecx
and ecx,3
rep stosb
pop ecx
shr ecx,2
rep stosd
;
load1_load1: ;Set file offset for data.
;
mov eax,es:LE_OBJ.LE_OBJ_PageIndex[esi] ;get first page index.
dec eax
; mul d[LE_Header.LE_PageSize+LEHeader] ;* page size.
TempAddress = LE_Header.LE_PageSize
TempAddress = TempAddress+LEHeader
mul DWORD PTR [TempAddress] ;* page size.
add eax,d[LE_Header.LE_Data+LEHeader] ;data offset.
mov dx,ax
shr eax,16
mov cx,ax
mov ax,4200h
mov bx,w[load1_Handle]
int 21h ;set the file pointer.
;
;Work out how much data we're going to load.
;
mov eax,es:LE_OBJ.LE_OBJ_PageNum[esi] ;get number of pages.
mov ebx,eax
; mul d[LE_Header.LE_PageSize+LEHeader] ;* page size.
TempAddress = LE_Header.LE_PageSize
TempAddress = TempAddress+LEHeader
mul DWORD PTR [TempAddress] ;* page size.
mov edx,es:LE_OBJ.LE_OBJ_Base[esi] ;get load address.
xor ecx,ecx
or eax,eax
jz load1_loadz
mov ecx,es:LE_OBJ.LE_OBJ_Size[esi]
add ebx,es:LE_OBJ.LE_OBJ_PageIndex[esi] ;get base page again.
dec ebx
cmp ebx,d[LE_Header.LE_Pages+LEHeader] ;we getting the last page?
jnz load1_load2
mov ebx,d[LE_Header.LE_PageSize+LEHeader]
sub ebx,d[LE_Header.LE_LastBytes+LEHeader]
sub eax,ebx
load1_load2:
cmp ecx,eax
jc load1_load3
mov ecx,eax
;
load1_load3: ;Load the data.
;
mov bx,w[load1_Handle]
push ds
push es
pop ds
call ReadFile
pop ds
jc load1_file_error
cmp eax,ecx
jnz load1_file_error
;
ZeroNotLoaded:
;Zero any memory we didn't just load to for Watcom's BSS benefit.
;
cmp ecx,es:LE_OBJ.LE_OBJ_Size[esi]
jnc load1_load4
push edi
mov edi,edx
add edi,ecx
sub ecx,es:LE_OBJ.LE_OBJ_Size[esi]
neg ecx
xor eax,eax
push ecx
shr ecx,2
or ecx,ecx
jz load1_load6
load1_load5:
mov es:[edi],eax
add edi,4
dec ecx
jnz load1_load5
load1_load6:
pop ecx
and ecx,3
rep stosb
pop edi
;
load1_load4: ;Next object.
load1_loadz:
;
add esi,size LE_OBJ
dec ebp
jnz load1_load0
;
;Get fixup table memory & load fixups.
;
mov ecx,d[LE_Header.LE_FixupSize+LEHeader]
sys GetMemLinear32 ;Get memory.
jc load1_mem_error ;Not enough memory.
mov d[load1_FixupMem],esi
push ecx
mov ecx,d[LE_Header.LE_Fixups+LEHeader]
add ecx,d[load1_LEOffset]
mov dx,cx
shr ecx,16
mov bx,w[load1_Handle]
mov ax,4200h
int 21h ;move to fixup data.
pop ecx
mov edx,esi
push ds
mov ds,apiDSeg
assume ds:_cwMain
mov ds,RealSegment
assume ds:_apiCode
call ReadFile
pop ds
jc load1_file_error
cmp eax,ecx
jnz load1_file_error
;
;Get IMPORT module name links.
;
mov ecx,d[LE_Header.LE_ImportModNum+LEHeader]
or ecx,ecx
jz load1_GotImpMods
shl ecx,2
add ecx,4
sys GetMemLinear32
jc load1_mem_error
mov DWORD PTR es:[esi],0 ;clear entry count for now.
push es
mov es,w[load1_PSP]
mov DWORD PTR es:[EPSP_Struc.EPSP_Imports],esi
pop es
mov d[load1_ModLink],esi
;
;Work out offset in fixup data.
;
mov esi,d[LE_Header.LE_ImportModNames+LEHeader]
sub esi,d[LE_Header.LE_Fixups+LEHeader]
add esi,d[load1_FixupMem]
;
;Work through each name getting the module link address.
;
load1_NextModLnk:
; cmp d[LE_ImportModNum+LEHeader],0
TempAddress = LE_Header.LE_ImportModNum
TempAddress = TempAddress+LEHeader
cmp DWORD PTR [TempAddress],0
jz load1_GotImpMods
;
;Preserve current header state.
;
push esi
mov ecx,size LE_Header
sys GetMemLinear32
mov ebp,esi
pop esi
jc load1_mem_error
mov edi,ebp
push esi
mov esi,offset LEHeader
rep movsb
pop esi
;
;Search for this name.
;
call FindModule
jc load1_error
;
push esi
push edi
mov esi,ebp
mov edi,offset LEHeader
mov ecx,size LE_Header
push ds
push es
pop ds
pop es
rep movsb
push ds
push es
pop ds
pop es
mov esi,ebp
sys RelMemLinear32
pop edi
pop esi
mov edx,d[load1_ModLink]
mov eax,es:[edx] ;get current count.
shl eax,2
add eax,4
mov es:[edx+eax],edi ;store link address.
inc DWORD PTR es:[edx] ;update link count.
;
movzx ecx,BYTE PTR es:[esi]
inc ecx
add esi,ecx
; dec d[LE_ImportModNum+LEHeader]
TempAddress = LE_Header.LE_ImportModNum
TempAddress = TempAddress+LEHeader
dec DWORD PTR [TempAddress]
jmp load1_NextModLnk
;
;Apply the fixups.
;
load1_GotImpMods:
mov eax,d[LE_Header.LE_ObjNum+LEHeader]
mov d[load1_ObjCount],eax
mov eax,d[load1_ObjMem]
mov d[load1_ObjBase],eax
mov d[load1_EntryEIP],0
load1_fix0: ;
mov esi,d[load1_ObjBase]
mov ecx,es:LE_OBJ.LE_OBJ_PageNum[esi]
or ecx,ecx
jz load1_fix400
mov d[load1_PageCount],ecx
mov d[load1_PageCount+4],0
mov edx,es:LE_OBJ.LE_OBJ_PageIndex[esi]
dec edx
mov ebp,edx ;Set base page map entry.
load1_fix1: ;
mov edx,ebp
mov esi,d[load1_FixupMem]
mov ecx,es:[esi+4+edx*4] ;Get next offset.
mov edx,es:[esi+edx*4] ;Get start offset.
sub ecx,edx ;Get number of bytes
jz load1_fix4
mov esi,d[load1_FixupMem]
add esi,d[LE_Header.LE_FixupsRec+LEHeader] ;Point to fixup data.
sub esi,d[LE_Header.LE_Fixups+LEHeader]
add esi,edx ;Move to start of this pages fixups.
load1_fix2:
mov al,es:[esi] ;Get type byte.
mov bl,al
shr bl,4 ;Get single/multiple flag.
mov bh,al
and bh,15 ;Get type.
inc esi
dec ecx
mov al,es:[esi] ;Get second type byte.
mov dl,al
and dl,3 ;Get internal/external specifier.
mov dh,al
shr dh,2 ;Get destination type.
inc esi
dec ecx
;
push ebx
and bl,not 1
or bl,bl ;Check it's a single entry.
pop ebx
jz CheckUnknown
IFDEF DEBUG4X
jnz load1_bad_fixup3
ENDIF
jnz load1_bad_fixup
;
IFDEF DEBUG4X
test dh,011010b ;Check for un-known bits.
jnz load1_bad_fixup9
ENDIF
; added support for additive bit, MED 06/10/96
; test dh,011011b ;Check for un-known bits.
CheckUnknown:
test dh,011010b ;Check for un-known bits.
jnz load1_bad_fixup
or dl,dl ;Check it's an internal target.
jnz load1_fixup_import
cmp bh,0010b ;Word segment?
jz load1_Seg16
cmp bh,0111b ;32-bit offset?
jz load1_32BitOff
cmp bh,0110b ;Seg:32-bit offset?
jz load1_Seg1632BitOff
cmp bh,1000b ;32-bit self relative?
jz load1_Self32Off
cmp bh,0101b ;16-bit offset?
jz load1_16BitOff
; MED 12/09/96
cmp bh,1 ; ignore fixup ???
je load1_fix3
IFDEF DEBUG4X
jmp load1_bad_fixup4
cmp bh,1
jne around
; add esi,4
; sub ecx,4
jmp load1_fix3
around:
ENDIF
jmp load1_bad_fixup
;
;Fetch an external referance.
;
load1_fixup_import:
;
;Grab the page offset.
;
movsx edi,WORD PTR es:[esi]
add esi,2
sub ecx,2
;
;Check import type.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?