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 + -
显示快捷键?