📄 11.txt
字号:
> .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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -