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

📄 _pm.asm

📁 Uboot源码,非常通用的bootloader.适用于各种平台的Linux系统引导.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;****************************************************************************;*;*                  SciTech OS Portability Manager Library;*;*  ========================================================================;*;*    The contents of this file are subject to the SciTech MGL Public;*    License Version 1.0 (the "License"); you may not use this file;*    except in compliance with the License. You may obtain a copy of;*    the License at http://www.scitechsoft.com/mgl-license.txt;*;*    Software distributed under the License is distributed on an;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or;*    implied. See the License for the specific language governing;*    rights and limitations under the License.;*;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.;*;*    The Initial Developer of the Original Code is SciTech Software, Inc.;*    All Rights Reserved.;*;*  ========================================================================;*;* Language:    80386 Assembler, TASM 4.0 or NASM;* Environment: IBM PC Real mode and 16/32 bit protected mode;*;* Description: Low level assembly support for the PM library specific to;*              MSDOS.;*;****************************************************************************        IDEALinclude "scitech.mac"               ; Memory model macrosheader      _pmdos                  ; Set up memory modelbegdataseg  _pmdosifndef  flatmodelstruc   rmregs_sax          dw  ?ax_high     dw  ?bx          dw  ?bx_high     dw  ?cx          dw  ?cx_high     dw  ?dx          dw  ?dx_high     dw  ?si          dw  ?si_high     dw  ?di          dw  ?di_high     dw  ?cflag       dw  ?cflag_high  dw  ?ends    rmregs_sRMREGS  = (rmregs_s PTR es:bx)struc   rmsregs_ses      dw  ?cs      dw  ?ss      dw  ?ds      dw  ?ends    rmsregs_sRMSREGS = (rmsregs_s PTR es:bx)endif   ; !flatmodelifdef flatmodel    cextern _PM_savedDS,USHORT    cextern _PM_VXD_off,UINT    cextern _PM_VXD_sel,UINTifdef   DOS4GW    cextern _PM_haveCauseWay,UINTendifendifintel_id        db  "GenuineIntel"  ; Intel vendor IDPMHELP_GETPDB       EQU 0026hPMHELP_FLUSHTLB     EQU 0027henddataseg  _pmdosP586begcodeseg  _pmdos                  ; Start of code segmentifndef  flatmodel;----------------------------------------------------------------------------; void PM_callRealMode(unsigned s,unsigned o, RMREGS *regs,;   RMSREGS *sregs);----------------------------------------------------------------------------; Calls a real mode procedure, loading the appropriate registers values; from the passed in structures. Only the DS and ES register are loaded; from the SREGS structure.;----------------------------------------------------------------------------cprocstart  PM_callRealMode        ARG     s:WORD, o:WORD, regs:DWORD, sregs:DWORD        LOCAL   addr:DWORD, bxVal:WORD, esVal:WORD, flags:WORD = LocalSize        enter_c        push    ds        push    es        mov     ax,[o]              ; Build the address to call in 'addr'        mov     [WORD addr],ax        mov     ax,[s]        mov     [WORD addr+2],ax        les     bx,[sregs]        mov     ax,[RMSREGS.ds]        mov     ds,ax               ; DS := passed in value        mov     ax,[RMSREGS.es]        mov     [esVal],ax        les     bx,[regs]        mov     ax,[RMREGS.bx]        mov     [bxVal],ax        mov     ax,[RMREGS.ax]      ; AX := passed in value        mov     cx,[RMREGS.cx]      ; CX := passed in value        mov     dx,[RMREGS.dx]      ; DX := passed in value        mov     si,[RMREGS.si]      ; SI := passed in value        mov     di,[RMREGS.di]      ; DI := passed in value        push    bp        push    [esVal]        pop     es                  ; ES := passed in value        mov     bx,[bxVal]          ; BX := passed in value        call    [addr]              ; Call the specified routine        pushf                       ; Save flags for later        pop     [flags]        pop     bp        push    es        pop     [esVal]        push    bx        pop     [bxVal]        les     bx,[sregs]        push    ds        pop     [RMSREGS.ds]        ; Save value of DS        push    [esVal]        pop     [RMSREGS.es]        ; Save value of ES        les     bx,[regs]        mov     [RMREGS.ax],ax      ; Save value of AX        mov     [RMREGS.cx],cx      ; Save value of CX        mov     [RMREGS.dx],dx      ; Save value of DX        mov     [RMREGS.si],si      ; Save value of SI        mov     [RMREGS.di],di      ; Save value of DI        mov     ax,[flags]          ; Return flags        and     ax,1h               ; Isolate carry flag        mov     [RMREGS.cflag],ax   ; Save carry flag status        mov     ax,[bxVal]        mov     [RMREGS.bx],ax      ; Save value of BX        pop     es        pop     ds        leave_c        retcprocendendif;----------------------------------------------------------------------------; void PM_segread(PMSREGS *sregs);----------------------------------------------------------------------------; Read the current value of all segment registers;----------------------------------------------------------------------------cprocstartdll16 PM_segread        ARG     sregs:DPTR        enter_c        mov     ax,es        _les    _si,[sregs]        mov     [_ES _si],ax        mov     [_ES _si+2],cs        mov     [_ES _si+4],ss        mov     [_ES _si+6],ds        mov     [_ES _si+8],fs        mov     [_ES _si+10],gs        leave_c        retcprocend; Create a table of the 256 different interrupt calls that we can jump; intoifdef   USE_NASM%assign intno 0intTable:%rep    256        db      0CDh        db      intno%assign intno   intno + 1        ret        nop%endrepelseintno = 0intTable:        REPT    256        db      0CDh        db      intnointno = intno + 1        ret        nop        ENDMendif;----------------------------------------------------------------------------; _PM_genInt    - Generate the appropriate interrupt;----------------------------------------------------------------------------cprocnear   _PM_genInt        push    _ax                     ; Save _ax        push    _bx                     ; Save _bxifdef flatmodel        mov     ebx,[UINT esp+12]       ; EBX := interrupt numberelse        mov     bx,sp                   ; Make sure ESP is zeroed        mov     bx,[UINT ss:bx+6]       ; BX := interrupt numberendif        mov     _ax,offset intTable     ; Point to interrupt generation table        shl     _bx,2                   ; _BX := index into table        add     _ax,_bx                 ; _AX := pointer to interrupt codeifdef flatmodel        xchg    eax,[esp+4]             ; Restore eax, and set for intelse        mov     bx,sp        xchg    ax,[ss:bx+2]            ; Restore ax, and set for intendif        pop     _bx                     ; restore _bx        retcprocend;----------------------------------------------------------------------------; int PM_int386x(int intno, PMREGS *in, PMREGS *out,PMSREGS *sregs);----------------------------------------------------------------------------; Issues a software interrupt in protected mode. This routine has been; written to allow user programs to load CS and DS with different values; other than the default.;----------------------------------------------------------------------------cprocstartdll16 PM_int386x        ARG     intno:UINT, inptr:DPTR, outptr:DPTR, sregs:DPTR        LOCAL   flags:UINT, sv_ds:UINT, sv_esi:ULONG = LocalSize        enter_c        push    ds        push    es                  ; Save segment registers        push    fs        push    gs        _lds    _si,[sregs]         ; DS:_SI -> Load segment registers        mov     es,[_si]        mov     bx,[_si+6]        mov     [sv_ds],_bx         ; Save value of user DS on stack        mov     fs,[_si+8]        mov     gs,[_si+10]        _lds    _si,[inptr]         ; Load CPU registers        mov     eax,[_si]        mov     ebx,[_si+4]        mov     ecx,[_si+8]        mov     edx,[_si+12]        mov     edi,[_si+20]        mov     esi,[_si+16]        push    ds                  ; Save value of DS        push    _bp                 ; Some interrupts trash this!        clc                         ; Generate the interrupt        push    [UINT intno]        mov     ds,[WORD sv_ds]     ; Set value of user's DS selector        call    _PM_genInt        pop     _bp                 ; Pop intno from stack (flags unchanged)        pop     _bp                 ; Restore value of stack frame pointer        pop     ds                  ; Restore value of DS        pushf                       ; Save flags for later        pop     [UINT flags]        push    esi                 ; Save ESI for later        pop     [DWORD sv_esi]        push    ds                  ; Save DS for later        pop     [UINT sv_ds]        _lds    _si,[outptr]        ; Save CPU registers        mov     [_si],eax        mov     [_si+4],ebx        mov     [_si+8],ecx        mov     [_si+12],edx        push    [DWORD sv_esi]        pop     [DWORD _si+16]        mov     [_si+20],edi        mov     _bx,[flags]         ; Return flags        and     ebx,1h              ; Isolate carry flag        mov     [_si+24],ebx        ; Save carry flag status        _lds    _si,[sregs]         ; Save segment registers        mov     [_si],es        mov     _bx,[sv_ds]        mov     [_si+6],bx          ; Get returned DS from stack        mov     [_si+8],fs        mov     [_si+10],gs        pop     gs                  ; Restore segment registers        pop     fs        pop     es        pop     ds        leave_c        retcprocend

⌨️ 快捷键说明

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