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