自制操作系统5:由实模式进入保护模式之32位寻址

参考:
https://blog.csdn.net/tyler_download/article/details/52021120
https://www.bilibili.com/video/BV1VJ41157wq?p=5&spm_id_from=pageDriver
先分析kernel.asm
https://github.com/wycl16514/OS-Kernel-from-real-to-protected-mode/blob/master/kernel.asm
这段代码有些复杂
先定义GDT
然后是16位跳转到32位
然后在32位模式下,往显存里面复制message,显示出来。

再分析pm.inc
https://github.com/wycl16514/OS-Kernel-from-real-to-protected-mode/blob/master/pm.inc
Descriptor 在这里定义。

编译为kernel.bat,用上一节的工具制作system.img,加载运行出错。检查发现boot.asm偏移地址不太对,需要修改一下
https://github.com/wycl16514/OS-Kernel-from-real-to-protected-mode/blob/master/boot.asm
LOAD_ADDR  EQU  0X9000
修改后问题解决:

kernel.asm

%include "pm.inc"

org 0x9000

jmp LABEL_BEGIN

[SECTION .gdt]
LABEL_GDT          Descriptor  0,       0,                0
LABEL_DESC_CODE32: Descriptor  0,       SegCode32Len - 1, DA_C + DA_32
LABEL_DESC_VIDEO:  Descriptor  0B8000h, 0fffh,            DA_DRW

GdtLen equ $ - LABEL_GDT
GdtPtr dw  GdtLen - 1
       dd  0

SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo  equ LABEL_DESC_VIDEO - LABEL_GDT

[SECTION  .s16]
[BITS  16]
LABEL_BEGIN:
  mov ax,cs
  mov ds, ax
  mov es, ax
  mov ss, ax
  mov sp, 0100h
  
  xor eax, eax
  mov ax,  cs
  shl eax, 4
  add eax, LABEL_SEG_CODE32
  mov word [LABEL_DESC_CODE32 + 2], ax
  shr eax, 16
  mov byte [LABEL_DESC_CODE32 + 4], al
  mov byte [LABEL_DESC_CODE32 + 7], ah
  
  xor eax, eax
  mov ax,  ds
  shl eax, 4
  add eax, LABEL_GDT
  mov dword  [GdtPtr + 2], eax
  
  lgdt [GdtPtr]
  
  cli
  
  in al, 92h
  or al, 00000010b
  out 92h, al
  
  mov eax, cr0
  or  eax, 1
  mov cr0, eax
  
  jmp dword SelectorCode32: 0
  
[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:
    mov ax, SelectorVideo
    mov gs, ax
    mov si, msg
    mov ebx, 10
    mov ecx, 2
showChar:
  mov edi, (80*11)
  add edi, ebx
  mov eax, edi
  mul ecx
  mov edi, eax
  mov ah,  0ch
  mov al,  [si]
  cmp al, 0
  je  end
  add ebx, 1
  add si, 1
  mov [gs:edi], ax
  jmp showChar
end:
  jmp $
  msg:
  DB "Protect Mode", 0
SegCode32Len  equ  $ - LABEL_SEG_CODE32
 

pm.inc

%macro Descriptor 3
  dw    %2  &  0FFFFh
  dw    %1  &  0FFFFh
  db   (%1>>16) & 0FFh
  dw   ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)
  db   (%1 >> 24) & 0FFh
%endmacro

DA_32  EQU 4000h
DA_C   EQU 98h
DA_DRW EQU 92h

boot.asm

org  0x7c00;

LOAD_ADDR  EQU  0X9000

entry:
    mov  ax, 0
    mov  ss, ax
    mov  ds, ax
    mov  es, ax
    mov  si, ax
readFloppy:
    mov          CH, 1        ;CH 用来存储柱面号
    mov          DH, 0        ;DH 用来存储磁头号
    mov          CL, 2        ;CL 用来存储扇区号

    mov          BX, LOAD_ADDR       ; ES:BX 数据存储缓冲区

    mov          AH, 0x02      ;  AH = 02 表示要做的是读盘操作
    mov          AL,  1        ; AL 表示要练习读取几个扇区
    mov          DL, 0         ;驱动器编号,一般我们只有一个软盘驱动器,所以写死   
                               ;为0
    INT          0x13          ;调用BIOS中断实现磁盘读取功能
   
    JC           fin

    jmp          LOAD_ADDR
fin:
    HLT
    jmp  fin      
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值