发信人: Reinhard.bbs@bbs.sjtu.edu.cn (摘星), 信区: cnhacker
标  题: 80386 保护模式简介 -5 by 软蛀 -- Alex 整理(转寄)
发信站: 饮水思源站 (Fri Apr 25 20:47:26 1997)
转信站: Lilac!ustcnews!ustcnews!sjtunews!sjtubbs
出  处: bbs.sjtu.edu.cn


                                                    ┌┐┌┐∞
【 80386 保护模式简介五 】                     ┘└┘└┘
==========================================================================
前言:
    底下是进入保护模式、进入 V86 的精简范例 ,执行前请确定 CPU 是处在真实模
式 ,程式码因为用到 386 指令 ,请用 TASM 3.1 来编译。
--------------------------------------------------------------------------
┌——————┐
│进入保护模式│
└——————┘

    进入保护模式的程式范例 ,其目地是进入保护模式 ,并在保护模式下用绝对记忆
体读写的方式 ,直接将 'Protection Mode !' 字串写入 Video Ram (B800:0000) ,
本程式以最精简的方式撰写 ,没有任何错误处理 ,因此请确定电脑现在处在真实模式
下才可执行本程式。(禁挂 EMM 系保护模式软体)

    程式流程如下:(底下所指记忆体位址皆为 32bit 绝对位址)

        1. 设定 GDTtab 表所在的记忆体位址填入 GDTadds

        2. 设定 Selector 0008 的记忆体起始位址就是现在 CS 的记忆体位址
           设定 Selector 0010 的记忆体起始位址就是现在 CS 的记忆体位址
                Selector 0018 的记忆体起始位址就是 000B8000 = (B800:0000)

        3. 执行 LGDT FWORD PTR CS:GDTadds 告诉 CPU 一但进入保护模式 ,各
                区段的记忆体起始位址、长度

        4. 设定 CR0 的 Bit0 = '1' ,并透过 JMP 指令进入保护模式
             ※ 进入保护模式後 ,DS.ES.SS.CS.GS.FS 等等暂存器定址方式不再
                是 Segment ,而变成 Selector

        5. 秀字 将 0010:MSG_1 搬到 0018:0000
                意即将 'Protection Mode !' 字串搬到 Video Ram 去

        6. 设定 CR0 的 Bit0 = '0' ,并透过 JMP 指令回到真实模式
             ※ 回到真实模式後 ,DS.ES.SS.CS.GS.FS 等等暂存器定址方式不再
                是 Selector ,而变成 Segment

        5. 秀字 将 CS:MSG_2 搬到 B800:00A0
                意即将 'Return Real Mode !' 字串搬到 Video Ram 去

        6. 结束程式

-----------------------------  P.ASM  ------------------------------------
code    segment
        assume  cs:code,ds:code
386p
start   proc    near
        jmp     next
gdtadds dw      001fh,0000h,0000h
gdttab  db      000h,000h,00h,00h,00h,00h,00h,00h ;00 Null
        db      0ffh,0ffh,00h,00h,00h,9bh,00h,00h ;08 PRG Seg
        db      0ffh,0ffh,00h,00h,00h,93h,00h,00h ;10 PRG Seg
        db      0ffh,0ffh,00h,80h,0bh,93h,00h,00h ;18 B8000
msg_1   db      'Protection Mode !'
msg_2   db      'Return Real Mode !'

next :
        xor     eax,eax                 ;
        xor     ebx,ebx                 ;
        mov     ax,cs                   ;设定 GDTadds
        shl     eax,04h                 ;
        mov     bx,offset gdttab        ;
        add     eax,ebx                 ;
        mov     di,offset gdtadds+02h   ;
        mov     cs:[di],eax             ;
        NOP
        xor     eax,eax                 ;
        xor     ebx,ebx                 ;
        mov     ax,cs                   ;
        shl     eax,04h                 ;
        mov     di,offset gdttab+08h    ;设定 GDTtab 内的
        mov     si,offset gdttab+10h    ;Selector 0008 及 0010
        mov     cs:[di+02h],ax          ;两个段落的记忆体起始位址
        mov     cs:[si+02h],ax          ;
        shr     eax,10h                 ;
        mov     cs:[di+04h],al          ;
        mov     cs:[si+04h],al          ;
        mov     cs:[di+07h],ah          ;
        mov     cs:[si+07h],ah          ;
        NOP
        cli
        lgdt    fword ptr cs:gdtadds    ;载入 GDT 表格
        mov     eax,cr0             ;
        or      al,01h              ;
        mov     cr0,eax             ;
        jmp     protection_mode     ;进入保护模式
protection_mode :                   ;
        mov     ax,0010h                ;
        mov     ds,ax                   ;
        mov     si,offset msg_1         ;
        mov     ax,0018h                ;将 0010:MSG_1 搬到 0018:0000
        mov     es,ax                   ;
        mov     di,0000h                ;
        mov     ah,70h                  ;
        mov     cx,0011h                ;
        cld                             ;
L1 :                                    ;
        lodsb                           ;
        stosw                           ;
        loop    L1                      ;
        NOP
        mov     eax,cr0             ;
        and     al,0feh             ;
        mov     cr0,eax             ;回到真实模式
        jmp     return_real_mode    ;
return_real_mode :                  ;
        sti
        mov     ax,cs                   ;
        mov     ds,ax                   ;
        mov     si,offset msg_2         ;
        mov     ax,0b800h               ;
        mov     es,ax                   ;将 CS:MSG_2 搬到 B800:00A0
        mov     di,00a0h                ;
        mov     ah,70h                  ;
        mov     cx,0012h                ;
        cld                             ;
L2 :                                    ;
        lodsb                           ;
        stosw                           ;
        loop    L2                      ;
        mov     ax,4cffh
        int     21h
start   endp
code    ends
        end     start
--------------------------------------------------------------------------
    因为保护模式下不能呼叫真实模式下的中断 ,所以笔者以直接填写显示卡记忆体
的方式秀字。这是一个简单、尚未使用中断向量表的范例。

注: 所谓一山不容二虎 ,如果已载入其它保护模式的程式 ,那本程式将会与它打架 ,
    造成电脑当机。










┌————————┐
│进入虚拟 86 模式│            为求精简 ,本程式毫无错误处理能力
└————————┘
------------------------  V86.ASM  ---------------------------------------
code    segment
        assume  cs:code,ds:code
386p
start   proc    near
        jmp     next
gdtadds dw      002fh,0000h,0000h
gdttab  db      000h,000h,000h,000h,000h,000h,000h,000h ;00 Null
        db      0ffh,0ffh,000h,000h,000h,09bh,000h,000h ;08 PRG Seg
        db      0ffh,0ffh,000h,000h,000h,093h,08fh,000h ;10 Dos=Page
        db      0ffh,0ffh,000h,000h,000h,089h,000h,000h ;18 TSSltr
        db      0ffh,0ffh,000h,000h,000h,089h,000h,000h ;20 TSSjmp
        db      0ffh,003h,000h,000h,000h,093h,000h,000h ;28 Stack (1K)

tssltr  dd      00000000h
        dd      000003ffh       ;ESP
        dw      0028h,0000h     ;SS.0
        dd      0,0,0,0,0
        dw      offset enter_v86,0000h      ;EIP
        dd      00000200h       ;EFlag
        dd      0,0,0,0
        dd      000003ffh       ;ESP
        dd      0,0,0
        dw      0010h,0000h     ;ES.0
        dw      0008h,0000h     ;CS.0
        dw      0028h,0000h     ;SS.0
        dw      0010h,0000h     ;DS,0
        dw      0010h,0000h     ;FS.0
        dw      0010h,0000h     ;GS.0
        dw      0000h,0000h     ;LDT.0
        dw      0000h,0068h     ;0.IOMAP
        dw      0ffffh

tssjmp  dd      00000000h
        dd      000003ffh       ;ESP
        dw      0028h,0000h     ;SS.0
        dd      0,0,0,0,0
        dw      offset enter_v86,0000h      ;EIP
        dd      00000000h       ;EFlag
        dd      0,0,0,0
        dd      000003ffh       ;ESP
        dd      0,0,0
        dw      0010h,0000h     ;ES.0
        dw      0008h,0000h     ;CS.0
        dw      0028h,0000h     ;SS.0
        dw      0010h,0000h     ;DS,0
        dw      0010h,0000h     ;FS.0
        dw      0010h,0000h     ;GS.0
        dw      0000h,0000h     ;LDT.0
        dw      0000h,0068h     ;0.IOMAP
iomap   db      1000h dup (0)
        dw      0ffffh

buffer1 db      0400h dup (0)           ;Stack

idtadds dw      07ffh,0000h,0000h
idttab  dw      offset new_00,0008h,0ee00h,0000h,offset 
new_01,0008h,0ee00h,0000h
        dw      offset new_02,0008h,0ee00h,0000h,offset 
new_03,0008h,0ee00h,0000h
        dw      offset new_04,0008h,0ee00h,0000h,offset 
new_05,0008h,0ee00h,0000h
        dw      offset new_06,0008h,0ee00h,0000h,offset 
new_07,0008h,0ee00h,0000h
        dw      offset new_08,0008h,0ee00h,0000h,offset 
new_09,0008h,0ee00h,0000h
        dw      offset new_0a,0008h,0ee00h,0000h,offset 
new_0b,0008h,0ee00h,0000h
        dw      offset new_0c,0008h,0ee00h,0000h,offset 
new_0d,0008h,0ee00h,0000h
        dw      offset new_0e,0008h,0ee00h,0000h,offset 
new_0f,0008h,0ee00h,0000h
        dw      offset new_10,0008h,0ee00h,0000h,offset 
new_11,0008h,0ee00h,0000h
        dw      offset new_12,0008h,0ee00h,0000h,offset 
new_13,0008h,0ee00h,0000h
        dw      offset new_14,0008h,0ee00h,0000h,offset 
new_15,0008h,0ee00h,0000h
        dw      offset new_16,0008h,0ee00h,0000h,offset 
new_17,0008h,0ee00h,0000h
        dw      offset new_18,0008h,0ee00h,0000h,offset 
new_19,0008h,0ee00h,0000h
        dw      offset new_1a,0008h,0ee00h,0000h,offset 
new_1b,0008h,0ee00h,0000h
        dw      offset new_1c,0008h,0ee00h,0000h,offset 
new_1d,0008h,0ee00h,0000h
        dw      offset new_1e,0008h,0ee00h,0000h,offset 
new_1f,0008h,0ee00h,0000h
        dw      offset new_20,0008h,0ee00h,0000h,offset 
new_21,0008h,0ee00h,0000h
        dw      offset new_22,0008h,0ee00h,0000h,offset 
new_23,0008h,0ee00h,0000h
        dw      offset new_24,0008h,0ee00h,0000h,offset 
new_25,0008h,0ee00h,0000h
        dw      offset new_26,0008h,0ee00h,0000h,offset 
new_27,0008h,0ee00h,0000h
        dw      offset new_28,0008h,0ee00h,0000h,offset 
new_29,0008h,0ee00h,0000h
        dw      offset new_2a,0008h,0ee00h,0000h,offset 
new_2b,0008h,0ee00h,0000h
        dw      offset new_2c,0008h,0ee00h,0000h,offset 
new_2d,0008h,0ee00h,0000h
        dw      offset new_2e,0008h,0ee00h,0000h,offset 
new_2f,0008h,0ee00h,0000h
        dw      offset new_30,0008h,0ee00h,0000h,offset 
new_31,0008h,0ee00h,0000h
        dw      offset new_32,0008h,0ee00h,0000h,offset 
new_33,0008h,0ee00h,0000h
        dw      offset new_34,0008h,0ee00h,0000h,offset 
new_35,0008h,0ee00h,0000h
        dw      offset new_36,0008h,0ee00h,0000h,offset 
new_37,0008h,0ee00h,0000h
        dw      offset new_38,0008h,0ee00h,0000h,offset 
new_39,0008h,0ee00h,0000h
        dw      offset new_3a,0008h,0ee00h,0000h,offset 
new_3b,0008h,0ee00h,0000h
        dw      offset new_3c,0008h,0ee00h,0000h,offset 
new_3d,0008h,0ee00h,0000h
        dw      offset new_3e,0008h,0ee00h,0000h,offset 
new_3f,0008h,0ee00h,0000h
        dw      offset new_40,0008h,0ee00h,0000h,offset 
new_41,0008h,0ee00h,0000h
        dw      offset new_42,0008h,0ee00h,0000h,offset 
new_43,0008h,0ee00h,0000h
        dw      offset new_44,0008h,0ee00h,0000h,offset 
new_45,0008h,0ee00h,0000h
        dw      offset new_46,0008h,0ee00h,0000h,offset 
new_47,0008h,0ee00h,0000h
        dw      offset new_48,0008h,0ee00h,0000h,offset 
new_49,0008h,0ee00h,0000h
        dw      offset new_4a,0008h,0ee00h,0000h,offset 
new_4b,0008h,0ee00h,0000h
        dw      offset new_4c,0008h,0ee00h,0000h,offset 
new_4d,0008h,0ee00h,0000h
        dw      offset new_4e,0008h,0ee00h,0000h,offset 
new_4f,0008h,0ee00h,0000h
        dw      offset new_50,0008h,0ee00h,0000h,offset 
new_51,0008h,0ee00h,0000h
        dw      offset new_52,0008h,0ee00h,0000h,offset 
new_53,0008h,0ee00h,0000h
        dw      offset new_54,0008h,0ee00h,0000h,offset 
new_55,0008h,0ee00h,0000h
        dw      offset new_56,0008h,0ee00h,0000h,offset 
new_57,0008h,0ee00h,0000h
        dw      offset new_58,0008h,0ee00h,0000h,offset 
new_59,0008h,0ee00h,0000h
        dw      offset new_5a,0008h,0ee00h,0000h,offset 
new_5b,0008h,0ee00h,0000h
        dw      offset new_5c,0008h,0ee00h,0000h,offset 
new_5d,0008h,0ee00h,0000h
        dw      offset new_5e,0008h,0ee00h,0000h,offset 
new_5f,0008h,0ee00h,0000h
        dw      offset new_60,0008h,0ee00h,0000h,offset 
new_61,0008h,0ee00h,0000h
        dw      offset new_62,0008h,0ee00h,0000h,offset 
new_63,0008h,0ee00h,0000h
        dw      offset new_64,0008h,0ee00h,0000h,offset 
new_65,0008h,0ee00h,0000h
        dw      offset new_66,0008h,0ee00h,0000h,offset 
new_67,0008h,0ee00h,0000h
        dw      offset new_68,0008h,0ee00h,0000h,offset 
new_69,0008h,0ee00h,0000h
        dw      offset new_6a,0008h,0ee00h,0000h,offset 
new_6b,0008h,0ee00h,0000h
        dw      offset new_6c,0008h,0ee00h,0000h,offset 
new_6d,0008h,0ee00h,0000h
        dw      offset new_6e,0008h,0ee00h,0000h,offset 
new_6f,0008h,0ee00h,0000h
        dw      offset new_70,0008h,0ee00h,0000h,offset 
new_71,0008h,0ee00h,0000h
        dw      offset new_72,0008h,0ee00h,0000h,offset 
new_73,0008h,0ee00h,0000h
        dw      offset new_74,0008h,0ee00h,0000h,offset 
new_75,0008h,0ee00h,0000h
        dw      offset new_76,0008h,0ee00h,0000h,offset 
new_77,0008h,0ee00h,0000h
        dw      offset new_78,0008h,0ee00h,0000h,offset 
new_79,0008h,0ee00h,0000h
        dw      offset new_7a,0008h,0ee00h,0000h,offset 
new_7b,0008h,0ee00h,0000h
        dw      offset new_7c,0008h,0ee00h,0000h,offset 
new_7d,0008h,0ee00h,0000h
        dw      offset new_7e,0008h,0ee00h,0000h,offset 
new_7f,0008h,0ee00h,0000h
        dw      offset new_80,0008h,0ee00h,0000h,offset 
new_81,0008h,0ee00h,0000h
        dw      offset new_82,0008h,0ee00h,0000h,offset 
new_83,0008h,0ee00h,0000h
        dw      offset new_84,0008h,0ee00h,0000h,offset 
new_85,0008h,0ee00h,0000h
        dw      offset new_86,0008h,0ee00h,0000h,offset 
new_87,0008h,0ee00h,0000h
        dw      offset new_88,0008h,0ee00h,0000h,offset 
new_89,0008h,0ee00h,0000h
        dw      offset new_8a,0008h,0ee00h,0000h,offset 
new_8b,0008h,0ee00h,0000h
        dw      offset new_8c,0008h,0ee00h,0000h,offset 
new_8d,0008h,0ee00h,0000h
        dw      offset new_8e,0008h,0ee00h,0000h,offset 
new_8f,0008h,0ee00h,0000h
        dw      offset new_90,0008h,0ee00h,0000h,offset 
new_91,0008h,0ee00h,0000h
        dw      offset new_92,0008h,0ee00h,0000h,offset 
new_93,0008h,0ee00h,0000h
        dw      offset new_94,0008h,0ee00h,0000h,offset 
new_95,0008h,0ee00h,0000h
        dw      offset new_96,0008h,0ee00h,0000h,offset 
new_97,0008h,0ee00h,0000h
        dw      offset new_98,0008h,0ee00h,0000h,offset 
new_99,0008h,0ee00h,0000h
        dw      offset new_9a,0008h,0ee00h,0000h,offset 
new_9b,0008h,0ee00h,0000h
        dw      offset new_9c,0008h,0ee00h,0000h,offset 
new_9d,0008h,0ee00h,0000h
        dw      offset new_9e,0008h,0ee00h,0000h,offset 
new_9f,0008h,0ee00h,0000h
        dw      offset new_a0,0008h,0ee00h,0000h,offset 
new_a1,0008h,0ee00h,0000h
        dw      offset new_a2,0008h,0ee00h,0000h,offset 
new_a3,0008h,0ee00h,0000h
        dw      offset new_a4,0008h,0ee00h,0000h,offset 
new_a5,0008h,0ee00h,0000h
        dw      offset new_a6,0008h,0ee00h,0000h,offset 
new_a7,0008h,0ee00h,0000h
        dw      offset new_a8,0008h,0ee00h,0000h,offset 
new_a9,0008h,0ee00h,0000h
        dw      offset new_aa,0008h,0ee00h,0000h,offset 
new_ab,0008h,0ee00h,0000h
        dw      offset new_ac,0008h,0ee00h,0000h,offset 
new_ad,0008h,0ee00h,0000h
        dw      offset new_ae,0008h,0ee00h,0000h,offset 
new_af,0008h,0ee00h,0000h
        dw      offset new_b0,0008h,0ee00h,0000h,offset 
new_b1,0008h,0ee00h,0000h
        dw      offset new_b2,0008h,0ee00h,0000h,offset 
new_b3,0008h,0ee00h,0000h
        dw      offset new_b4,0008h,0ee00h,0000h,offset 
new_b5,0008h,0ee00h,0000h
        dw      offset new_b6,0008h,0ee00h,0000h,offset 
new_b7,0008h,0ee00h,0000h
        dw      offset new_b8,0008h,0ee00h,0000h,offset 
new_b9,0008h,0ee00h,0000h
        dw      offset new_ba,0008h,0ee00h,0000h,offset 
new_bb,0008h,0ee00h,0000h
        dw      offset new_bc,0008h,0ee00h,0000h,offset 
new_bd,0008h,0ee00h,0000h
        dw      offset new_be,0008h,0ee00h,0000h,offset 
new_bf,0008h,0ee00h,0000h
        dw      offset new_c0,0008h,0ee00h,0000h,offset 
new_c1,0008h,0ee00h,0000h
        dw      offset new_c2,0008h,0ee00h,0000h,offset 
new_c3,0008h,0ee00h,0000h
        dw      offset new_c4,0008h,0ee00h,0000h,offset 
new_c5,0008h,0ee00h,0000h
        dw      offset new_c6,0008h,0ee00h,0000h,offset 
new_c7,0008h,0ee00h,0000h
        dw      offset new_c8,0008h,0ee00h,0000h,offset 
new_c9,0008h,0ee00h,0000h
        dw      offset new_ca,0008h,0ee00h,0000h,offset 
new_cb,0008h,0ee00h,0000h
        dw      offset new_cc,0008h,0ee00h,0000h,offset 
new_cd,0008h,0ee00h,0000h
        dw      offset new_ce,0008h,0ee00h,0000h,offset 
new_cf,0008h,0ee00h,0000h
        dw      offset new_d0,0008h,0ee00h,0000h,offset 
new_d1,0008h,0ee00h,0000h
        dw      offset new_d2,0008h,0ee00h,0000h,offset 
new_d3,0008h,0ee00h,0000h
        dw      offset new_d4,0008h,0ee00h,0000h,offset 
new_d5,0008h,0ee00h,0000h
        dw      offset new_d6,0008h,0ee00h,0000h,offset 
new_d7,0008h,0ee00h,0000h
        dw      offset new_d8,0008h,0ee00h,0000h,offset 
new_d9,0008h,0ee00h,0000h
        dw      offset new_da,0008h,0ee00h,0000h,offset 
new_db,0008h,0ee00h,0000h
        dw      offset new_dc,0008h,0ee00h,0000h,offset 
new_dd,0008h,0ee00h,0000h
        dw      offset new_de,0008h,0ee00h,0000h,offset 
new_df,0008h,0ee00h,0000h
        dw      offset new_e0,0008h,0ee00h,0000h,offset 
new_e1,0008h,0ee00h,0000h
        dw      offset new_e2,0008h,0ee00h,0000h,offset 
new_e3,0008h,0ee00h,0000h
        dw      offset new_e4,0008h,0ee00h,0000h,offset 
new_e5,0008h,0ee00h,0000h
        dw      offset new_e6,0008h,0ee00h,0000h,offset 
new_e7,0008h,0ee00h,0000h
        dw      offset new_e8,0008h,0ee00h,0000h,offset 
new_e9,0008h,0ee00h,0000h
        dw      offset new_ea,0008h,0ee00h,0000h,offset 
new_eb,0008h,0ee00h,0000h
        dw      offset new_ec,0008h,0ee00h,0000h,offset 
new_ed,0008h,0ee00h,0000h
        dw      offset new_ee,0008h,0ee00h,0000h,offset 
new_ef,0008h,0ee00h,0000h
        dw      offset new_f0,0008h,0ee00h,0000h,offset 
new_f1,0008h,0ee00h,0000h
        dw      offset new_f2,0008h,0ee00h,0000h,offset 
new_f3,0008h,0ee00h,0000h
        dw      offset new_f4,0008h,0ee00h,0000h,offset 
new_f5,0008h,0ee00h,0000h
        dw      offset new_f6,0008h,0ee00h,0000h,offset 
new_f7,0008h,0ee00h,0000h
        dw      offset new_f8,0008h,0ee00h,0000h,offset 
new_f9,0008h,0ee00h,0000h
        dw      offset new_fa,0008h,0ee00h,0000h,offset 
new_fb,0008h,0ee00h,0000h
        dw      offset new_fc,0008h,0ee00h,0000h,offset 
new_fd,0008h,0ee00h,0000h
        dw      offset new_fe,0008h,0ee00h,0000h,offset 
new_ff,0008h,0ee00h,0000h

new_00 :
        push    0000h
        jmp     int_emu
new_01 :
        push    0001h
        jmp     int_emu
new_02 :
        push    0002h
        jmp     int_emu
new_03 :
        push    0003h
        jmp     int_emu
new_04 :
        push    0004h
        jmp     int_emu
new_05 :
        push    0005h
        jmp     int_emu
new_06 :
        push    0006h
        jmp     int_emu
new_07 :
        push    0007h
        jmp     int_emu
new_08 :
        push    0008h
        jmp     int_emu
new_09 :
        push    0009h
        jmp     int_emu
new_0a :
        push    000ah
        jmp     int_emu
new_0b :
        push    000bh
        jmp     int_emu
new_0c :
        push    000ch
        jmp     int_emu
new_0d :
        push    000dh
        jmp     int_emu
new_0e :
        push    000eh
        jmp     int_emu
new_0f :
        push    000fh
        jmp     int_emu
new_10 :
        push    0010h
        jmp     int_emu
new_11 :
        push    0011h
        jmp     int_emu
new_12 :
        push    0012h
        jmp     int_emu
new_13 :
        push    0013h
        jmp     int_emu
new_14 :
        push    0014h
        jmp     int_emu
new_15 :
        cmp     ah,87h
        jnz     L3
        push    bp
        mov     bp,sp
        add     bp,02h
        push    eax
        push    ebx
        push    ecx
        push    edx
        push    edi
        push    esi
        mov     ebx,ss:[bp+14h]
        shl     ebx,04h
        and     esi,0000ffffh
        add     ebx,esi
        mov     ax,0010h
        mov     ds,ax
        mov     es,ax
        mov     esi,ds:[ebx+12h]
        mov     edi,ds:[ebx+1ah]
        and     esi,00ffffffh
        and     edi,00ffffffh
        or      cx,cx
        jz      L2
L1 :
        mov     ax,ds:[esi]
        mov     es:[edi],ax
        add     esi,02h
        add     edi,02h
        loop    L1
L2 :
        pop     esi
        pop     edi
        pop     edx
        pop     ecx
        pop     ebx
        pop     eax
        pop     bp
        iretd
L3 :
        push    0015h
        jmp     int_emu
new_16 :
        push    0016h
        jmp     int_emu
new_17 :
        push    0017h
        jmp     int_emu
new_18 :
        push    0018h
        jmp     int_emu
new_19 :
        push    0019h
        jmp     int_emu
new_1a :
        push    001ah
        jmp     int_emu
new_1b :
        push    001bh
        jmp     int_emu
new_1c :
        push    001ch
        jmp     int_emu
new_1d :
        push    001dh
        jmp     int_emu
new_1e :
        push    001eh
        jmp     int_emu
new_1f :
        push    001fh
        jmp     int_emu
new_20 :
        push    0020h
        jmp     int_emu
new_21 :
        push    0021h
        jmp     int_emu
new_22 :
        push    0022h
        jmp     int_emu
new_23 :
        push    0023h
        jmp     int_emu
new_24 :
        push    0024h
        jmp     int_emu
new_25 :
        push    0025h
        jmp     int_emu
new_26 :
        push    0026h
        jmp     int_emu
new_27 :
        push    0027h
        jmp     int_emu
new_28 :
        push    0028h
        jmp     int_emu
new_29 :
        push    0029h
        jmp     int_emu
new_2a :
        push    002ah
        jmp     int_emu
new_2b :
        push    002bh
        jmp     int_emu
new_2c :
        push    002ch
        jmp     int_emu
new_2d :
        push    002dh
        jmp     int_emu
new_2e :
        push    002eh
        jmp     int_emu
new_2f :
        push    002fh
        jmp     int_emu
new_30 :
        push    0030h
        jmp     int_emu
new_31 :
        push    0031h
        jmp     int_emu
new_32 :
        push    0032h
        jmp     int_emu
new_33 :
        push    0033h
        jmp     int_emu
new_34 :
        push    0034h
        jmp     int_emu
new_35 :
        push    0035h
        jmp     int_emu
new_36 :
        push    0036h
        jmp     int_emu
new_37 :
        push    0037h
        jmp     int_emu
new_38 :
        push    0038h
        jmp     int_emu
new_39 :
        push    0039h
        jmp     int_emu
new_3a :
        push    003ah
        jmp     int_emu
new_3b :
        push    003bh
        jmp     int_emu
new_3c :
        push    003ch
        jmp     int_emu
new_3d :
        push    003dh
        jmp     int_emu
new_3e :
        push    003eh
        jmp     int_emu
new_3f :
        push    003fh
        jmp     int_emu
new_40 :
        push    0040h
        jmp     int_emu
new_41 :
        push    0041h
        jmp     int_emu
new_42 :
        push    0042h
        jmp     int_emu
new_43 :
        push    0043h
        jmp     int_emu
new_44 :
        push    0044h
        jmp     int_emu
new_45 :
        push    0045h
        jmp     int_emu
new_46 :
        push    0046h
        jmp     int_emu
new_47 :
        push    0047h
        jmp     int_emu
new_48 :
        push    0048h
        jmp     int_emu
new_49 :
        push    0049h
        jmp     int_emu
new_4a :
        push    004ah
        jmp     int_emu
new_4b :
        push    004bh
        jmp     int_emu
new_4c :
        push    004ch
        jmp     int_emu
new_4d :
        push    004dh
        jmp     int_emu
new_4e :
        push    004eh
        jmp     int_emu
new_4f :
        push    004fh
        jmp     int_emu
new_50 :
        push    0050h
        jmp     int_emu
new_51 :
        push    0051h
        jmp     int_emu
new_52 :
        push    0052h
        jmp     int_emu
new_53 :
        push    0053h
        jmp     int_emu
new_54 :
        push    0054h
        jmp     int_emu
new_55 :
        push    0055h
        jmp     int_emu
new_56 :
        push    0056h
        jmp     int_emu
new_57 :
        push    0057h
        jmp     int_emu
new_58 :
        push    0058h
        jmp     int_emu
new_59 :
        push    0059h
        jmp     int_emu
new_5a :
        push    005ah
        jmp     int_emu
new_5b :
        push    005bh
        jmp     int_emu
new_5c :
        push    005ch
        jmp     int_emu
new_5d :
        push    005dh
        jmp     int_emu
new_5e :
        push    005eh
        jmp     int_emu
new_5f :
        push    005fh
        jmp     int_emu
new_60 :
        push    0060h
        jmp     int_emu
new_61 :
        push    0061h
        jmp     int_emu
new_62 :
        push    0062h
        jmp     int_emu
new_63 :
        push    0063h
        jmp     int_emu
new_64 :
        push    0064h
        jmp     int_emu
new_65 :
        push    0065h
        jmp     int_emu
new_66 :
        push    0066h
        jmp     int_emu
new_67 :
        push    0067h
        jmp     int_emu
new_68 :
        push    0068h
        jmp     int_emu
new_69 :
        push    0069h
        jmp     int_emu
new_6a :
        push    006ah
        jmp     int_emu
new_6b :
        push    006bh
        jmp     int_emu
new_6c :
        push    006ch
        jmp     int_emu
new_6d :
        push    006dh
        jmp     int_emu
new_6e :
        push    006eh
        jmp     int_emu
new_6f :
        push    006fh
        jmp     int_emu
new_70 :
        push    0070h
        jmp     int_emu
new_71 :
        push    0071h
        jmp     int_emu
new_72 :
        push    0072h
        jmp     int_emu
new_73 :
        push    0073h
        jmp     int_emu
new_74 :
        push    0074h
        jmp     int_emu
new_75 :
        push    0075h
        jmp     int_emu
new_76 :
        push    0076h
        jmp     int_emu
new_77 :
        push    0077h
        jmp     int_emu
new_78 :
        push    0078h
        jmp     int_emu
new_79 :
        push    0079h
        jmp     int_emu
new_7a :
        push    007ah
        jmp     int_emu
new_7b :
        push    007bh
        jmp     int_emu
new_7c :
        push    007ch
        jmp     int_emu
new_7d :
        push    007dh
        jmp     int_emu
new_7e :
        push    007eh
        jmp     int_emu
new_7f :
        push    007fh
        jmp     int_emu
new_80 :
        push    0080h
        jmp     int_emu
new_81 :
        push    0081h
        jmp     int_emu
new_82 :
        push    0082h
        jmp     int_emu
new_83 :
        push    0083h
        jmp     int_emu
new_84 :
        push    0084h
        jmp     int_emu
new_85 :
        push    0085h
        jmp     int_emu
new_86 :
        push    0086h
        jmp     int_emu
new_87 :
        push    0087h
        jmp     int_emu
new_88 :
        push    0088h
        jmp     int_emu
new_89 :
        push    0089h
        jmp     int_emu
new_8a :
        push    008ah
        jmp     int_emu
new_8b :
        push    008bh
        jmp     int_emu
new_8c :
        push    008ch
        jmp     int_emu
new_8d :
        push    008dh
        jmp     int_emu
new_8e :
        push    008eh
        jmp     int_emu
new_8f :
        push    008fh
        jmp     int_emu
new_90 :
        push    0090h
        jmp     int_emu
new_91 :
        push    0091h
        jmp     int_emu
new_92 :
        push    0092h
        jmp     int_emu
new_93 :
        push    0093h
        jmp     int_emu
new_94 :
        push    0094h
        jmp     int_emu
new_95 :
        push    0095h
        jmp     int_emu
new_96 :
        push    0096h
        jmp     int_emu
new_97 :
        push    0097h
        jmp     int_emu
new_98 :
        push    0098h
        jmp     int_emu
new_99 :
        push    0099h
        jmp     int_emu
new_9a :
        push    009ah
        jmp     int_emu
new_9b :
        push    009bh
        jmp     int_emu
new_9c :
        push    009ch
        jmp     int_emu
new_9d :
        push    009dh
        jmp     int_emu
new_9e :
        push    009eh
        jmp     int_emu
new_9f :
        push    009fh
        jmp     int_emu
new_a0 :
        push    00a0h
        jmp     int_emu
new_a1 :
        push    00a1h
        jmp     int_emu
new_a2 :
        push    00a2h
        jmp     int_emu
new_a3 :
        push    00a3h
        jmp     int_emu
new_a4 :
        push    00a4h
        jmp     int_emu
new_a5 :
        push    00a5h
        jmp     int_emu
new_a6 :
        push    00a6h
        jmp     int_emu
new_a7 :
        push    00a7h
        jmp     int_emu
new_a8 :
        push    00a8h
        jmp     int_emu
new_a9 :
        push    00a9h
        jmp     int_emu
new_aa :
        push    00aah
        jmp     int_emu
new_ab :
        push    00abh
        jmp     int_emu
new_ac :
        push    00ach
        jmp     int_emu
new_ad :
        push    00adh
        jmp     int_emu
new_ae :
        push    00aeh
        jmp     int_emu
new_af :
        push    00afh
        jmp     int_emu
new_b0 :
        push    00b0h
        jmp     int_emu
new_b1 :
        push    00b1h
        jmp     int_emu
new_b2 :
        push    00b2h
        jmp     int_emu
new_b3 :
        push    00b3h
        jmp     int_emu
new_b4 :
        push    00b4h
        jmp     int_emu
new_b5 :
        push    00b5h
        jmp     int_emu
new_b6 :
        push    00b6h
        jmp     int_emu
new_b7 :
        push    00b7h
        jmp     int_emu
new_b8 :
        push    00b8h
        jmp     int_emu
new_b9 :
        push    00b9h
        jmp     int_emu
new_ba :
        push    00bah
        jmp     int_emu
new_bb :
        push    00bbh
        jmp     int_emu
new_bc :
        push    00bch
        jmp     int_emu
new_bd :
        push    00bdh
        jmp     int_emu
new_be :
        push    00beh
        jmp     int_emu
new_bf :
        push    00bfh
        jmp     int_emu
new_c0 :
        push    00c0h
        jmp     int_emu
new_c1 :
        push    00c1h
        jmp     int_emu
new_c2 :
        push    00c2h
        jmp     int_emu
new_c3 :
        push    00c3h
        jmp     int_emu
new_c4 :
        push    00c4h
        jmp     int_emu
new_c5 :
        push    00c5h
        jmp     int_emu
new_c6 :
        push    00c6h
        jmp     int_emu
new_c7 :
        push    00c7h
        jmp     int_emu
new_c8 :
        push    00c8h
        jmp     int_emu
new_c9 :
        push    00c9h
        jmp     int_emu
new_ca :
        push    00cah
        jmp     int_emu
new_cb :
        push    00cbh
        jmp     int_emu
new_cc :
        push    00cch
        jmp     int_emu
new_cd :
        push    00cdh
        jmp     int_emu
new_ce :
        push    00ceh
        jmp     int_emu
new_cf :
        push    00cfh
        jmp     int_emu
new_d0 :
        push    00d0h
        jmp     int_emu
new_d1 :
        push    00d1h
        jmp     int_emu
new_d2 :
        push    00d2h
        jmp     int_emu
new_d3 :
        push    00d3h
        jmp     int_emu
new_d4 :
        push    00d4h
        jmp     int_emu
new_d5 :
        push    00d5h
        jmp     int_emu
new_d6 :
        push    00d6h
        jmp     int_emu
new_d7 :
        push    00d7h
        jmp     int_emu
new_d8 :
        push    00d8h
        jmp     int_emu
new_d9 :
        push    00d9h
        jmp     int_emu
new_da :
        push    00dah
        jmp     int_emu
new_db :
        push    00dbh
        jmp     int_emu
new_dc :
        push    00dch
        jmp     int_emu
new_dd :
        push    00ddh
        jmp     int_emu
new_de :
        push    00deh
        jmp     int_emu
new_df :
        push    00dfh
        jmp     int_emu
new_e0 :
        push    00e0h
        jmp     int_emu
new_e1 :
        push    00e1h
        jmp     int_emu
new_e2 :
        push    00e2h
        jmp     int_emu
new_e3 :
        push    00e3h
        jmp     int_emu
new_e4 :
        push    00e4h
        jmp     int_emu
new_e5 :
        push    00e5h
        jmp     int_emu
new_e6 :
        push    00e6h
        jmp     int_emu
new_e7 :
        push    00e7h
        jmp     int_emu
new_e8 :
        push    00e8h
        jmp     int_emu
new_e9 :
        push    00e9h
        jmp     int_emu
new_ea :
        push    00eah
        jmp     int_emu
new_eb :
        push    00ebh
        jmp     int_emu
new_ec :
        push    00ech
        jmp     int_emu
new_ed :
        push    00edh
        jmp     int_emu
new_ee :
        push    00eeh
        jmp     int_emu
new_ef :
        push    00efh
        jmp     int_emu
new_f0 :
        push    00f0h
        jmp     int_emu
new_f1 :
        push    00f1h
        jmp     int_emu
new_f2 :
        push    00f2h
        jmp     int_emu
new_f3 :
        push    00f3h
        jmp     int_emu
new_f4 :
        push    00f4h
        jmp     int_emu
new_f5 :
        push    00f5h
        jmp     int_emu
new_f6 :
        push    00f6h
        jmp     int_emu
new_f7 :
        push    00f7h
        jmp     int_emu
new_f8 :
        push    00f8h
        jmp     int_emu
new_f9 :
        push    00f9h
        jmp     int_emu
new_fa :
        push    00fah
        jmp     int_emu
new_fb :
        push    00fbh
        jmp     int_emu
new_fc :
        push    00fch
        jmp     int_emu
new_fd :
        push    00fdh
        jmp     int_emu
new_fe :
        push    00feh
        jmp     int_emu
new_ff :
        push    00ffh
        jmp     int_emu

int_emu :
        push    bp
        mov     bp,sp
        add     bp,04h
        push    eax
        push    ebx
       mov     ax,0010h                 ;
       mov     ds,ax                    ;
        mov     ax,ss:[bp+0ch]          ;
        sub     ax,06h                  ;
        mov     ss:[bp+0ch],ax          ;
        xor     eax,eax                 ;
        xor     ebx,ebx                 ;
        mov     ax,ss:[bp+10h]          ;V86 下 IRET 要返回的位址
        shl     eax,04h                 ;
        mov     bx,ss:[bp+0ch]          ;
        add     ebx,eax                 ;
        mov     ax,ss:[bp+00h]          ;
        mov     ds:[ebx],ax             ;
        mov     ax,ss:[bp+04h]          ;
        mov     ds:[ebx+02h],ax         ;
        mov     ax,ss:[bp+08h]          ;
        mov     ds:[ebx+04h],ax         ;
        nop
        xor     ebx,ebx                 ;
        mov     bx,ss:[bp-02h]          ;
        shl     ebx,02h                 ;
        mov     ax,ds:[ebx]             ;IRETD後跳到何处执行
        mov     ss:[bp+00h],ax          ;(查 0000:0000 的中断表)
        mov     ax,ds:[ebx+02h]         ;
        mov     ss:[bp+04h],ax          ;
        mov     eax,ss:[bp+08h]
        or      eax,00032000h
        and     eax,0fffffeffh
        mov     ss:[bp+08h],eax
        pop     ebx
        pop     eax
        pop     bp
        add     sp,02h
        iretd

set_base :
        mov     cs:[di+02h],ax
        shr     eax,0010h
        mov     cs:[di+04h],al
        mov     cs:[di+07h],ah
        ret
next :
        xor     eax,eax
        xor     ebx,ebx
        mov     ax,cs
        shl     eax,04h
        mov     bx,offset gdttab
        add     eax,ebx
        mov     di,offset gdtadds+02h
        mov     cs:[di],eax                     ;设定 gdtadds
        NOP
        xor     eax,eax
        xor     ebx,ebx
        mov     ax,cs
        shl     eax,04h
        mov     di,offset gdttab+08h
        call    set_base                        ;设定 PRG Seg 的 Base
        NOP
        xor     eax,eax
        xor     ebx,ebx
        mov     ax,cs
        shl     eax,04h
        mov     bx,offset tssltr
        add     eax,ebx
        mov     di,offset gdttab+18h
        call    set_base
        NOP                                     ;设定 TSSltr 的 Base
        xor     eax,eax
        xor     ebx,ebx
        mov     ax,cs
        shl     eax,04h
        mov     bx,offset tssjmp
        add     eax,ebx
        mov     di,offset gdttab+20h
        call    set_base
        NOP                                     ;设定 TSSjmp 的 Base
        xor     eax,eax
        xor     ebx,ebx
        mov     ax,cs
        shl     eax,04h
        mov     bx,offset buffer1
        add     eax,ebx
        mov     di,offset gdttab+28h
        call    set_base
        NOP                                     ;设定 Stack 的 Base
        xor     eax,eax
        xor     ebx,ebx
        mov     ax,cs
        shl     eax,04h
        mov     bx,offset idttab
        add     eax,ebx
        mov     di,offset idtadds+02h
        mov     cs:[di],eax                     ;设定 idtadds
        NOP
        cli
        lgdt    fword ptr cs:gdtadds
        lidt    fword ptr cs:idtadds
        mov     eax,cr0
        or      al,01h
        mov     cr0,eax
        mov     bx,0018h
        ltr     bx
        db      0eah,00h,00h,20h,00h            ;根据TSS表可知跳到enter_v86
enter_v86 :
        mov     ax,0028h
        mov     es,ax
        xor     eax,eax
        mov     ax,code
        push    eax             ;GS
        push    eax             ;FS
        push    eax             ;DS
        push    eax             ;ES
        push    eax             ;SS
        mov     ax,0f000h
        push    eax             ;ESP
        mov     eax,00023000h   ;设定VM=1    等级=3
        push    eax             ;Eflag
        xor     eax,eax
        mov     ax,code
        push    eax             ;CS
        mov     ax,offset return_dos
        push    eax             ;EIP
        clts                    ;将 387 切换成 32 位元模式
        iretd                   ;回到 V86 (共弹出24h BYTE)
;-------------------------------------------------------------------------
;  下面的程式便是回到 V86 继续执行的程式
;-------------------------------------------------------------------------
return_dos :
        sti
        mov     ax,cs
        mov     ds,ax
        mov     dx,offset next
        add     dx,0200h
        int     27h
start   endp
code    ends
        end     start
;-------------------------------------------------------------------------
    如何侦测现在是在真实模式下或保护模式呢 ,重点就在於 CR0 暂存器的 Bit0
是否为 '1' ,若为 '1' 则表示现在在保护模式 ,反之则为真实模式 ,不过如果要
执行 MOV EAX,CR0 这个指令必需要在特权等级才能执行 ,所以您要侦测这个位元的
话 ,可以使用 SMSW AX ,来读取 CR0 的低位元部份。


┌———————————————————————————————————┐
│  Soft Bugger 软体蛀虫 90:90/2                    软体新技术的实行者  │
│  BBS:02-5955461 24HR          ID:Werong Ho               -- 软蛀 --  │
└———————————————————————————————————┘
--


                                                    沉默的人
                                                 Reinhard Young

※ 来源:·饮水思源站 bbs.sjtu.edu.cn·[FROM: 202.96.212.29]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:631.126毫秒