NASM 纯汇编打造简单中文操作系统(2 init.asm初始化操作系统内存。进入32位保护模式)

二、init.asm初始化操作系统内存。进入32位保护模式

[BITS 16]
[ORG 0x0]
JMP main
;-----------------------------------------------------------
;操作系统内存结构
;0x0-0x3FFF ;堆栈16kb
;0x4000-0x40ff ;鼠标指针数据256byte
;0x4100-0x90ff ;图像缓冲区20kb
;0x9100-0x9fff ;init模块3kb
;0x10000:0x2ffff;64kb系统内存包括声卡内存数据信息.前10kb给系统表使用4k给声卡用
;变量从0x13800开始申请50kb
;20000-0x61600 ;图文字库用的ucdos字库 262.5kb
;0x61610-0x9FFFF;系统内核250.5kb
;0x9ffff
;a0000-1f0000 ;1.34mb未申请的内存
;0x100000 ;显示缓存跳过未申请的内存区
;-----------------------------------------------------------
;GDT表定义:
;为了能让内存对其方式为2的幂次所以第一个GDT结构要定义成空
GDTTABLE:
 GDT0:
  DD 0
  DD 0
 GDT_CODE_SEGMENT_POS equ $-GDTTABLE
 GDT_CODE_SEGMENT:
  DW 0xffff ;0到0xffff也就是0x10000*4KB大小。这个段可以访问4个GB
  DW 0x1610
  DB 0x06
  DB 10011010B ;GDT表详细描述中有详细注释
  DB 11001111B ;设置为一个表限制为1*4KB,数据段为32位,其他为0
  DB 0 

 GDT_DATA_SEGMENT_POS equ $-GDTTABLE
 GDT_DATA_SEGMENT:
  DW 0xffff
  DW 0x0000
  DB 0x0
  DB 10010010B ;注意这个是数据段有一个标志位和代码段是不同的
  DB 11001111B 
  DB 0
 GDT_VESA_MEM_POS equ $-GDTTABLE ;b800的位置用来现实文字
 GDT_VESA_MEM:
  DW 0xFFFF
  DW 0x0000 ;0xb800转换成线性地址乘10h
  DB 0x0  ;意思也就是这个结构的线性地址从物理内存的b800处开始映射
  DB 10010010B
  DB 11001111B
  DB 0
 GDT_END:
 GDT_ADDR:    ;这个也是固定结构,cpu读取GDT表必须要用的
  DW GDT_END - GDTTABLE -1 ;GDT 表的大小这里1个=8个字节。也就是代表有多少个GDT项.
      ;一个GDT项为8个字节组成
  DD GDTTABLE+0x9100  ;GDT表的地址
;--------------------------------------------------------------------------------------------------------
VBE_ADDR: EQU 0x1380
;-------------------------------------------------------------------------------------
;PUSH 磁头号 WORD
;PUSH segment WORD
;PUSH offset  WORD
;PUSH driver  WORD
;PUSH 起始磁道     WORD
;PUSH 起始扇区      WORD
;PUSH 读取多少个扇区 WORD
ReadDriver:
 PUSH BP
 MOV BP,SP
read: 
 MOV AX,WORD [ESP+14]  ;获得欲拷贝的段地址  
 MOV ES,AX  
 MOV BX,WORD [ESP+12]  ;拷贝地址的偏移
 MOV AH,2
 MOV DH,BYTE [ESP+16]  ;磁头号
 MOV DL,BYTE [ESP+10]  ;驱动器
 MOV CH,BYTE [ESP+8]  ;第几个磁道开始读取
 MOV CL,BYTE [ESP+6]  ;从第4个扇区开始读
 MOV AL,BYTE [ESP+4]          ;读入扇区数,每个扇区为 512B*8.
 INT 0x13     ;调用13中断读取磁盘信息 
 JC      read
 MOV SP,BP
 POP BP
 ret 14
;-------------------------------------------------------------------------------------------- 
main:
 MOV ESP,0xFFFF
 MOV AX,0x910
 MOV DS,AX 

;读取鼠标光标
 PUSH WORD 0  ;0
 PUSH WORD 0x1000 ;存入段地址
 PUSH WORD 0  ;存入的偏移
 PUSH WORD 0  ;驱动器
 PUSH WORD 0  ;起始磁道
 PUSH WORD 12  ;起始扇区
 PUSH WORD 1  ;读取扇区数量
 CALL ReadDriver

        ;移动512字节的各部分数据到相应的内存
       PUSH DS
       PUSH ES
       XOR ECX,ECX
       XOR EAX,EAX
       XOR ESI,ESI
       XOR EDI,EDI
       MOV AX,0x1000
       MOV ES,AX
       MOV AX,0x400
       MOV DS,AX
       MOV EAX,[ES:0] ;移动鼠标点阵到0x4000处
       MOV [DS:0],DWORD EAX
       MOV EAX,[ES:4]
       MOV [DS:4],DWORD EAX
 ;MOV CX,2
 ;MOV AX,0x1000 ;复制原
 ;MOV DS,AX
 ;MOV AX,0x400
 ;MOV ES,AX  ;目标
 ;REP
 
 POP ES
 POP DS
 ;PUSH WORD 0
 ;PUSH WORD 0x20A0 ;存入段地址
 ;PUSH WORD 0  ;存入的偏移
 ;PUSH WORD 0  ;驱动器
 ;PUSH WORD 1  ;起始磁道
 ;PUSH WORD 1  ;起始扇区
 ;PUSH WORD 18  ;读取扇区数量
 ;CALL ReadDriver  
 ;读取字库0
 PUSH WORD 0
 PUSH WORD 0x2000 ;存入段地址
 PUSH WORD 0  ;存入的偏移
 PUSH WORD 0  ;驱动器
 PUSH WORD 0  ;起始磁道
 PUSH WORD 13  ;起始扇区
 PUSH WORD 24  ;读取扇区数量 
 CALL ReadDriver
 MOV AX,0x2780
 MOV ES,AX
 MOV CX,2  ;起始磁道
rlop:
 PUSH WORD 0x910
 POP DS  ;恢复数据段寄存器
 PUSH CX
 PUSH ES
 PUSH WORD 0
 PUSH WORD 0x2300 ;存入段地址
 PUSH WORD 0  ;存入的偏移
 PUSH WORD 0  ;驱动器
 PUSH CX  ;起始磁道
 PUSH WORD 1  ;起始扇区
 PUSH WORD 37  ;读取扇区数量
 CALL ReadDriver
 MOV AX,0x2300
 MOV DS,AX
 XOR SI,SI
 XOR DI,DI
 POP ES
 MOV CX,0x2500
 CLD
 REP MOVSW 

 MOV AX,ES
 ADD AX,0x4A0
 MOV ES,AX
 PUSH WORD 0x910
 POP DS  ;恢复数据段寄存器
 POP CX
 
 INC CX 
 CMP CX,16  ;循环2-15次
 JNZ rlop
 
 PUSH WORD 0
 PUSH WORD 0x2300 ;存入段地址
 PUSH WORD 0  ;存入的偏移
 PUSH WORD 0  ;驱动器
 PUSH WORD 1  ;起始磁道
 PUSH WORD 1  ;起始扇区
 PUSH WORD 36  ;读取扇区数量
 CALL ReadDriver 


 ;读取内核
 PUSH WORD 0  ;磁头号0
 PUSH WORD 0x6161 ;存入段地址
 PUSH WORD 0  ;存入的偏移
 PUSH WORD 0  ;驱动器
 PUSH WORD 0  ;起始磁道
 PUSH WORD 4  ;起始扇区
 PUSH WORD 8  ;读取扇区数量01010101
 CALL ReadDriver      
        MOV     DX,0x3F2               ;关闭软区马达
        MOV     AL,0
        OUT     DX,AL
;-----------------------------------------------------------------------------------------------------
;设置现卡模式
;-----------------------------------------------------------------------------------------------------
 ;设置显卡模式
 MOV AX , 0x4f02
 MOV BX , 0x4114  ;800 * 600 16位色( 5:6:5 )
 int 0x10   ;设置显示模式
 
 ;取得该模式下显存线性地址
 PUSH DS
 POP ES
 ;MOV BX,0x0
 ;MOV ES,BX 
 MOV DI,VBE_ADDR  ;用来存放vesa信息的结构
 MOV AX,0x4f01
 MOV CX,0x114
 INT 0x10 
 MOV EAX,[VBE_ADDR + 40] ;获得直接色彩模式属性(结构第40个字节)
 MOV BX,0x1380  ;一个DWORD型的显存地址放到0x1380:0的位置
 MOV ES,BX   ;设置段地址
 MOV [ES:0],EAX

;进入32位保护模式
     ;关闭一切设备的输入 
 LGDT [GDT_ADDR]  ;装载GDT表

   CLI
   IN AL,0x92    ;打开a20地址总线的为访问更多内存
 OR AL,2    ;第2个二进制位
 OUT 0x92,AL    ;打开32位模式
  
 MOV EAX,CR0    ;进入模式
 OR EAX,1    ;打开寄存器cr0中的第一个二进制位
 MOV CR0,EAX    ;把修改好的内容写回去就进入32位保护模式了
 
 STI
 
 ;接下来执行32位代码

 JMP DWORD GDT_CODE_SEGMENT_POS:0
 TIMES 0x400-($-$$) DB 0


http://blog.csdn.net/kylixfire/article/details/3963585


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值