其他分享
首页 > 其他分享> > OSLab:实模式与保护模式

OSLab:实模式与保护模式

作者:互联网

 

日期:2019/5/18 12:00

内容:操作系统实验作业;x86;IA-32;实模式与保护模式。

PS:如果我们上的是同一门课,有借鉴代码的铁汁请留言告知嗷。只是作业笔记,不推荐学习。

一、实模式

众所周知,机器启动时都是处于实模式状态的。8多说,先看看今天的作业。

1.1 BIOS中断打印字符串

这是一个幼儿园版本的主引导记录(MBR),输出一个字符串,结合附录INT中断说明来看。

org 0x7c00这个表示程序加载到物理内存的起始地址0x7c00,关于0x7c00请看附录。

    org 0x7c00

    [bits 16]

    mov ax, 0x1301

    mov bx, 0x000c

    mov cx, 5

    mov dx, 0x0808

    mov bp, msg

    int 0x10

    jmp $

msg:

    db "HELLO", 0

    times 510-($-$$) db 0

    dw 0xaa55

 

1.2 直接操纵显卡显示字符串

实模式下,访问内存的格式:[REG: DISP],其中REG是段寄存器:SS,DS,ES等。DISP是16位的偏移,对应的真实物理地址为(REG<<4)+DISP(20位)。

VGA全称Video Graphics Array,是一种视频传输标准。

VGA所使用的视讯内存对应于PC的主内存,它们的真实物理地址为0xA000和0xC000之间的内存。典型地来说位址的开始点是:

注意在0xB800这种模式下,每个VGA字符占2字节,低地址字节是字符的ASCII码,高地址字节是属性值(控制颜色)。每个输出页面是25*80大小。

例如:

坐标

地址1内容

地址2内容

说明

(0,0)

[0xB800:0000] = 'H'

[0xB800:0001]=0x0C

红色的H字符

(0,1)

[0xB800:0002] = 'e'

[0xB800:0003]=0x0C

红色的e字符

最大坐标是(24,79)。

在(0, 0)位置输出红色的X字符。

org 0x7c00

[bits 16]

mov ax, 0xb800

mov es, ax

mov ah, 0x0c

mov al,'X'

mov [es:0], ax

jmp $

times 510-($-$$) db 0

dw 0xaa55

 

1.3 利用VGA输出字符串

通过循环,基于输出字符X实现。

    org 0x7c00

    [bits 16]

    mov si, msg

    mov bx, 0xb800

    mov es, bx

    mov di, 0

lab:

    mov ah, 0x0c

    mov al, [si]

    mov [es:di], ax

    add di, 2

    inc si

    cmp al, 0

    jne lab

    jmp $

msg:

    db "Hello msg from sin", 0

    times 510-($-$$) db 0

    dw 0xaa55

 

1.4 清空VGA屏幕

VGA每个屏幕(显示页)大小为25*80 = 2000。清屏可通过输出2000个ASCII=0的空白字符。

    org 0x7c00

    [bits 16]

    mov ax, 0xb800

    mov es, ax

    mov bx, 0

    mov cx, 0x07d0

lab:mov dl, 0

    mov dh, 0

    mov [es:bx], dx

    add bx, 2

    loop lab

    jmp $

    times 510-($-$$) db 0

    dw 0xaa55

 

二、保护模式

2.1 GDT与GDTR

base=32bit

limit=16bit

GDT最多有几个表项?

limit=FFFFH,GDT所占字节数为216bytes,每项8个字节,所以最大表项数目 = 213 = 8192。

2.2 CR系列寄存器

微机原理时间:

对CR0的位进行说明:

考试坑点:分页机制开启 iff PE = 1 AND PG=1(分页机制一定工作在保护模式下)

2.3 段选择子

Segment selector,其实就是段寄存器的值。也就是说,段寄存器在保护模式下,各个字段的含义如下:

Index字符就是用于索引GDT表项,类似于数组一样:GDT[index]

2.2 作业:RTFSC

%define CR0_PE          (1 << 0)

%define CR0_MP          (1 << 1)

%define CR0_EM          (1 << 2)

%define CR0_TS          (1 << 3)

%define CR0_WP          (1 << 16)

%define CR0_PG          (1 << 31)

gdt: dw 0,0,0,0 ; dummy

 

        dw 0xFFFF ; limit=4GB

        dw 0x0000 ; base address=0

        dw 0x9A00 ; code read/exec

        dw 0x00CF ; granularity=4096,386

 

        dw 0xFFFF ; limit=4GB

        dw 0x0000 ; base address=0

        dw 0x9200 ; data read/write

        dw 0x00CF ; granularity=4096,386

 

        align 8

gdt_desc:

        dw 23 ; gdt limit=sizeof(gdt) - 1

        dw gdt

 

        times 510-($-$$) db 0

        dw 0xAA55

org 0x7c00

[bits 16]

; First, BIOS loads the bootsector into 0000:7C00.

cli

xor ax, ax

mov ds, ax

mov ss, ax

mov sp, 0

 

; Switch to protect mode

lgdt [gdt_desc]

mov eax, cr0

or eax, CR0_PE

mov cr0, eax

jmp 0x08:start32

 

start32:

; In protect mode

cli

mov ax, 0x10

mov ds, ax

mov es, ax

mov ss, ax

mov esp, 0x10000

 

mov al, 'X'

mov ah, 0x0c

mov [0xB8000], ax

jmp $

align 8

 

附录

INT 0x10中断

参考:https://blog.csdn.net/yes_life/article/details/6778834

为什么MBR要放在0x7C00

参考:http://www.ruanyifeng.com/blog/2015/09/0x7c00.html

注意嗷:MBR在关机的时候是放在磁盘的0号扇区的,开机之后,由BIOS把它加载到内存的嗷。

主引导记录内存地址设定在比32KB小1024个字节的0x7C00H的位置。(32KB=215=0x7fff)

是因为Intel第一代cpu8088所搭配的系统最少需要使用32KB的地址空间

8088本身需要占用0x0000~0x03FF,用来保存各种中断处理程序,内存只剩下0x0400~0x7FFF可使用

为了把尽量多的连续内存留给操作系统,主引导记录就被放到了内存地址的尾部。

一个扇区是512字节,主引导记录本身也会产生数据,另外留出一个扇区保存数据。

为了cpu的向前兼容

于是0x7c00H便成为了每一代cpu的主引导记录内存地址。

内存布局图解:

+--------------------- 0x0

| Interrupts vectors

+--------------------- 0x400

| BIOS data area

+--------------------- 0x5??

| OS load area

+--------------------- 0x7C00

| Boot sector

+--------------------- 0x7E00

| Boot data/stack

+--------------------- 0x7FFF

| (not used)

+--------------------- (...)

标签:保护模式,GDT,gdt,mov,模式,OSLab,dw,ax,内存
来源: https://www.cnblogs.com/sinkinben/p/10888599.html