loadle.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 2,407 行 · 第 1/3 页
ASM
2,407 行
; inc esi
; jmp debugabloop1
debugaba:
mov edx,OFFSET debugabtext2
push cs
pop ds
mov ecx,2
mov bx,1
mov ah,40h
int 21h
pop ds
pop esi
pop edx
pop ecx
pop ebx
pop eax
jmp debugabout
debugabtext1 DB 'Before FindModule call: ',0
debugabtext2 DB 13,10
debugabout:
ENDIF
call FindModule
jc @@error
IFDEF DEBUG2
push eax
push ebx
push ecx
push edx
push esi
push ds
push cs
pop ds
mov edx,OFFSET debugactext1
debugacloop2:
cmp BYTE PTR ds:[edx],0
je debugacb
mov ecx,1
mov bx,1
mov ah,40h
int 21h
inc edx
jmp debugacloop2
debugacb:
push es
pop ds
movzx ecx,BYTE PTR ds:[esi]
inc esi
;debugacloop1:
; cmp BYTE PTR ds:[esi],' '
; jbe debugaca
mov edx,esi
; mov ecx,1
mov bx,1
mov ah,40h
int 21h
; inc esi
; jmp debugacloop1
debugaca:
mov edx,OFFSET debugactext2
push cs
pop ds
mov ecx,2
mov bx,1
mov ah,40h
int 21h
pop ds
pop esi
pop edx
pop ecx
pop ebx
pop eax
jmp debugacout
debugactext1 DB 'After FindModule call: ',0
debugactext2 DB 13,10
debugacout:
ENDIF
;
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[@@ModLink]
mov eax,es:[edx] ;get current count.
shl eax,2
add eax,4
mov es:[edx+eax],edi ;store link address.
inc es:d[edx] ;update link count.
;
movzx ecx,es:b[esi]
inc ecx
add esi,ecx
dec d[LE_ImportModNum+LEHeader]
jmp @@NextModLnk
;
;Apply the fixups.
;
@@GotImpMods:
mov eax,d[LE_ObjNum+LEHeader]
mov d[@@ObjCount],eax
mov eax,d[@@ObjMem]
mov d[@@ObjBase],eax
mov d[@@EntryEIP],0
@@fix0: ;
mov esi,d[@@ObjBase]
mov ecx,es:LE_OBJ_PageNum[esi]
or ecx,ecx
jz @@fix400
mov d[@@PageCount],ecx
mov d[@@PageCount+4],0
mov edx,es:LE_OBJ_PageIndex[esi]
dec edx
mov ebp,edx ;Set base page map entry.
@@fix1: ;
mov edx,ebp
mov esi,d[@@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 @@fix4
IFDEF DEBUG4
push eax
push ebx
push ecx
push edx
push ds
push cs
pop ds
mov edx,OFFSET debug10text1
debug10loop2:
cmp BYTE PTR ds:[edx],0
je debug10b
mov ecx,1
mov bx,1
mov ah,40h
int 21h
inc edx
jmp debug10loop2
debug10b:
mov edx,OFFSET debug10text2
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 debug10out
debug10text1 DB 'New fixup page...',0
debug10text2 DB 13,10
debug10out:
ENDIF
mov esi,d[@@FixupMem]
add esi,d[LE_FixupsRec+LEHeader] ;Point to fixup data.
sub esi,d[LE_Fixups+LEHeader]
add esi,edx ;Move to start of this pages fixups.
@@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
IFDEF DEBUG4
jnz @@bad_fixup3
ENDIF
jnz @@bad_fixup
;
IFDEF DEBUG4
test dh,011010b ;Check for un-known bits.
jnz @@bad_fixup9
ENDIF
; added support for additive bit, MED 06/10/96
; test dh,011011b ;Check for un-known bits.
test dh,011010b ;Check for un-known bits.
jnz @@bad_fixup
or dl,dl ;Check it's an internal target.
jnz @@fixup_import
cmp bh,0010b ;Word segment?
jz @@Seg16
cmp bh,0111b ;32-bit offset?
jz @@32BitOff
cmp bh,0110b ;Seg:32-bit offset?
jz @@Seg1632BitOff
cmp bh,1000b ;32-bit self relative?
jz @@Self32Off
cmp bh,0101b ;16-bit offset?
jz @@16BitOff
; MED 12/09/96
cmp bh,1 ; ignore fixup ???
je @@fix3
IFDEF DEBUG4
jmp @@bad_fixup4
cmp bh,1
jne around
; add esi,4
; sub ecx,4
jmp @@fix3
around:
ENDIF
jmp @@bad_fixup
;
;Fetch an external referance.
;
@@fixup_import:
;
;Grab the page offset.
;
movsx edi,es:w[esi]
add esi,2
sub ecx,2
;
;Check import type.
;
cmp dl,01b ;ordinal?
jz @@fiximp0
cmp dl,10b ;name?
IFDEF DEBUG4
jnz @@bad_fixup5
ENDIF
jnz @@bad_fixup
;
;Importing by name so find the name.
;
pushm edi,ebp
mov ebp,d[LE_ImportNames+LEHeader]
sub ebp,d[LE_Fixups+LEHeader]
movzx eax,es:w[esi+1]
add ebp,eax ;point to function name.
add ebp,d[@@FixupMem]
movzx eax,es:b[esi]
shl eax,2
add eax,d[@@ModLink]
mov edi,es:[eax] ;point to module.
mov edi,es:EPSP_EXPORTS[edi] ;point to export table.
IFDEF DEBUG4
push eax
push ebx
push ecx
push edx
push ebp
push ds
push cs
pop ds
mov edx,OFFSET debug2text1
debug2loop2:
cmp BYTE PTR ds:[edx],0
je debug2b
mov ecx,1
mov bx,1
mov ah,40h
int 21h
inc edx
jmp debug2loop2
debug2b:
push es
pop ds
movzx ecx,BYTE PTR ds:[ebp]
inc ebp
debug2loop1:
; cmp BYTE PTR ds:[ebp],' '
; jbe debug2a
mov edx,ebp
; mov ecx,1
mov bx,1
mov ah,40h
int 21h
; inc ebp
; jmp debug2loop1
debug2a:
mov edx,OFFSET debug2text2
push cs
pop ds
mov ecx,2
mov bx,1
mov ah,40h
int 21h
pop ds
pop ebp
pop edx
pop ecx
pop ebx
pop eax
jmp debug2out
debug2text1 DB 'FindFunction call: ',0
debug2text2 DB 13,10
debug2out:
ENDIF
call FindFunction
mov eax,edi
popm edi,ebp
jc @@file_error
add esi,1+2
sub ecx,1+2
jmp @@fiximp2
;
;Importing by ordinal so go strieght to the export.
;
@@fiximp0: push edi
movzx edi,es:b[esi]
shl edi,2
add edi,d[@@ModLink]
mov edi,es:[edi]
mov edi,es:EPSP_EXPORTS[edi] ;point to export table.
movzx eax,es:w[esi+1]
add esi,2
sub ecx,2
test dh,100000b
jz @@fiximp1
sub esi,2
add ecx,2
movzx eax,es:b[esi+1]
add esi,1
sub ecx,1
@@fiximp1: mov eax,es:[edi+4+eax*4] ;point to export.
pop edi
add esi,1
sub ecx,1
@@fiximp2:
IFDEF DEBUG4
push eax
push ebx
push ecx
push edx
push ds
push cs
pop ds
mov edx,OFFSET debug4text1
debug4loop2:
cmp BYTE PTR ds:[edx],0
je debug4b
mov ecx,1
mov bx,1
mov ah,40h
int 21h
inc edx
jmp debug4loop2
debug4b:
mov edx,OFFSET debug4text2
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 debug4out
debug4text1 DB 'Performing fixup...',0
debug4text2 DB 13,10
debug4out:
ENDIF
;Now perform the fixup.
;
cmp bh,0010b ;Word segment?
jz @@iSeg16
cmp bh,0111b ;32-bit offset?
jz @@i32BitOff
cmp bh,0110b ;Seg:32-bit offset?
jz @@iSeg1632BitOff
cmp bh,1000b ;32-bit self relative?
jz @@iSelf32Off
IFDEF DEBUG4
jmp @@bad_fixup6
ENDIF
jmp @@bad_fixup
;
@@iSeg16: ;Deal with a 16-bit segment.
;
test dh,4
IFDEF DEBUG4
jnz @@bad_fixup7
ENDIF
jnz @@bad_fixup
;
or edi,edi
js @@iNeg0
mov ebx,d[@@ObjBase]
mov ebx,es:LE_OBJ_Base[ebx]
add edi,ebx
mov ebx,d[@@PageCount+4] ;Get page number.
shl ebx,12
add edi,ebx ;Point to the right page.
mov ax,es:[eax+4] ;Get the target segment.
mov es:[edi],ax ;Store target.
; MED 06/10/96
test dh,1 ; see if additive value
jne @@bad_fixup ; yes, don't allow additives on segment fixups
@@iNeg0: jmp @@fix3
;
@@i32BitOff: ;Deal with a 32-bit offset.
;
or edi,edi
js @@iNeg1
mov ebx,d[@@ObjBase]
mov ebx,es:LE_OBJ_Base[ebx]
add edi,ebx
mov ebx,d[@@PageCount+4] ;Get page number.
shl ebx,12
add edi,ebx ;Point to the right page.
mov eax,es:[eax]
mov es:[edi],eax
; MED 06/10/96
test dh,1 ; see if additive value
je @@fix3 ; no
movzx eax,WORD PTR es:[esi] ; get additive value
add esi,2
sub ecx,2
add es:[edi],eax ;Store target.
jmp @@fix3
@@iNeg1:
test dh,1 ; MED 06/12/96
jz @@iNeg1a
add esi,2
sub ecx,2
@@iNeg1a:
jmp @@fix3
@@iSelf32Off: ;Deal with a 32-bit self relative offset.
or edi,edi
js @@isfNeg1
mov ebx,d[@@ObjBase]
mov ebx,es:LE_OBJ_Base[ebx]
add edi,ebx
mov ebx,d[@@PageCount+4] ;Get page number.
shl ebx,12
add edi,ebx ;Point to the right page.
mov ebx,edi
add ebx,4
mov eax,es:[eax]
sub eax,ebx
mov es:[edi],eax
; MED 06/10/96
test dh,1 ; see if additive value
je @@fix3 ; no
movzx eax,WORD PTR es:[esi] ; get additive value
add esi,2
sub ecx,2
add es:[edi],eax ;Store target.
@@isfNeg1: jmp @@fix3
@@iSeg1632BitOff: ;Deal with an FWORD fixup by splitting into a seg16 and 32-bit
;offset relocation entry.
;
or edi,edi
js @@iNeg2
mov ebx,d[@@ObjBase]
mov ebx,es:LE_OBJ_Base[ebx]
add edi,ebx
mov ebx,d[@@PageCount+4] ;Get page number.
shl ebx,12
add edi,ebx ;Point to the right page.
push eax
movzx eax,es:w[eax+4]
mov es:[edi+4],ax ;Store target.
pop eax
mov eax,es:[eax]
mov es:[edi],eax
; MED 06/10/96
test dh,1 ; see if additive value
je @@fix3 ; no
movzx eax,WORD PTR es:[esi] ; get additive value
add esi,2
sub ecx,2
add es:[edi],eax ;Store target.
@@iNeg2: jmp @@fix3
;Deal with a 16-bit segment.
@@Seg16:
;EBP - Page offset within segment.
;w[esi] - offset within page.
;b[esi+2] - target object+1.
;
test dh,4
IFDEF DEBUG4
jnz @@bad_fixup8
ENDIF
jnz @@bad_fixup
;
mov edi,d[@@ObjBase]
mov edi,es:LE_OBJ_Base[edi]
mov eax,d[@@PageCount+4] ;Get page number.
shl eax,12
add edi,eax ;Point to the right page.
movsx eax,es:w[esi]
or eax,eax
js @@Neg0
add edi,eax ;Point to the right offset.
movzx eax,es:b[esi+2] ;Get the target segment.
dec eax
shl eax,3
add ax,w[@@Segs]
mov es:[edi],ax ;Store target.
;
@@Neg0: add esi,2+1
sub ecx,2+1
jmp @@fix3
;
@@16BitOff: ;Deal with a 16-bit offset.
;
;EBP - Page offset within segment.
;w[esi] - offset within page.
;b[esi+2] - target object+1
;w[esi+3] - target offset.
;
mov edi,d[@@ObjBase]
mov edi,es:LE_OBJ_Base[edi]
mov eax,d[@@PageCount+4] ;Get page number.
shl eax,12
add edi,eax ;Point to the right page.
movsx eax,es:w[esi]
or eax,eax
js @@Neg3
add edi,eax ;Point to the right offset.
mov ax,es:w[esi+3] ;Get target offset.
mov es:[edi],ax
@@Neg3: add esi,2+1+2
sub ecx,2+1+2
jmp @@fix3
;
@@32BitOff: ;Deal with a 32-bit offset.
;
;EBP - Page offset within segment.
;w[esi] - offset within page.
;b[esi+2] - target object+1
;w[esi+3] - target offset.
;
mov edi,d[@@ObjBase]
mov edi,es:LE_OBJ_Base[edi]
mov eax,d[@@PageCount+4] ;Get page number.
shl eax,12
add edi,eax ;Point to the right page.
movsx eax,es:w[esi]
or eax,eax
js @@Neg1
add edi,eax ;Point to the right offset.
movzx eax,es:b[esi+2] ;Get the target segment.
dec eax
push edx
mov edx,size LE_OBJ
mul edx
pop edx
add eax,d[@@ObjMem] ;point to target segment details.
mov eax,es:LE_OBJ_Base[eax] ;Get target segments offset from start of image.
COMMENT !
movzx ebx,es:w[esi+3] ;Get target offset.
test dh,4
jz @@Big0
mov ebx,es:[esi+3] ;Get target offset.
@@Big0: add eax,ebx
mov es:[edi],eax
END COMMENT !
; MED 06/12/96, allow for additive bit
test dh,4
jnz @@Big0
movzx ebx,es:w[esi+3] ;Get 16-bit target offset.
add esi,2+1+2 ; adjust offset, byte count
sub ecx,2+1+2
stuff1:
add eax,ebx
mov es:[edi],eax
test dh,1 ; check for additive value
je @@fix3 ; none
movzx eax,WORD PTR es:[esi] ; get additive value
add esi,2
sub ecx,2
add es:[edi],eax ;Store target.
jmp @@fix3
@@Big0:
mov ebx,es:[esi+3] ;Get 32-bit target offset.
add esi,2+1+4 ; adjust offset, byte count
sub ecx,2+1+4
jmp stuff1
@@Neg1:
add esi,2+1+2
sub ecx,2+1+2
test dh,1 ; MED 06/12/96
jz @@Neg1a
add esi,2
sub ecx,2
@@Neg1a:
test dh,4
jz @@fix3
add esi,2
sub ecx,2
jmp @@fix3
@@Self32Off: ;Deal with a 32-bit self relative offset.
;
;EBP - Page offset within segment.
;w[esi] - offset within page.
;b[esi+2] - target object+1
;w[esi+3] - target offset.
;
mov edi,d[@@ObjBase]
mov ebx,es:LE_OBJ_Flags[edi]
mov edi,es:LE_OBJ_Base[edi]
mov eax,d[@@PageCount+4] ;Get page number.
shl eax,12
add edi,eax ;Point to the right page.
movsx eax,es:w[esi]
or eax,eax
js @@sfNeg1
add edi,eax ;Point to the right offset.
mov ebx,edi
movzx eax,es:b[esi+2] ;Get the target segment.
dec eax
push edx
mov edx,size LE_OBJ
mul edx
pop edx
add eax,d[@@ObjMem] ;point to target segment details.
mov eax,es:LE_OBJ_Base[eax]
push ebx
movzx ebx,es:w[esi+3] ;Get target offset.
test dh,4
jz @@sfBig0
mov ebx,es:[esi+3] ;Get target offset.
@@sfBig0: add eax,ebx
pop ebx
add ebx,4
sub eax,ebx
mov es:[edi],eax
;
@@sfNeg1: add esi,2+1+2
sub ecx,2+1+2
test dh,4
jz @@fix3
add esi,2
sub ecx,2
jmp @@fix3
;
@@Seg1632BitOff: ;Deal with an FWORD fixup by splitting into a seg16 and 32-bit
;offset relocation entry.
;
;EBP - Page offset within segment.
;w[esi] - offset within page.
;b[esi+2] - target object+1
;w[esi+3] - target offset.
;
mov edi,d[@@ObjBase]
mov edi,es:LE_OBJ_Base[edi]
mov eax,d[@@PageCount+4] ;Get page number.
shl eax,12
add edi,eax ;Point to the right page.
movsx eax,es:w[esi]
or eax,eax
js @@Neg2
add edi,eax ;Point to the right offset.
add edi,4 ;Point to the seg bit.
movzx eax,es:b[esi+2] ;Get the target segment.
dec eax
shl eax,3
add ax,w[@@Segs]
mov es:[edi],ax ;Store target.
;
mov edi,d[@@ObjBase]
mov edi,es:LE_OBJ_Base[edi]
mov eax,d[@@PageCount+4] ;Get page number.
shl eax,12
add edi,eax ;Point to the right page.
movzx eax,es:w[esi]
add edi,eax ;Point to the right offset.
movzx eax,es:b[esi+2] ;Get the target segment.
dec eax
push edx
mov edx,size LE_OBJ
mul edx
pop edx
add eax,d[@@ObjMem] ;point to target segment details.
test es:LE_OBJ_Flags[eax],LE_OBJ_Flags_Big
pushf
mov eax,es:LE_OBJ_Base[eax] ;Get target segments offset from start of image.
movzx ebx,es:w[esi+3] ;Get target offset.
test dh,4
jz @@Big1
mov ebx,es:[esi+3] ;Get target offset.
@@Big1: popf
jz @@NotFlat1
add ebx,eax
@@NotFlat1: mov es:[edi],ebx
;
@@Neg2: add esi,2+1+2
sub ecx,2+1+2
test dh,4
jz @@fix3
add esi,2
sub ecx,2
jmp @@fix3
;
@@fix3: inc d[@@EntryEIP]
or ecx,ecx
jnz @@fix2
;
@@fix4: inc ebp
inc d[@@PageCount+4]
dec d[@@PageCount]
jnz @@fix1
;
@@fix400: add d[@@ObjBase],size LE_OBJ
dec d[@@ObjCount]
jnz @@fix0
mov esi,d[@@FixupMem]
sys RelMemLinear32
mov d[@@FixupMem],0
IFDEF DEBUG2
push eax
push ebx
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?