loadle.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 2,407 行 · 第 1/3 页

ASM
2,407
字号
	push	ecx
	push	edx
	push	ds
	push	cs
	pop	ds
	mov	edx,OFFSET debugadtext1
debugadloop2:
	cmp	BYTE PTR ds:[edx],0
	je	debugadb
	mov	ecx,1
	mov	bx,1
	mov	ah,40h
	int	21h
	inc	edx
	jmp	debugadloop2
debugadb:
	mov	edx,OFFSET debugadtext2
	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	debugadout

debugadtext1	DB	'Setup entry CS:EIP...',0
debugadtext2	DB	13,10

debugadout:
ENDIF

;
;Setup entry CS:EIP.
;
	mov	ebx,d[LE_EntryCS+LEHeader]
	or	ebx,ebx
	jz	@@NoEntryCS
	dec	ebx
	mov	eax,size LE_OBJ
	mul	ebx
	shl	ebx,3
	mov	esi,d[LE_EntryEIP+LEHeader]
	mov	edi,d[@@ObjMem]
	add	edi,eax
	add	esi,es:LE_OBJ_Base[edi]
	test	es:LE_OBJ_Flags[edi],LE_OBJ_Flags_Big	;FLAT segment?
	jnz	@@FlatEIP
	sub	esi,d[@@ProgMem]
@@FlatEIP:	add	bx,w[@@Segs]
	mov	d[@@EntryEIP],esi
@@NoEntryCS:	mov	w[@@EntryCS],bx
;
;Setup entry SS:ESP
;
	mov	ebx,d[LE_EntrySS+LEHeader]
	or	ebx,ebx
	jz	@@NoEntrySS
	dec	ebx
	mov	eax,size LE_OBJ
	mul	ebx
	shl	ebx,3
	mov	esi,d[LE_EntryESP+LEHeader]
	mov	edi,d[@@ObjMem]
	add	edi,eax
	add	esi,es:LE_OBJ_Base[edi]
	test	es:LE_OBJ_Flags[edi],LE_OBJ_Flags_Big	;FLAT segment?
	jnz	@@FlatESP
	sub	esi,d[@@ProgMem]
@@FlatESP:	add	bx,w[@@Segs]
	mov	d[@@EntryESP],esi
@@NoEntrySS:	mov	w[@@EntrySS],bx
;
;Setup entry ES & DS.
;
	mov	ax,w[@@PSP]
	mov	w[@@EntryES],ax
	mov	w[@@EntryDS],ax
	mov	eax,d[LE_AutoDS+LEHeader]
	or	eax,eax
	jz	@@NoAutoDS
	dec	eax
	shl	eax,3
	add	ax,w[@@Segs]
	mov	w[@@EntryDS],ax
;
;Convert object definitions into 3P segment definitions for CWD.
;
@@NoAutoDS:	mov	ebp,d[LE_ObjNum+LEHeader]	;number of objects.
	mov	esi,d[@@ObjMem]
	mov	edi,esi
@@makesegs0:	mov	eax,es:LE_OBJ_Flags[esi]	;Get objects flags.
	xor	ebx,ebx
	test	eax,LE_OBJ_Flags_Exec	;Executable?
	jnz	@@makesegs1
	inc	ebx		;Make it Data.
	test	eax,LE_OBJ_Flags_Write	;Writeable?
	jz	@@makesegs1
;	add	ebx,2		;Read only data.
@@makesegs1:	shl	ebx,24
	test	eax,LE_OBJ_Flags_Big	;Big bit set?
	jz	@@makesegs2
	or	ebx,1 shl 26		;Force 32-bit.
	or	ebx,1 shl 27		;assume 32-bit is FLAT.
	jmp	@@makesegs3
@@makesegs2:	or	ebx,1 shl 25		;Force 16-bit.
@@makesegs3:	mov	eax,es:LE_OBJ_Size[esi]
	cmp	eax,100000h		;>1M?
	jc	@@makesegs4
	shr	eax,12
	or	eax,1 shl 20
@@makesegs4:	or	ebx,eax		;Include length.
	mov	eax,es:LE_OBJ_Base[esi]
	sub	eax,d[@@ProgMem]	;lose load address.
	mov	es:d[edi+0],eax
	mov	es:d[edi+4],ebx
	add	esi,size LE_OBJ
	add	edi,4+4
	dec	ebp
	jnz	@@makesegs0
	;
	;Shrink OBJ memory to fit segment definitions.
	;
	mov	eax,4+4
	mul	d[LE_ObjNum+LEHeader]	;number of objects.
	mov	ecx,eax
	mov	esi,d[@@ObjMem]
	sys	ResMemLinear32
	jc	@@mem_error		;shouldn't be able to happen.
	mov	d[@@ObjMem],esi	;set new Obj mem address.
;
;Setup selectors.
;
	mov	ecx,d[LE_ObjNum+LEHeader]
	mov	esi,d[@@ObjMem]
	mov	bx,w[@@Segs]		;base selector.
@@SegLoop:	pushm	ebx,ecx,esi
	;
	mov	eax,es:[esi+4]	;Get limit.
	mov	ecx,eax
	and	ecx,0fffffh		;mask to 20 bits.
	test	eax,1 shl 20		;G bit set?
	jz	@@NoGBit
	shl	ecx,12
	or	ecx,4095
@@NoGBit:	or	ecx,ecx
	jz	@@NoDecLim
	cmp	ecx,-1
	jz	@@NoDecLim
	dec	ecx
@@NoDecLim:	mov	edx,es:[esi]		;get base.
	;
	test	eax,1 shl 27		;FLAT segment?
	jz	@@NotFLATSeg
	;
	push	fs
	mov	fs,w[@@PSP]
	mov	fs:d[EPSP_NearBase],0	;Make sure NEAR functions work.
	pop	fs
	;
	add	edx,d[@@ProgMem]
	or	ecx,-1		;Update the limit.
	xor	edx,edx
	jmp	@@DoSegSet
	;
@@NotFLATSeg:	add	edx,d[@@ProgMem]	;offset within real memory.
	;
@@DoSegSet:	sys	SetSelDet32
	;
	mov	eax,es:[esi+4]	;Get class.
	shr	eax,21		;move type into useful place.
	and	eax,0fh		;isolate type.
	or	eax,eax
	jz	@@CodeSeg
	mov	eax,es:[esi+4]	;Get type bits.
	mov	cx,0		;Set 16 bit seg.
	test	eax,1 shl 25
	jnz	@@gotBBit
	mov	cx,1
	test	eax,1 shl 26		;32 bit seg?
	jnz	@@gotBBit
	mov	cx,0		;Set 16 bit seg.
@@GotBBit:	call	_DSizeSelector
	jmp	@@SegDone
	;
@@CodeSeg:	mov	eax,es:[esi+4]	;Get type bits.
	mov	cx,0		;Set 16 bit seg.
	test	eax,1 shl 25
	jnz	@@Default
	mov	cx,1
	test	eax,1 shl 26		;32 bit seg?
	jnz	@@Default
	mov	cx,0		;Set 16 bit seg.
@@Default:	sys	CodeSel
	;
@@SegDone:	popm	ebx,ecx,esi
	add	esi,8		;next definition.
	add	ebx,8		;next selector.
	dec	ecx
	jnz	@@SegLoop
;
;Close the input file.
;

IFDEF DEBUG2
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	ds
	push	cs
	pop	ds
	mov	edx,OFFSET debugaetext1
debugaeloop2:
	cmp	BYTE PTR ds:[edx],0
	je	debugaeb
	mov	ecx,1
	mov	bx,1
	mov	ah,40h
	int	21h
	inc	edx
	jmp	debugaeloop2
debugaeb:
	mov	edx,OFFSET debugaetext2
	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	debugaeout

debugaetext1	DB	'Close Input File...',0
debugaetext2	DB	13,10

debugaeout:
ENDIF

	xor	bx,bx
	xchg	bx,w[@@Handle]
	mov	ah,3eh
	int	21h
;
;Check if this is an exec or just a load.
;
	cmp	d[@@Flags],0
	jz	@@Exec

;
;Switch back to parents PSP if this is a debug load.
;
	cmp	d[@@Flags],2
	jz	@@NoPSwitch2
	push	fs
	mov	fs,w[@@PSP]
	mov	bx,fs:w[EPSP_Parent]
	pop	fs
	mov	ah,50h
	int	21h
	mov	ebp,d[@@ObjMem]
;
;Return program details to caller.
;
@@NoPSwitch2:	mov	edx,d[@@EntryEIP]
	mov	cx,w[@@EntryCS]
	mov	eax,d[@@EntryESP]
	mov	bx,w[@@EntrySS]
	mov	si,w[@@EntryES]
	mov	di,w[@@EntryDS]
	clc
	jmp	@@exit
;
;Run it.
;
@@Exec:
	mov	eax,d[@@Flags]
	mov	ebx,d[@@EntryEIP]
	mov	cx,w[@@EntryCS]
	mov	edx,d[@@EntryESP]
	mov	si,w[@@EntrySS]
	mov	di,w[@@PSP]
	mov	bp,w[@@EntryDS]
	call	ExecModule

	clc
;
;Shut down anything still hanging around.
;
@@error:
	pushf
	push	ax
;
;Make sure file is closed.
;
	pushf
	xor	bx,bx
	xchg	bx,w[@@Handle]
	or	bx,bx
	jz	@@NoClose
	mov	ah,3eh
	int	21h
;
;Make sure all work spaces are released.
;
@@NoClose:	xor	esi,esi
	xchg	esi,d[@@ObjMem]
	or	esi,esi
	jz	@@NoObjRel
	sys	RelMemLinear32
;
;Restore previous state.
;
@@NoObjRel:	popf
	jnc	@@RelPSP
	cmp	w[@@PSP],0
	jz	@@NoRelRes
;
;Restore vectors & DPMI state.
;
@@RelPSP:	mov	eax,d[@@Flags]
	mov	bx,w[@@PSP]
	pushm	ds,ds,ds
	popm	es,fs,gs
	call	DeletePSP
;
;Return to caller.
;
@@NoRelRes:	pop	ax
	popf
	;
@@exit:
IFDEF LXWORK
	pop	WORD PTR [@@LXFlag]	; MED
ENDIF
	popm	w[@@EntryDS],w[@@EntryES],d[@@ModLink],d[@@ModLink+4],d[@@LEOffset]
	popm	d[@@EntryEIP],w[@@EntryCS],d[@@EntryESP],w[@@EntrySS]
	popm	d[@@ObjBase],d[@@PageCount],d[@@PageCount+4]
	popm	d[@@Segs],d[@@ObjMem],d[@@FixupMem],d[@@ObjCount]
	popm	w[@@Environment],w[@@Handle],w[@@PSP],d[@@ProgMem],d[@@ProgMem+4]
	popm	d[@@Name],w[@@Name+4],d[@@Flags],d[@@Command],w[@@command+4]
	;
	popm	ds,es,fs,gs

IFDEF DEBUG2
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	ds
	push	cs
	pop	ds
	mov	edx,OFFSET debugaftext1
debugafloop2:
	cmp	BYTE PTR ds:[edx],0
	je	debugafb
	mov	ecx,1
	mov	bx,1
	mov	ah,40h
	int	21h
	inc	edx
	jmp	debugafloop2
debugafb:
	mov	edx,OFFSET debugaftext2
	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	debugafout

debugaftext1	DB	'Returning from LoadLE...',0
debugaftext2	DB	13,10

debugafout:
ENDIF

	ret
;
;Not enough memory error.
;
@@mem_error:

	mov	ax,3
	stc
	jmp	@@error
;
;Couldn't find the file.
;
@@no_file_error:
	mov	ax,1
	stc
	jmp	@@error
;
;Fixup type we don't understand.
;
@@bad_fixup:
IFDEF DEBUG4
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	ds
	push	cs
	pop	ds
	mov	edx,OFFSET debug5text1
debug5loop2:
	cmp	BYTE PTR ds:[edx],0
	je	debug5b
	mov	ecx,1
	mov	bx,1
	mov	ah,40h
	int	21h
	inc	edx
	jmp	debug5loop2
debug5b:
	dec	esi
	mov	edx,OFFSET debug5t1
	add	edx,esi
	push	cs
	pop	ds
	mov	ecx,1
	mov	bx,1
	mov	ah,40h
	int	21h
	mov	edx,OFFSET debug5text2
	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
	pop	esi
	jmp	debug5out

debug5text1	DB	' Bad fixup: ',0
debug5text2	DB	13,10
debug5t1	DB	'1','2','3','4','5','6','7','8','9','A'

@@bad_fixup1:
	push	esi
	mov	esi,1
	jmp	@@bad_fixup
@@bad_fixup2:
	push	esi
	mov	esi,2
	jmp	@@bad_fixup
@@bad_fixup3:
	push	esi
	mov	esi,3
	jmp	@@bad_fixup
@@bad_fixup4:
	push	esi
	mov	esi,4
	jmp	@@bad_fixup
@@bad_fixup5:
	push	esi
	mov	esi,5
	jmp	@@bad_fixup
@@bad_fixup6:
	push	esi
	mov	esi,6
	jmp	@@bad_fixup
@@bad_fixup7:
	push	esi
	mov	esi,7
	jmp	@@bad_fixup
@@bad_fixup8:
	push	esi
	mov	esi,8
	jmp	@@bad_fixup
@@bad_fixup9:
	push	eax
	push	ebx
	push	ecx
	push	edx
	mov	cx,8
bfloop:
	rol	dh,1
	mov	bl,dh
	and	dh,1
	mov	dl,dh
	add	dl,30h
	mov	ah,2
	int	21h
	mov	dh,bl
	dec	cx
	jne	bfloop
	pop	edx
	pop	ecx
	pop	ebx
	pop	eax
	push	esi
	mov	esi,9
	jmp	@@bad_fixup

debug5out:
ENDIF

	mov	eax,d[@@EntryEIP]	;Get the relocation number.
	push	ds
	assume ds:nothing
	mov	ds,cs:apiDSeg
	assume ds:_cwMain
	if	0
	mov	b[ErrorM11_0+0]," "
	mov	b[ErrorM11_0+1]," "
	mov	b[ErrorM11_0+2]," "
	mov	ecx,8
	mov	edi,offset ErrorM11_1
	call	Bin2HexA
	endif
	assume ds:_apiCode
	pop	ds
	mov	ax,2
	stc
	jmp	@@error
;
;Not an LE file.
;
@@file_error:
IFDEF DEBUG4
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	ds
	push	cs
	pop	ds
	mov	edx,OFFSET debug7text1
debug7loop2:
	cmp	BYTE PTR ds:[edx],0
	je	debug7b
	mov	ecx,1
	mov	bx,1
	mov	ah,40h
	int	21h
	inc	edx
	jmp	debug7loop2
debug7b:
	mov	edx,OFFSET debug7text2
	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	debug7out

debug7text1	DB	'File error type 1',0
debug7text2	DB	13,10

debug7out:
ENDIF

	mov	ax,2
	stc
	jmp	@@error
;
;Corrupt file or file we don't understand.
;
@@file_error2:

IFDEF DEBUG4
	push	eax
	push	ebx
	push	ecx
	push	edx
	push	ds
	push	cs
	pop	ds
	mov	edx,OFFSET debug8text1
debug8loop2:
	cmp	BYTE PTR ds:[edx],0
	je	debug8b
	mov	ecx,1
	mov	bx,1
	mov	ah,40h
	int	21h
	inc	edx
	jmp	debug8loop2
debug8b:
	mov	edx,OFFSET debug8text2
	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	debug8out

debug8text1	DB	'File error type 2',0
debug8text2	DB	13,10

debug8out:
ENDIF

	mov	ax,2
	stc
	jmp	@@error
;
@@Name:	;
	df 0
@@Flags:	;
	dd 0
@@Command:	;
	df 0
@@Environment:	;
	dw 0
@@Handle:	;
	dw 0
@@PSP:	;
	dw 0
@@LEOffset:	;
	dd 0
@@ProgMem:	;
	dd 0,0
@@Segs:	;
	dw 0,0
@@ObjMem:	;
	dd 0
@@FixupMem:	;
	dd 0
@@ObjCount:	;
	dd 0
@@ObjBase:	;
	dd 0
@@PageCount:	;
	dd 0,0
@@EntryEIP:	;
	dd 0
@@EntryCS:	;
	dw 0
@@EntryESP:	;
	dd 0
@@EntrySS:	;
	dw 0
@@EntryES:	;
	dw 0
@@EntryDS:	;
	dw 0
@@ModLink:	;
	dd 0,0
IFDEF LXWORK
@@LXFlag	DW	0	; nonzero if LX instead of LE, MED
ENDIF
LoadLE	endp


;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
;LE header format.
;
LE_Header		struc
LE_ID		dw ?	;"LE" text identifier.
LE_ByteOrder		db ?	;byte order, 0=little-endian, none-zero=big.
LE_WordOrder		db ?	;word order.
LE_Format		dd ?	;format level.
;
LE_CPU		dw ?	;CPU type.
LE_CPU_286		equ 1
LE_CPU_386		equ 2
LE_CPU_486		equ 3
LE_CPU_586		equ 4
LE_CPU_i860		equ 20h
LE_CPU_N11		equ 21h
LE_CPU_R2000		equ 40h
LE_CPU_R6000		equ 41h
LE_CPU_R4000		equ 42h
;
LE_OS		dw ?	;Target operating system.
LE_OS_OS2		equ 1
LE_OS_Windows		equ 2
LE_OS_DOS4		equ 3
LE_OS_Win386		equ 4
;
LE_Version		dd ?	;Module version.
;
LE_Type		dd ?	;Module type.
LE_Type_InitPer	equ 1 shl 2	;initialise per process.
LE_Type_IntFixup	equ 1 shl 4	;no internal fixups.
LE_Type_ExtFixup	equ 1 shl 5	;no external fixups.
LE_Type_NoLoad		equ 1 shl 13	;module not loadable.
LE_Type_DLL		equ 1 shl 15	;DLL
;
LE_Pages		dd ?	;number of memory pages.
LE_EntryCS		dd ?	;Entry CS object.
LE_EntryEIP		dd ?	;Entry EIP.
LE_EntrySS		dd ?	;Entry SS object.
LE_EntryESP		dd ?	;Entry ESP.
LE_PageSize		dd ?	;Page size.
LE_LastBytes		dd ?	;Bytes on last page.
LE_FixupSize		dd ?	;fixup section size.
LE_FixupChk		dd ?	;fixup section check sum.
LE_LoaderSize		dd ?	;loader section size.
LE_LoaderChk		dd ?	;loader section check sum.
LE_ObjOffset		dd ?	;offset of object table.
LE_ObjNum		dd ?	;object table entries
LE_PageMap		dd ?	;object page map table offset.
LE_IterateMap		dd ?	;object iterate data map offset.
LE_Resource		dd ?	;resource table offset
LE_ResourceNum		dd ?	;resource table entries.
LE_ResidentNames	dd ?	;resident names table offset.
LE_EntryTable		dd ?	;entry table offset.
LE_Directives		dd ?	;module directives table offset.
LE_DirectivesNum	dd ?	;module directives entries.
LE_Fixups		dd ?	;fixup page table offset.
LE_FixupsRec		dd ?	;fixup record table offset.
LE_ImportModNames	dd ?	;imported module name table offset.
LE_ImportModNum	dd ?	;imported modules count.
LE_ImportNames		dd ?	;imported procedures name table offset.
LE_PageChk		dd ?	;per-page checksum table offset.
LE_Data		dd ?	;data pages offset.
LE_PreLoadNum		dd ?	;pre-load page count.
LE_NoneRes		dd ?	;non-resident names table offset.
LE_NoneResSize		dd ?	;non-resident names table length.
LE_NoneResChk		dd ?	;non-resident names checksum.
LE_AutoDS		dd ?	;automatic data object.
LE_Debug		dd ?	;debug information offset.
LE_DebugSize		dd ?	;debug information size.
LE_PreLoadInstNum	dd ?	;pre-load instance pages number.
LE_DemandInstNum	dd ?	;demand instance pages number.
LE_HeapExtra		dd ?	;extra heap alloction.
LE_Reserved		db 20 dup (?) ;reserved.
LE_DeviceID		dw ?	;device ID (Windows VxD only).
LE_DDK		dw ?	;DDK version number.
LE_Header		ends


;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
;LE object format.
;
LE_OBJ		struc
LE_OBJ_Size		dd ?	;virtual size in bytes.
LE_OBJ_Base		dd ?	;relocation base address.
;
LE_OBJ_Flags		dd ?	;object flags.
LE_OBJ_Flags_Read	equ 1	;Readable.
LE_OBJ_Flags_Write	equ 2	;Writeable.
LE_OBJ_Flags_Exec	equ 4	;Executable.
LE_OBJ_Flags_Res	equ 8	;Resource.
LE_OBJ_Flags_Discard	equ 16	;Discardable.
LE_OBJ_Flags_Shared	equ 32	;Shared.
LE_OBJ_Flags_PreLoad	equ 64	;Preload.
LE_OBJ_Flags_Invalid	equ 128	;Invalid.
LE_OBJ_Flags_FillMsk	equ 256+512	;Mask for fill type bits.
LE_OBJ_Flags_Normal	equ 0	;Normal fill type.
LE_OBJ_Flags_Zero	equ 256	;Zero filled.
LE_OBJ_Flags_Res1	equ 512	;resident.
LE_OBJ_Flags_Res2	equ 256+512	;resident/contiguous.
LE_OBJ_Flags_LongLoc	equ 1024	;long lockable.
LE_OBJ_Flags_16Alias	equ 4096	;16:16_ALIAS
LE_OBJ_Flags_Big	equ 8192	;"BIG" (Huge: 32-bit)
LE_OBJ_Flags_Conform	equ 16384	;Conforming.
LE_OBJ_Flags_IOPriv	equ 32768	;"OBJECT_I/O_PRIVILEGE_LEVEL
;
LE_OBJ_PageIndex	dd ?	;page map index.
LE_OBJ_PageNum		dd ?	;page map entries.
LE_OBJ_Reserved	db 4 dup (0)	;reserved.
LE_OBJ		ends


;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
;Somewhere to load the LE header.
;
LEHeader	LE_Header <>

LETemp	db 256 dup (0)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?