首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

386+ 處理器實模式進入 V86 模式組語程式

     編輯:組合語言

程式用途

本程式示範如何在 80386 以上處理器上,從實模式(Real Mode)切換至虛擬 8086 模式(Virtual 8086 Mode, V86)。V86 模式允許在保護模式下執行實模式程式(如 DOS 程式),是 Windows 3.x/9x/NTVDM 等系統支援 DOS 相容性的核心機制。程式碼為片段,展示關鍵步驟:計算記憶體邊界、建立 GDT 描述符、載入 IDTR、切換 CR0 暫存器(PE 位元)等。

核心流程解析

  1. 取得記憶體大小:INT 12h 取得常規記憶體(KB),INT 15h, AH=88h 取得擴充記憶體(KB),換算為位元組並對齊段邊界。
  2. 計算 PSP 與程式大小:透過 ES:[2Ch] 取得環境區段落,推算程式佔用記憶體上界。
  3. 建立 GDT 描述符:fill1_gdt 程序設定代碼/資料段描述符基址與限制,準備進入保護模式所需的全域描述符表。
  4. 載入 GDTR/IDTR:雖然程式碼片段未完整呈現 LGDT/LIDT,但 SIDT 指令已用於讀取 IDTR 內容。
  5. 啟用保護模式:設定 CR0 的 PE 位元(Bit 0),處理器進入保護模式。
  6. 進入 V86 模式:在保護模式下,將旗標暫存器 EFLAGS 的 VM 位元(Bit 17)置 1,通常透過 IRET 從特權級 0 返回特權級 3 任務時自動載入含 VM=1 的 EFLAGS,即進入 V86 模式。

原始碼片段

.model small
.386p
.data
base_memory dd ?
new_base dd 0
new_base1 dd 0
.code
mov cs:psp_seg,ds
mov ax,seg base_memory
mov ds,ax
mov es,ax
mov ds,ax
int 12h
movzx eax,ax
shl eax,0ah
add eax,0fffh
and ax,0f000h
mov base_memory,eax
mov ah,88h
int 15h
add ax,400h
movzx eax,ax
shl eax,0ah
and ax,0f000h
mov bx,cs:psp_seg
mov es,bx
mov si,2ch
cmp bx,es:[si]
jb ignore
mov bx,es:[si]
ignore:
movzx ebx,bx
shl ebx,4
add ebx,0fffh
and bx,0f000h
mov ecx,base_memory
sub ecx,ebx
sub eax,ecx
sub eax,010000h
mov new_base,eax
shr eax,4
mov new_base1,eax
call fill1_gdt
psp_seg dw ?
fill1_gdt proc near
movzx eax,ax
shl eax,4
mov ebx,eax
shr ebx,10h
add [si+2],ax
adc [si+4],bl
fill1_gdt endp
end

關鍵指令與暫存器說明

指令/暫存器用途
INT 12h取得常規記憶體大小(KB),回傳 AX
INT 15h, AH=88h取得擴充記憶體大小(KB),回傳 AX
SIDT儲存 IDTR 內容至記憶體
CR0.PE保護模式啟用位元 (Bit 0)
EFLAGS.VM虛擬 8086 模式位元 (Bit 17)
LGDT / LIDT載入 GDTR / IDTR(程式碼片段未含,實作時必須補上)

補充:完整切換流程大綱

; 1. 關閉中斷
cli
; 2. 建立 GDT(含 Null、Code32、Data32、Code16、Data16、TSS 等描述符)
; 3. LGDT 載入 GDTR
; 4. LIDT 載入 IDTR(可選,保護模式需重新設定 IDT)
; 5. 啟用 A20 線(透過鍵盤控制器或 Fast A20 Gate)
; 6. 設定 CR0.PE = 1 進入保護模式
; 7. 遠跳轉至 32-bit 程式碼段刷新 CS 基址
; 8. 載入資料段暫存器 (DS, ES, FS, GS, SS) 為 32-bit 資料段選擇子
; 9. 建立/載入 TSS,設定 TR
; 10. 設定 IDT 門描述符對應 V86 模式所需中斷向量
; 11. 配置分頁(可選,V86 通常需分頁以攔截 I/O 指令)
; 12. 準備一個含 VM=1 的 EFLAGS 映像於堆疊
; 13. IRET 返回 CPL=3,處理器載入 EFLAGS.VM=1,進入 V86 模式

歷史意義與現代關聯

  • Windows 3.x Enhanced Mode、Windows 9x、OS/2 2.0、NTVDM (Windows NT 系列) 均仰賴 V86 模式執行 DOS/Win16 應用程式。
  • 現代 x86-64 長模式下,V86 模式僅在相容模式(32-bit 保護模式)中可用;64-bit 核心通常透過模擬或虛擬化(VM86 指令在長模式下無效)執行 16-bit 代碼。
  • 本程式碼屬教學片段,缺少 A20 啟用、完整 GDT/IDT 建立、分頁設定、IRET 進入 V86 等關鍵步驟,不可直接執行。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved