?? asm2.asm
字號(hào):
;名稱(chēng):ASM2.ASM
;功能:演示實(shí)方式和保護(hù)方式切換(切換到32位代碼段)
;----------------------------------------------------------------------------
INCLUDE 386SCD.INC
;----------------------------------------------------------------------------
DSEG SEGMENT USE16 ;16位數(shù)據(jù)段
;----------------------------------------------------------------------------
GDT LABEL BYTE ;全局描述符表
DUMMY Desc <> ;空描述符
Normal Desc <0ffffh,,,ATDW,,> ;規(guī)范段描述符
Code32 Desc <C32Len-1,,,ATCE,D32,> ;32位代碼段描述符
Code16 Desc <0ffffh,,,ATCE,,> ;16位代碼段描述符
DataS Desc <DataLen-1,0,10h,ATDR,,> ;源數(shù)據(jù)段描述符
DataD Desc <3999,8000h,0bh,ATDW,,> ;顯示緩沖區(qū)描述符
Stacks Desc <StackLen-1,,,ATDW,,> ;堆棧段描述符
;----------------------------------------------------------------------------
GDTLen = $-GDT ;全局描述符表長(zhǎng)度
VGDTR PDesc <GDTLen-1,> ;偽描述符
;----------------------------------------------------------------------------
SaveSP DW ? ;用于保存SP寄存器
SaveSS DW ? ;用于保存SS寄存器
;----------------------------------------------------------------------------
Normal_Sel = Normal-GDT ;規(guī)范段描述符選擇子
Code32_Sel = Code32-GDT ;32位代碼段選擇子
Code16_Sel = Code16-GDT ;16位代碼段選擇子
DataS_Sel = Datas-GDT ;源數(shù)據(jù)段選擇子
DataD_Sel = DataD-GDT ;目標(biāo)數(shù)據(jù)段選擇子
Stacks_Sel = Stacks-GDT ;堆棧段描述符選擇子
;----------------------------------------------------------------------------
DataLen = 16
;----------------------------------------------------------------------------
DSEG ENDS ;數(shù)據(jù)段定義結(jié)束
;----------------------------------------------------------------------------
StackSeg SEGMENT PARA STACK USE16
StackLen = 256
DB StackLen DUP(0)
StackSeg ENDS
;----------------------------------------------------------------------------
CSEG1 SEGMENT USE16 'REAL' ;16位代碼段
ASSUME CS:CSEG1,DS:DSEG
;----------------------------------------------------------------------------
Start PROC
mov ax,DSEG
mov ds,ax
;準(zhǔn)備要加載到GDTR的偽描述符
mov bx,16
mul bx
add ax,OFFSET GDT ;計(jì)算并設(shè)置基地址
adc dx,0 ;界限已在定義時(shí)設(shè)置好
mov WORD PTR VGDTR.Base,ax
mov WORD PTR VGDTR.Base+2,dx
;設(shè)置32位代碼段描述符
mov ax,CSEG2
mul bx
mov WORD PTR Code32.BaseL,ax
mov BYTE PTR Code32.BaseM,dl
mov BYTE PTR Code32.BaseH,dh
;設(shè)置16位代碼段描述符
mov ax,CSEG3
mul bx
mov WORD PTR Code16.BaseL,ax ;代碼段開(kāi)始偏移為0
mov BYTE PTR Code16.BaseM,dl ;代碼段界限已在定義時(shí)設(shè)置好
mov BYTE PTR Code16.BaseH,dh
;設(shè)置堆棧段描述符
mov ax,ss
mov WORD PTR SaveSS,ax
mov WORD PTR SaveSP,sp
mov ax,StackSeg
mul bx
mov WORD PTR Stacks.BaseL,ax
mov BYTE PTR Stacks.BaseM,dl
mov BYTE PTR Stacks.BaseH,dh
;加載GDTR
lgdt QWORD PTR VGDTR
cli ;關(guān)中斷
EnableA20 ;打開(kāi)地址線A20
;切換到保護(hù)方式
mov eax,cr0
or al,1
mov cr0,eax
;清指令預(yù)取隊(duì)列,并真正進(jìn)入保護(hù)方式
JUMP16 Code32_Sel,<OFFSET SPM32>
ToReal: ;現(xiàn)在又回到實(shí)方式
mov ax,DSEG
mov ds,ax
mov sp,SaveSP
mov ss,SaveSS
DisableA20
sti
mov ax,4c00h
int 21h
Start ENDP
;----------------------------------------------------------------------------
CSEG1 ENDS ;代碼段定義結(jié)束
;----------------------------------------------------------------------------
CSEG2 SEGMENT USE32 'PM32'
ASSUME CS:CSEG2
;----------------------------------------------------------------------------
SPM32 PROC
mov ax,Stacks_Sel
mov ss,ax
mov esp,StackLen
mov ax,DataS_Sel
mov ds,ax
mov ax,DataD_Sel
mov es,ax
xor esi,esi
xor edi,edi
mov ecx,DataLen
cld
Next: lodsb
push ax
CALL ToASCII
mov ah,7
shl eax,16
pop ax
shr al,4
CALL ToASCII
mov ah,7
stosd
mov al,20h
stosw
loop Next
JUMP32 Code16_Sel,<OFFSET SPM16>
SPM32 ENDP
;----------------------------------------------------------------------------
ToASCII PROC
and al,00001111b
add al,30h
cmp al,39h
jbe Isdig
add al,7
IsDig: ret
ToASCII ENDP
;----------------------------------------------------------------------------
C32Len = $
;----------------------------------------------------------------------------
CSEG2 ENDS
;----------------------------------------------------------------------------
CSEG3 SEGMENT USE16 'PM16'
ASSUME CS:CSEG3
;----------------------------------------------------------------------------
SPM16 PROC
xor si,si
mov di,DataLen*3*2
mov ah,7
mov cx,DataLen
AGain: lodsb
stosw
loop AGain
mov ax,Normal_sel
mov ds,ax
mov es,ax
mov ss,ax
mov eax,cr0
and al,11111110b
mov cr0,eax
jmp FAR PTR ToReal
SPM16 ENDP
;----------------------------------------------------------------------------
CSEG3 ENDS
;----------------------------------------------------------------------------
END Start
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -