loadle.asm

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

ASM
2,013
字号
        mov     ecx,es:[esi]            ;get number of entries.
        add     DWORD PTR es:[esi+4],4+2        ;correct module name pointer.
        add     esi,4+4
load1_exp0:
        push    ecx
        push    esi
        push    edx
        mov     esi,es:[esi]            ;point to this entry.
        xor     ebp,ebp
        xchg    bp,WORD PTR es:[esi+4]  ;get & clear ordinal.
        dec     ebp
load1_exp1:     mov     bh,es:[edx]             ;get bundle count.
        or      bh,bh
        jz      load1_bad_entry
        mov     bl,es:[edx+1]   ;get bundle type.
        add     edx,2
        mov     edi,edx         ;point to object number incase we need it.
        xor     eax,eax
        mov     al,0
        cmp     bl,0
        jz      load1_exp2
        add     edx,2           ;skip object number.
        mov     al,3
        cmp     bl,1
        jz      load1_exp2
        mov     al,5
        cmp     bl,2
        jz      load1_exp2
        mov     al,5
        cmp     bl,3
        jz      load1_exp2
        mov     al,7
        cmp     bl,4
        jz      load1_exp2
        jmp     load1_bad_entry
load1_exp2:     ;
load1_exp3:     or      bh,bh
        jz      load1_exp1              ;end of this bundle.
        or      ebp,ebp         ;our ordinal?
        jz      load1_exp4
        add     edx,eax         ;next entry.
        dec     ebp
        dec     bh
        jmp     load1_exp3
        ;
load1_exp4:     or      bl,bl
        jz      load1_bad_entry
        dec     bl
        jz      load1_exp_16bit
        dec     bl

IFDEF DEBUG4X
        jz      load1_bad_fixup1
ENDIF

        jz      load1_bad_fixup
        dec     bl
        jz      load1_exp_32bit
        dec     bl
        jz      load1_bad_entry
        jmp     load1_bad_entry
        ;
load1_bad_entry:
        pop     edx
        pop     esi
        pop     ecx

IFDEF DEBUG4X
        push    eax
        push    ebx
        push    ecx
        push    edx
        push    ds
        push    cs
        pop     ds
        cmp     bl,4
        jae     debugf2ae10
        mov     edx,OFFSET debugf2textl10
        jmp     debugf2loop2
debugf2ae10:
        mov     edx,OFFSET debugf2textae10
debugf2loop2:
        cmp     BYTE PTR ds:[edx],0
        je      debugf2b
        mov     ecx,1
        mov     bx,1
        mov     ah,40h
        int     21h
        inc     edx
        jmp     debugf2loop2
debugf2b:
        mov     edx,OFFSET debugf2textcrlf
        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     debugf2out

debugf2textl10  DB      '<10',0
debugf2textae10 DB      '>=10',0
debugf2textcrlf DB      13,10

debugf2out:
        jmp     load1_bad_fixup2
ENDIF

        jmp     load1_bad_fixup
        ;
load1_exp_16bit:        movzx   eax,WORD PTR es:[edi]   ;get the object number.
        dec     eax
        shl     ax,3
        add     ax,w[load1_Segs]
        mov     es:[esi+4],ax
        movzx   eax,WORD PTR es:[edx+1] ;get the offset.
        mov     es:[esi],eax
        jmp     load1_exp8
        ;
load1_exp_32bit:        movzx   eax,WORD PTR es:[edi]
        dec     eax
        push    eax
        shl     eax,2
        mov     ebx,eax
        add     ebx,ebx
        shl     eax,2
        add     ebx,eax
        add     ebx,d[load1_ObjMem]
        mov     ebx,es:LE_OBJ.LE_OBJ_Base[ebx]
        pop     eax
        shl     ax,3
        add     ax,w[load1_Segs]
        mov     es:[esi+4],ax
        mov     eax,es:[edx+1]
        add     eax,ebx
        mov     es:[esi],eax
;       jmp     load1_exp8      ; MED 02/03/2003, superfluous
        ;
load1_exp8:
        pop     edx
        pop     esi
        pop     ecx
        add     esi,4
        dec     ecx
        jnz     load1_exp0
        ;
        mov     esi,edx
        sys     RelMemLinear32
;
;Read program objects.
;
load1_NoEntries:
        mov     ebp,d[LE_Header.LE_ObjNum+LEHeader]     ;number of objects.
        mov     esi,d[load1_ObjMem]

load1_load0:
        mov     eax,es:LE_OBJ.LE_OBJ_Flags[esi] ;get objects flags.
        and     eax,LE_OBJ_Flags_FillMsk        ;isolate fill type.
        cmp     eax,LE_OBJ_Flags_Zero   ;zero filled?
        jnz     load1_load1
        ;
        ;Zero this objects memory.
        ;
        mov     ecx,es:LE_OBJ.LE_OBJ_Size[esi]  ;get objects virtual length.
        mov     edi,es:LE_OBJ.LE_OBJ_Base[esi]
        xor     eax,eax
        push    ecx
        and     ecx,3
        rep     stosb
        pop     ecx
        shr     ecx,2
        rep     stosd
        ;
load1_load1:    ;Set file offset for data.
        ;
        mov     eax,es:LE_OBJ.LE_OBJ_PageIndex[esi] ;get first page index.
        dec     eax

;       mul     d[LE_Header.LE_PageSize+LEHeader]       ;* page size.
TempAddress     =       LE_Header.LE_PageSize
TempAddress     =       TempAddress+LEHeader
        mul     DWORD PTR [TempAddress] ;* page size.

        add     eax,d[LE_Header.LE_Data+LEHeader]       ;data offset.
        mov     dx,ax
        shr     eax,16
        mov     cx,ax
        mov     ax,4200h
        mov     bx,w[load1_Handle]
        int     21h             ;set the file pointer.
        ;
        ;Work out how much data we're going to load.
        ;
        mov     eax,es:LE_OBJ.LE_OBJ_PageNum[esi] ;get number of pages.
        mov     ebx,eax

;       mul     d[LE_Header.LE_PageSize+LEHeader]       ;* page size.
TempAddress     =       LE_Header.LE_PageSize
TempAddress     =       TempAddress+LEHeader
        mul     DWORD PTR [TempAddress] ;* page size.

        mov     edx,es:LE_OBJ.LE_OBJ_Base[esi]  ;get load address.
        xor     ecx,ecx
        or      eax,eax
        jz      load1_loadz
        mov     ecx,es:LE_OBJ.LE_OBJ_Size[esi]

        add     ebx,es:LE_OBJ.LE_OBJ_PageIndex[esi] ;get base page again.
        dec     ebx
        cmp     ebx,d[LE_Header.LE_Pages+LEHeader]      ;we getting the last page?
        jnz     load1_load2
        mov     ebx,d[LE_Header.LE_PageSize+LEHeader]
        sub     ebx,d[LE_Header.LE_LastBytes+LEHeader]
        sub     eax,ebx

load1_load2:
        cmp     ecx,eax
        jc      load1_load3
        mov     ecx,eax
        ;
load1_load3:    ;Load the data.
        ;
        mov     bx,w[load1_Handle]
        push    ds
        push    es
        pop     ds
        call    ReadFile
        pop     ds
        jc      load1_file_error
        cmp     eax,ecx
        jnz     load1_file_error
        ;
ZeroNotLoaded:
        ;Zero any memory we didn't just load to for Watcom's BSS benefit.
        ;
        cmp     ecx,es:LE_OBJ.LE_OBJ_Size[esi]
        jnc     load1_load4
        push    edi
        mov     edi,edx
        add     edi,ecx
        sub     ecx,es:LE_OBJ.LE_OBJ_Size[esi]
        neg     ecx
        xor     eax,eax
        push    ecx
        shr     ecx,2
        or      ecx,ecx
        jz      load1_load6
load1_load5:
        mov     es:[edi],eax
        add     edi,4
        dec     ecx
        jnz     load1_load5
load1_load6:
        pop     ecx
        and     ecx,3
        rep     stosb
        pop     edi
        ;
load1_load4:    ;Next object.

load1_loadz:
        ;
        add     esi,size LE_OBJ
        dec     ebp
        jnz     load1_load0
;
;Get fixup table memory & load fixups.
;
        mov     ecx,d[LE_Header.LE_FixupSize+LEHeader]
        sys     GetMemLinear32  ;Get memory.
        jc      load1_mem_error         ;Not enough memory.
        mov     d[load1_FixupMem],esi
        push    ecx
        mov     ecx,d[LE_Header.LE_Fixups+LEHeader]
        add     ecx,d[load1_LEOffset]
        mov     dx,cx
        shr     ecx,16
        mov     bx,w[load1_Handle]
        mov     ax,4200h
        int     21h             ;move to fixup data.
        pop     ecx
        mov     edx,esi
        push    ds
        mov     ds,apiDSeg
        assume ds:_cwMain
        mov     ds,RealSegment
        assume ds:_apiCode
        call    ReadFile
        pop     ds
        jc      load1_file_error
        cmp     eax,ecx
        jnz     load1_file_error
;
;Get IMPORT module name links.
;
        mov     ecx,d[LE_Header.LE_ImportModNum+LEHeader]
        or      ecx,ecx
        jz      load1_GotImpMods
        shl     ecx,2
        add     ecx,4
        sys     GetMemLinear32
        jc      load1_mem_error
        mov     DWORD PTR es:[esi],0            ;clear entry count for now.
        push    es
        mov     es,w[load1_PSP]
        mov     DWORD PTR es:[EPSP_Struc.EPSP_Imports],esi
        pop     es
        mov     d[load1_ModLink],esi
        ;
        ;Work out offset in fixup data.
        ;
        mov     esi,d[LE_Header.LE_ImportModNames+LEHeader]
        sub     esi,d[LE_Header.LE_Fixups+LEHeader]
        add     esi,d[load1_FixupMem]
        ;
        ;Work through each name getting the module link address.
        ;
load1_NextModLnk:
;       cmp     d[LE_ImportModNum+LEHeader],0
TempAddress     =       LE_Header.LE_ImportModNum
TempAddress     =       TempAddress+LEHeader
        cmp     DWORD PTR [TempAddress],0

        jz      load1_GotImpMods
        ;
        ;Preserve current header state.
        ;

        push    esi
        mov     ecx,size LE_Header
        sys     GetMemLinear32
        mov     ebp,esi
        pop     esi
        jc      load1_mem_error
        mov     edi,ebp
        push    esi
        mov     esi,offset LEHeader
        rep     movsb
        pop     esi

        ;
        ;Search for this name.
        ;

        call    FindModule
        jc      load1_error

        ;
        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[load1_ModLink]
        mov     eax,es:[edx]            ;get current count.
        shl     eax,2
        add     eax,4
        mov     es:[edx+eax],edi        ;store link address.
        inc     DWORD PTR es:[edx]              ;update link count.
        ;
        movzx   ecx,BYTE PTR es:[esi]
        inc     ecx
        add     esi,ecx

;       dec     d[LE_ImportModNum+LEHeader]
TempAddress     =       LE_Header.LE_ImportModNum
TempAddress     =       TempAddress+LEHeader
        dec     DWORD PTR [TempAddress]

        jmp     load1_NextModLnk

;
;Apply the fixups.
;
load1_GotImpMods:
        mov     eax,d[LE_Header.LE_ObjNum+LEHeader]
        mov     d[load1_ObjCount],eax
        mov     eax,d[load1_ObjMem]
        mov     d[load1_ObjBase],eax
        mov     d[load1_EntryEIP],0
load1_fix0:     ;
        mov     esi,d[load1_ObjBase]
        mov     ecx,es:LE_OBJ.LE_OBJ_PageNum[esi]
        or      ecx,ecx
        jz      load1_fix400
        mov     d[load1_PageCount],ecx
        mov     d[load1_PageCount+4],0
        mov     edx,es:LE_OBJ.LE_OBJ_PageIndex[esi]
        dec     edx
        mov     ebp,edx         ;Set base page map entry.
load1_fix1:     ;
        mov     edx,ebp
        mov     esi,d[load1_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      load1_fix4

        mov     esi,d[load1_FixupMem]
        add     esi,d[LE_Header.LE_FixupsRec+LEHeader] ;Point to fixup data.
        sub     esi,d[LE_Header.LE_Fixups+LEHeader]
        add     esi,edx         ;Move to start of this pages fixups.
load1_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
        jz      CheckUnknown

IFDEF DEBUG4X
        jnz     load1_bad_fixup3
ENDIF

        jnz     load1_bad_fixup
        ;

IFDEF DEBUG4X
        test    dh,011010b              ;Check for un-known bits.
        jnz     load1_bad_fixup9
ENDIF


; added support for additive bit, MED 06/10/96
;       test    dh,011011b              ;Check for un-known bits.
CheckUnknown:
        test    dh,011010b              ;Check for un-known bits.
        jnz     load1_bad_fixup

        or      dl,dl           ;Check it's an internal target.
        jnz     load1_fixup_import

        cmp     bh,0010b                ;Word segment?
        jz      load1_Seg16
        cmp     bh,0111b                ;32-bit offset?
        jz      load1_32BitOff
        cmp     bh,0110b                ;Seg:32-bit offset?
        jz      load1_Seg1632BitOff
        cmp     bh,1000b                ;32-bit self relative?
        jz      load1_Self32Off
        cmp     bh,0101b                ;16-bit offset?
        jz      load1_16BitOff

; MED 12/09/96
        cmp     bh,1                    ; ignore fixup ???
        je      load1_fix3

IFDEF DEBUG4X
        jmp     load1_bad_fixup4
        cmp     bh,1
        jne     around
;       add     esi,4
;       sub     ecx,4
        jmp     load1_fix3
around:
ENDIF

        jmp     load1_bad_fixup
;
;Fetch an external referance.
;
load1_fixup_import:
        ;
        ;Grab the page offset.
        ;
        movsx   edi,WORD PTR es:[esi]
        add     esi,2
        sub     ecx,2
        ;
        ;Check import type.

⌨️ 快捷键说明

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