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

📄 loader.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	and	si,0Fh
	add	si,si
	mov	_err_code,4006h		; "16bit fixup overflow"
	call	fix_tab[si]
	pop	si
	jmp	@@5

;
; EAX = Data
; EDX = Address of Object
; EDI = Address to Fixup
; EBP:EBX = Ptr to Current Object Table
;-----------------------------------------------------------------------------
fix_byte:
	mov	gs:[edi+0],al
	ret
fix_16off:
	mov	gs:[edi+0],ax
	ret
fix_32off:
	add	eax,edx
	mov	gs:[edi+0],eax
	ret
fix_32selfrel:
	add	eax,edx
	lea	ecx,[edi+4]
	sub	eax,ecx
	test	word ptr [ebp+ebx+12],2000h
	jnz	@@1
	lea	ecx,[eax+8002h]
	shr	ecx,16
	jnz	file_errorm
	mov	gs:[edi+0],ax
	ret
@@1:	mov	gs:[edi+0],eax
	ret
fix_16sel:
	call	check_range
	mov	gs:[edi+0],dx
	ret
fix_1616ptr:
	call	check_range
	mov	gs:[edi+0],ax
	mov	gs:[edi+2],dx
	ret
fix_1632ptr:
	add	eax,edx
	mov	gs:[edi+0],eax
	call	check_range
	mov	gs:[edi+4],dx
	ret
fix_invalid:
	mov	ax,4005h			; "unrecognized fixup data"
	jmp	file_error

check_range:
	test	word ptr [ebp+ebx+12],1000h	; check if 16:16 alias requird
	jnz	@@1				; if yes, jump
	test	cl,10h
	jnz	@@1
@@0:	mov	ecx,_app_tmp_addr2
	mov	dx,[ebp+ecx+14]			; get selector
	ret
@@1:	test	cl,10h
	jz	@@0
	mov	ecx,_app_tmp_addr2
	mov	dx,[ebp+ecx+14]			; get selector
	test	eax,0FFFF0000h			; check 64K range
	jnz	file_errorm
	ret


	evendata
fix_tab	label word
	dw	fix_byte		; 00h
	dw	fix_invalid		; 01h
	dw	fix_16sel		; 02h
	dw	fix_1616ptr		; 03h
	dw	fix_invalid		; 04h
	dw	fix_16off		; 05h
	dw	fix_1632ptr		; 06h
	dw	fix_32off		; 07h
	dw	fix_32selfrel		; 08h








;-----------------------------------------------------------------------------
; In:	ECX = size
; Out:	EDI = address
;
fill_zero_pages:
	push	es dx eax ecx edi
	push	gs
	pop	es
	mov	dl,cl
	shr	ecx,2
	xor	eax,eax
	rep	stos dword ptr es:[edi]
	mov	cl,dl
	and	cl,3
	rep	stos byte ptr es:[edi]
	pop	edi ecx eax dx es
	ret


;-----------------------------------------------------------------------------
; In:	EAX = size
; Out:	EDI = address
;
alloc_block:
	push	dx
	test	eax,eax			; if size of Object is zero
	jz	@@null			; then report a warning 9005
	mov	dl,_misc_byte		; get misc byte
	shr	dx,4			; get memory alloc bits in bit1,0
	and	dx,3			; mask them
	jz	@@00			; if 00b alloc scheme, jump
	dec	dx
	jz	@@01
	dec	dx
	jz	@@10
	dec	dx
	jz	@@11
@@done:	pop	dx
	ret
@@null:	push	ax si
	mov	si,[esp+0Ch]
	mov	ax,9005h
	call	report_error
	pop	si ax dx
	xor	edi,edi
	ret

;
; load 16bit/32bit -> low, then high, then error
;---------------------------------------
@@00:	call	alloc_dos_mem		; try to allocate DOS memory block
	jnc	@@done			; if allocated, jump
	mov	_err_code,4003h		; "not enough DPMI mem"
	call	alloc_dpmi_mem		; try to allocate DPMI memory block
	jnc	@@done			; if allocated, jump
	jmp	file_errorm		; if failed, error
;
; load 16bit -> low, then high, then error
; load 32bit -> high only, then error
;---------------------------------------
@@01:	test	cx,2000h		; check if 32bit Object
	jnz	@@01_1			; if yes, jump
	mov	_err_code,4002h		; "not enough DOS mem"
	call	alloc_dos_mem
	jnc	@@done			; if allocated, jump
@@01_1:	mov	_err_code,4003h		; "not enough DPMI mem"
	call	alloc_dpmi_mem
	jnc	@@done			; if allocated, jump
	jmp	file_errorm		; if failed, error
;
; load 16bit/32bit low, then error
;---------------------------------------
@@10:	mov	_err_code,4002h		; "not enough DOS mem"
	call	alloc_dos_mem
	jnc	@@done
	jmp	file_errorm		; if failed, error
;
; load 16bit/32bit high, then error
;---------------------------------------
@@11:	mov	_err_code,4003h		; "not enough DPMI mem"
	call	alloc_dpmi_mem
	jnc	@@done
	jmp	file_errorm		; if failed, error




;-----------------------------------------------------------------------------
alloc_dos_mem:
	push	eax ebp			; EAX = size to allocate
	add	eax,0Fh			; align size on para
	shr	eax,4
	test	eax,0FFFF0000h		; check high word of EAX
	stc
	jnz	@@done
	sub	esp,32h
	mov	ebp,esp
	mov	byte ptr [ebp+1Dh],48h	; DOS func: AH=48h
	mov	word ptr [ebp+10h],ax	; DOS BX=size
	call	int21h
	movzx	edi,word ptr [ebp+1Ch]	; get returned value in EAX
	shl	edi,4			; NOTE: addres is relative to 0
	bt	word ptr [ebp+20h],0	; check for errors
	lea	esp,[esp+32h]
@@done:	pop	ebp eax
	ret

;-----------------------------------------------------------------------------
alloc_dpmi_mem:
	push	esi ebx ecx edx eax
	mov	ebx,eax
	mov	ax,0FF91h		; allocate DPMI memory
	int	21h
	jc	@@done
	mov	eax,ebx
	xor	edx,edx
	test	_misc_byte2,00000100b	; check if para or page alignment
	jnz	@@l1
	test	al,0Fh
	jz	@@1
	jmp	@@l2
@@l1:	test	ax,0FFFh		; check if returned addr aligned
	jz	@@1			; on PAGE boundary, if yes, jump
@@l2:	test	_misc_byte2,00000100b
	jnz	@@l3
	add	ebx,0Fh
	and	bl,0F0h
	jmp	@@l4
@@l3:	add	ebx,0FFFh
	and	bx,0F000h		; align linear addr on PAGE boundary
@@l4:	sub	ebx,eax			; calculate difference
	mov	edx,ebx
	add	ebx,[esp]
	mov	ax,0FF93h		; resize DPMI memory block
	int	21h
	jc	@@done
@@1:	lea	edi,[ebx+edx]		; adjust linear address
	test	_misc_byte2,00000100b
	jnz	@@l5
	test	di,000Fh
	jmp	@@l6
@@l5:	test	di,0FFFh
@@l6:	stc
	jnz	@@done
	clc
@@done:	pop	eax edx ecx ebx esi
	ret



;-----------------------------------------------------------------------------
create_selector:
	push	ebx ecx edx esi edi
	mov	ax,dx
	mov	ecx,ebp			; ECX = Virtual Size[Object]
	mov	dx,_acc_rights		; default: PAGE, USE32, DATA
	test	al,0004h		; check if object is executable
	jz	@@1			; if not, jump
	or	dl,0008h		; set selector to Code
@@1:	test	ax,2000h		; check if object is 32bit
	jz	@@2			; if not, jump
	xor	edi,edi			; set base to Zero
	or	ecx,-1			; set limit to 4Gb

	test	al,0004h		; check if code or data Object
	mov	ax,_sel32_cs		; AX = 32bit code selector
	jnz	@@0			; if code, then jump
	mov	ax,_sel32_ss		; AX = 32bit data selector
@@0:	test	ax,ax			; check if already allocated
	jnz	@@4			; if yes, use this selector
	jmp	@@3

@@2:	and	dx,0BFFFh		; set selector to 16bit
@@3:	call	set_descriptor		; allocate selector
	jc	dpmi_error
@@4:	pop	edi esi
	mov	[esp+2],ax		; store selector in high word of EDX
	pop	edx ecx ebx
	mov	_app_buf_allocsel[ecx*2],ax
	mov	_app_buf_allocbase[ecx*4],edi

	cmp	cx,word ptr _app_eip_object; is Current_Object# == EIP_Object#
	jnz	@@l1			; if not, jump
	mov	_sel32_cs,ax
	mov	_unreloc_eip,edi
	test	dx,2000h		; check if Object is 32bit
	jz	@@l1			; if not, leave _APP_EIP as is
	add	_app_eip,edi

@@l1:	cmp	cx,word ptr _app_esp_object; is Current_Object# == ESP_Object#
	jnz	@@l2			; if not, jump
	mov	_sel32_ss,ax
	mov	_unreloc_esp,edi
	add	_app_esp,edi		; adjust ESP
@@l2:	ret


preload_fixups:
	cmp	_app_type,2
	jz	preload_lc_fixups

	mov	ebx,_app_siz_fixrecstab	; allocate memory for fixups
	mov	_app_load,0		; default load fixups low
	mov	ax,0FF95h
	int	21h
	jnc	@@1
	mov	_app_load,1		; try load fixups hi
	mov	al,91h
	int	21h
	mov	ax,4004h
	jc	file_error		; if not enough memory, error
@@1:	mov	_app_buf_fixrecstab,esi

	mov	_err_code,3002h		; "error in app file"
	mov	edx,_app_off_fixpagetab	; move file ptr to fixups
	call	seek_from_start
	mov	edx,ebx
	mov	ecx,_app_siz_fixrecstab
	call	load_gs_block

	mov	eax,_app_off_fixrectab
	mov	ebx,_app_off_fixpagetab
	sub	eax,ebx
	add	eax,edx
	mov	_app_off_fixpagetab,edx
	mov	_app_off_fixrectab,eax
	ret


unload_fixups:
	cmp	_app_type,2
	jz	unload_lc_fixups

	mov	esi,_app_buf_fixrecstab
	mov	ax,0FF96h
	cmp	_app_load,0
	jz	@@1
	mov	al,92h
@@1:	int	21h
	ret


PopState

⌨️ 快捷键说明

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