⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;
; Copyright (C) 1996-2002 Supernar Systems, Ltd. All rights reserved.
;
; Redistribution  and  use  in source and  binary  forms, with or without
; modification,  are permitted provided that the following conditions are
; met:
;
; 1.  Redistributions  of  source code  must  retain  the above copyright
; notice, this list of conditions and the following disclaimer.
;
; 2.  Redistributions  in binary form  must reproduce the above copyright
; notice,  this  list of conditions and  the  following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; 3. The end-user documentation included with the redistribution, if any,
; must include the following acknowledgment:
;
; "This product uses DOS/32 Advanced DOS Extender technology."
;
; Alternately,  this acknowledgment may appear in the software itself, if
; and wherever such third-party acknowledgments normally appear.
;
; 4.  Products derived from this software  may not be called "DOS/32A" or
; "DOS/32 Advanced".
;
; THIS  SOFTWARE AND DOCUMENTATION IS PROVIDED  "AS IS" AND ANY EXPRESSED
; OR  IMPLIED  WARRANTIES,  INCLUDING, BUT  NOT  LIMITED  TO, THE IMPLIED
; WARRANTIES  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED.  IN  NO  EVENT SHALL THE  AUTHORS  OR  COPYRIGHT HOLDERS BE
; LIABLE  FOR  ANY DIRECT, INDIRECT,  INCIDENTAL,  SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF
; SUBSTITUTE  GOODS  OR  SERVICES;  LOSS OF  USE,  DATA,  OR  PROFITS; OR
; BUSINESS  INTERRUPTION) HOWEVER CAUSED AND  ON ANY THEORY OF LIABILITY,
; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
; OTHERWISE)  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
;

;*****************************************************************************
; DOS/32A 32-bit application loader (LE/LX style file formats)
;
;*****************************************************************************

PushState

APP_MAXOBJECTS	= 64


.386p
;=============================================================================
load_le_app:
	mov	_app_type,0
	jmp	load_application

load_lx_app:
	mov	_app_type,1
	jmp	load_application

load_lc_app:
	mov	_app_type,2


;=============================================================================
load_application:
	call	load_header		; load 'LE'/'LX' exec header
	call	verbose_showloadhdr
	mov	ecx,1			; start with Object #1
@@1:	call	load_object		; load object
	call	create_selector		; allocate selector for loaded object
	call	verbose_showloadobj
	push	edx			; save Object Selector/Object Flags
	push	edi			; save Address of loaded Object
	push	esi			; save Page Table Index
	push	ebx			; save # Page Table Entries
	inc	cx			; increment Current_Object#
	cmp	cx,word ptr _app_num_objects
	jbe	@@1			; loop until all objects are loaded
	call	preload_fixups		; preload fixup tables and records
	mov	ebp,esp			; base pointer to last loaded Object
	mov	ebx,_app_num_objects	; number of Objects
	dec	bx
	shl	bx,4
	mov	_app_tmp_addr1,ebx
@@4:	call	relocate_object
	sub	bx,10h
	jnc	@@4
	call	unload_fixups		; free allocated memory for fixups
	call	close_exec		; close file
	mov	esp,_sel_esp
	call	verbose_showstartup
	jmp	enter_32bit_code



;-----------------------------------------------------------------------------
load_header:
	mov	ecx,0A8h		; load 'LE' header
	mov	edx,04h
	mov	_err_code,3002h		; "error in app file"
	cmp	_app_type,2
	jz	load_lc_header

	call	load_fs_block
	mov	edx,_exec_start

	mov	ax,fs:[0010h]		; get Module Flags
	and	ax,2000h		; check if not-loadable;/no-fixups
	mov	ax,3005h
	jnz	file_error
	mov	ax,fs:[0044h]		; get # Objects
	mov	cx,ax
	cmp	ax,APP_MAXOBJECTS
	mov	ax,4001h		; "too many objects"
	ja	file_error
	mov	_app_num_objects,ecx

	mov	eax,fs:[0040h]		; get Object Table Offset
	add	eax,edx
	mov	_app_off_objects,eax
	mov	eax,fs:[0048h]		; get Object PageTable Offset
	add	eax,edx
	mov	_app_off_objpagetab,eax
	mov	eax,fs:[0068h]		; get Fixup PageTable Offset
	add	eax,edx
	mov	_app_off_fixpagetab,eax
	mov	eax,fs:[006Ch]		; get Fixup Record Table Offset
	add	eax,edx
	mov	_app_off_fixrectab,eax
	mov	eax,fs:[0080h]		; get Data Pages Offset
	add	_app_off_datapages,eax

	mov	eax,fs:[0018h]		; get EIP Object #
	mov	_app_eip_object,eax
	mov	eax,fs:[0020h]		; get ESP Object #
	mov	_app_esp_object,eax
	mov	eax,fs:[001Ch]		; get EIP
	mov	_app_eip,eax
	mov	eax,fs:[0024h]		; get ESP
	mov	_app_esp,eax
	mov	eax,fs:[0030h]		; get Fixup Records Size
	mov	_app_siz_fixrecstab,eax
	mov	eax,fs:[002Ch]		; get Bytes on Last Page (LE-only)
	mov	_app_siz_lastpage,eax

	mov	eax,0FFFh
	cmp	_app_type,0
	jz	@@done
	mov	ax,1
	mov	cx,fs:[002Ch]		; get Page Offset Shift for LX-type
	shl	ax,cl			; max shift is 15 (8000h-1)
	dec	ax

@@done:	mov	_app_off_pageshift,eax
	ret



;-----------------------------------------------------------------------------
load_object:
	push	ecx
	cmp	_app_type,2
	jz	load_lc_object

	mov	_err_code,3002h		; "error in app file"
	mov	edx,_app_off_objects
	call	seek_from_start		; move to object header
	mov	ecx,18h
	xor	edx,edx
	call	load_fs_block		; load object header
	add	_app_off_objects,eax

	mov	edx,_app_off_datapages	; get Data_Pages_Offset
	call	seek_from_start		; move to object data
	mov	eax,fs:[0000h]		; get Virtual_Size[Object]
	mov	ebx,fs:[0010h]		; get # Page Table Entries
	mov	ecx,fs:[0008h]		; get Flags[Object]
	mov	esi,fs:[000Ch]		; get Page Table Index

	push	ecx			; save Object Flags
	call	alloc_block		; allocate EAX memory block to EDI
	mov	ecx,eax			; ECX = bytes to read
	mov	ebp,eax			; EBP = preserve Virtual Size
	mov	edx,edi			; EDX = addres to read to
	call	fill_zero_pages		; fill allocated memory with zeroes

	mov	eax,ebx
	test	eax,eax			; check if # Page Table Entries = 0
	jz	@@5			; if yes, skip loading
	shl	eax,12			; convert # Page Table Entries to bytes
	cmp	eax,ecx			; check if # bytes >= bytes to load
	jae	@@1			; if yes, jump
	mov	ecx,eax			; else adjust number of bytes to read

@@1:	mov	ax,[esp+4]		; get Object #
	cmp	ax,word ptr _app_num_objects
	jnz	@@3
	cmp	_app_type,0
	jnz	@@2
	lea	ecx,[ebx-1]		; load LE-style Last Object (BSS)
	shl	ecx,12
	add	ecx,_app_siz_lastpage
	jmp	@@3
@@2:	mov	ecx,ebx			; load LX-style Last Object (BSS)
	shl	ecx,12

@@3:	mov	_err_code,3002h		; "error in app file"
	call	load_gs_block		; load object data
	mov	eax,ecx
	mov	edx,_app_off_pageshift
	test	eax,edx
	jz	@@4
	mov	ecx,edx
	not	edx
	and	eax,edx
	lea	eax,[eax+ecx+1]
@@4:	add	_app_off_datapages,eax

@@5:	pop	edx			; restore Object Flags
@@done:	pop	ecx
	ret




;=============================================================================
relocate_object:
	xor	eax,eax
	cmp	eax,[ebp+ebx+0]		; get # Page Table Entries[Object]
	jnz	@@0			; if zero, done
	ret
@@0:	cmp	_app_type,0
	jnz	relocate_lx_object

relocate_le_object:
	mov	ecx,[ebp+ebx+4]		; get Page Table Index
	mov	edx,_app_off_objpagetab	; get Object Page Table Offset in exec
	lea	edx,[ecx*4+edx-4]
	mov	_err_code,3002h		; "error in app file"
	call	seek_from_start		; *1) move file ptr
@@1:	push	eax			; EAX = counter
	mov	ecx,4
	xor	edx,edx
	mov	_err_code,3002h		; "error in app file"
	call	load_fs_block		; load block
	xor	ecx,ecx			; get index into FixupPageTab
	mov	ch,fs:[0001h]
	mov	cl,fs:[0002h]
	jcxz	@@2
	mov	eax,_app_off_fixpagetab	; get Fixup Page Table Offset
	lea	eax,[ecx*4+eax-4]
	mov	esi,gs:[eax+00h]	; get offset of 1st fixup table
	mov	ecx,gs:[eax+04h]	; get offset of 2nd fixup table
	sub	ecx,esi			; calculate size of 1st tab
	jz	@@2			; if 1st == 2nd, no fixups
	add	esi,_app_off_fixrectab	; get Fixup Record Table Offset
;	sub	esi,_seg_ds_base
	mov	edi,[esp]		; get current page number
	shl	edi,12
	add	edi,[ebp+ebx+8]		; address of page target to fix in mem
	add	ecx,esi
	call	apply_fixups		; patch target with fixup data
@@2:	pop	eax
	inc	ax
	cmp	ax,word ptr [ebp+ebx+0]
	jb	@@1
	ret

relocate_lx_object:
	mov	ecx,[ebp+ebx+4]		; get Page Table Index
	mov	edx,_app_off_fixpagetab	; get Fixup Page Table Offset
	lea	edx,[ecx*4+edx-4]
@@1:	push	eax edx			; EAX = counter
	mov	esi,gs:[edx+00h]	; get offset of 1st fixup table
	mov	ecx,gs:[edx+04h]	; get offset of 2nd fixup table
	sub	ecx,esi			; calculate size of 1st tab
	jz	@@2			; if 1st == 2nd, no fixups
	add	esi,_app_off_fixrectab	; get Fixup Record Table Offset
;	sub	esi,_seg_ds_base
	mov	edi,[esp+4]		; get current page number
	shl	edi,12
	add	edi,[ebp+ebx+8]		; address of page target to fix in mem
	add	ecx,esi
	call	apply_fixups		; patch target with fixup data
@@2:	pop	edx eax
	add	edx,4
	inc	ax
	cmp	ax,word ptr [ebp+ebx+0]
	jb	@@1
	ret



;=============================================================================
apply_fixups:
@@0:	push	ecx edi
	mov	_err_code,4005h		; "unrecognized fixup data"
	mov	cx,gs:[esi+0]		; get SRC/FLAGS
	movsx	edx,word ptr gs:[esi+2]	; get SRCOFF
	movzx	eax,word ptr gs:[esi+4]	; get OBJNUM
	add	edi,edx			; calculate dest addr to be fixed
	test	cx,0F20h		; SrcLists/Imports not supported
	jnz	file_errorm		; jump if one of these
	test	cx,4000h		; test if 16bit object number
	jnz	@@1			; if yes, jump
	mov	ah,0
	dec	esi
@@1:	add	esi,6
	dec	eax			; Object Number - 1
	shl	eax,4
	mov	edx,_app_tmp_addr1
	sub	edx,eax
	jc	file_errorm
	mov	_app_tmp_addr2,edx
	mov	edx,[ebp+edx+8]		; EDX = Destination Object Address
	mov	al,cl
	and	al,0Fh
	cmp	al,02h			; check if 16bit Selector
	jz	@@3			; if yes, jump
	cmp	al,08h
	ja	file_errorm
	mov	eax,gs:[esi]
	test	cx,1000h		; check for Alias flag
	jnz	@@2			; if not, jump
	movzx	eax,ax
	sub	esi,2
@@2:	add	esi,4
@@3:	cmp	cl,07h
	jnz	@@4
	add	eax,edx
	mov	gs:[edi+0],eax
@@5:	pop	edi ecx
	cmp	esi,ecx
	jb	@@0
	ret
@@4:	push	si
	mov	si,cx

⌨️ 快捷键说明

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