技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 668|回复: 4
收起左侧

【汇编】最简单的切保护模式的源码

[复制链接]

995

主题

2207

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16461 个
贡献
32335 次
宅之契约
0 份
在线时间
1565 小时
注册时间
2014-1-26
发表于 2017-6-15 08:51:49 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
[Asm] 纯文本查看 复制代码
bits 16
org 0x7c00

Start:
xor ax,ax
mov ds,ax

cli

lgdt [GDTR]

mov eax,cr0
or al,1
mov cr0,eax
jmp dword 0x08:PEStart

GDTR:
.limit:
dw GDT.End-GDT-1
.base:
dd GDT

GDT:
dw 0,0,0,0

dw 0xffff
dw 0
dw 0x9a00
dw 0x00cf

dw 0xffff
dw 0
dw 0x9200
dw 0x00cf
.End:

PEStart:
bits 32

mov ax,0x10
mov es,ax
mov ss,ax
mov ds,ax
mov fs,ax
mov gs,ax
mov esp, 0xffff

.text:
mov dword[0xb8000],'P'|('r'<<16)|0x07000700
mov dword[0xb8004],'o'|('t'<<16)|0x07000700
mov dword[0xb8008],'e'|('c'<<16)|0x07000700
mov dword[0xb800c],'t'|('e'<<16)|0x07000700
mov dword[0xb8010],'d'|(' '<<16)|0x07000700
mov dword[0xb8014],'m'|('o'<<16)|0x07000700
mov dword[0xb8018],'d'|('e'<<16)|0x07000700
jmp .text

times 510-($-$$) db 0
dw 0xAA55
编译为平坦格式flp后缀,让vmware把它当作一个启动软盘加载即可运行。
没有出问题的话,它应该会显示一句“Protected mode”。
20170615094224.png
细节上要注意的点:
1、切模式前务必关中断。用cli即可。如果只是想进保护模式玩玩的话,无需设置IDT和TS。
2、nasm编译器,我用的版本是2.13.01。经过我的测试2.11版有BUG,会导致它无视你的bits 32语句。
3、修改cr0的数值后必须立即跳转。
4、可以不用在跳转前修改段选择子。
5、开头的那几句:
    xor ax,ax
    mov ds,ax
经测试,必须要有。因为引导进来的时候ds并没有指向你的代码所在的段上。不设置这两句的话,lgdt指令并不能正确找到你的gdt表。

25

主题

81

帖子

1088

积分

用户组: 版主

UID
1821
精华
6
威望
57 点
宅币
832 个
贡献
31 次
宅之契约
0 份
在线时间
196 小时
注册时间
2016-7-12
发表于 2017-6-15 19:56:21 | 显示全部楼层
用masm写起来就恶心了 dos bin
[Asm] 纯文本查看 复制代码
DESC STRUC
	lim_00_15 DW ?
	bas_00_15 DW ?
	bas_16_23 DB ?
	access    DB ?
	gran      DB ?
	bas_24_31 DB ?
DESC ENDS

data segment
	GDT_REG label DESC
	;cs 0
				dw 0
				
				dw 0
				
				db 0
				db 0
				
				db 0
				db 0
	;cs 08h 
				dw 0FFFFh
				dw 0
				
				db 0
				db 9ah
				
				db 0cfh
				db 0
	;es 10h
				dw 0FFFFh
				dw 0
				
				db 0
				db 92h
				
				db 0cfh
				db 0
	;ss 18h
				dw 0FFFFh
				dw 0
				
				db 0
				db 92h
				
				db 0cfh
				db 0
	GDT_LENGTH  EQU $ - offset GDT_REG
	
	
	GDTR_org 	dw 0
				dd 0
	GDTR_new	dw GDT_LENGTH - 1
				dd offset GDT_REG
data ends


u16 segment 
	assume cs:u16,ds:data
REAL_MODE:

start:
	mov ax,data
	mov ds,ax

	mov ax,u32
.386
	shl eax,4
.8086
	mov GDT_REG[8].bas_00_15,ax
.386	
	shr eax,16
.8086
	mov GDT_REG[8].bas_16_23,al
	mov GDT_REG[8].bas_24_31,ah
	
	mov ax,data
.386
	shl eax,4
	add eax,dword ptr ds:GDTR_new[2]
	mov dword ptr ds:GDTR_new[2],eax
	
.386p
	cli
	db 66h	
	sgdt fword ptr ds:[GDTR_org]
	
	db 66h
	lgdt fword ptr ds:[GDTR_new]

	mov eax,cr0
	or  eax,1
	mov cr0,eax
	
	db 66h
	db 0eah
	dd 0
	dw 8

u16 ends

.386

u32 segment use32
PROTECT_MODE:

	mov ax,10h
	mov es,ax

	mov edi,0b8000h
	mov ecx,80*25
	mov al,"*"
	mov ah,11001010b
	rep stosw
	
	jmp $
	
u32 ends

end start

995

主题

2207

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16461 个
贡献
32335 次
宅之契约
0 份
在线时间
1565 小时
注册时间
2014-1-26
 楼主| 发表于 2017-6-15 21:06:07 | 显示全部楼层
Ayala 发表于 2017-6-15 19:56
用masm写起来就恶心了 dos bin
[mw_shl_code=asm,true]DESC STRUC
        lim_00_15 DW ?

这db 66h让我回忆起了曾经的辛酸

25

主题

81

帖子

1088

积分

用户组: 版主

UID
1821
精华
6
威望
57 点
宅币
832 个
贡献
31 次
宅之契约
0 份
在线时间
196 小时
注册时间
2016-7-12
发表于 2017-6-15 21:26:05 | 显示全部楼层
0xAA55 发表于 2017-6-15 21:06
这db 66h让我回忆起了曾经的辛酸

这种写法 最早出自intel自己呢!

1

主题

86

帖子

91

积分

用户组: 小·技术宅

UID
3026
精华
0
威望
1 点
宅币
3 个
贡献
0 次
宅之契约
0 份
在线时间
6 小时
注册时间
2017-10-31
发表于 2017-10-31 09:44:37 | 显示全部楼层
这也可以。
回复

使用道具 举报

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-9-20 09:32 , Processed in 0.108773 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表