⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setup.asm

📁 是经典的UNIX的部分源代码
💻 ASM
字号:
[BITS 16]           
[ORG 0x0000]
;--------------------------------------------------------------------------------------------------------
jmp                 main
;--------------------------------------------------------------------------------------------------------
;;数据区说明(基址)
;;0x0000  boot 程序
;;0x1000  setup 程序
;;0x2000  登陆图 3
;;0x3000  字库
;;0x4000  光标
;;0x5000  登陆图 1
;;0x6000  登陆图 2
;;0x7000  应用程序图标
;;0x8000  系统数据及堆栈区
;;0x9000  kernel 程序
;;把 kernel 读到 0x9000 的意义在于可以让它访问更大的空间,全局变量并不在程序中分配空间,而只分配它的指针
;-------------------------------------------------------------------------------------------------------
BOOT_DRIVER         db  0

VESA:               times 512 db 0                          ;;分配一块区域存放 vesa 返回的信息
;---------------------------------------------------------------------------------------------------------
;;下面定义临时 GDT 表描述符
;;总共定义三个段,一个空段由 intel 保留,一个代码段,一个数据段
gdt_descriptor:
                    dw                  0xffff              ;;GDT 表的大小
                    dw                  gdt                 ;;GDT 表的位置
                    dw                  0x0001              ;;此处的 1 是由于段基址为 0x1000
														                              	;;如果 SETUP_SEG 不是 0x1000 则更换此值
gdt:
  gdt_null:
                    dw                  0x0000
                    dw                  0x0000
                    dw                  0x0000
                    dw                  0x0000
  gdt_kernel_code:                                          ;;内核代码段,把整个内存空间做为一个整段
                    dw                  0xffff              
                    dw                  0x0000
                    dw                  0x9a00              ;;非一致代码段
                    dw                  0x00cf
  gdt_system_data:
                    dw                  0xffff
                    dw                  0x0000
                    dw                  0x9200              ;;非一致数据段
                    dw                  0x00cf    
;---------------------------------------------------------------------------------------------------------
get_boot_driver:                                            ;;取得启动驱动器号,此号由 boot 程序保留
  push              fs
  
  mov               ax , 0x8000
  mov               fs , ax
  mov               al , [ fs:0 ]
  mov               [ BOOT_DRIVER ] ,al
  
  pop               fs
  ret
;---------------------------------------------------------------------------------------------------------
set_vesa_model:                                             ;;设置显卡模式
  push              es
  push              fs    
  
  ;;设置显卡模式
  mov               ax , 0x4f02
  mov               bx , 0x4114                             ;;800 * 600 ( 5:6:5 ) ;虚拟机不支持高色  
  int               0x10
  
  ;;取得该模式下显存线性地址
  mov               bx , 0x1000
  mov               es , bx  
  mov               bx , 0x8000
  mov               fs , bx
  mov               di , VESA  
  mov               ax , 0x4f01
  mov               cx , 0x114
  int               0x10  
  mov               eax , [ es:VESA + 40 ]
  mov               [ fs:1 ] , eax

  pop               es
  pop               fs
  ret
;--------------------------------------------------------------------------------------------------------
read_login_bmp1:
  ;;下面继续读入第 0 面的第 2 磁道,共18扇区,(login.bmp ),存入 0x5000:0000 处   
  mov               ax , 0x5000
  mov               di , 7                                  ;;欲读入的磁道总数(0.2 , 1.2 , 0.3 , 1.3 , 0.4 , 1.4 , 0.5)
  mov               dh , 0
  mov               ch , 2
  
  call              read_disk_length_less_64K 
  ret
;---------------------------------------------------------------------------------------------------  
read_application_bmp
  ;;下面继续读入第 1 面的第 11 磁道,共18扇区,(login.bmp ),存入 0x7000:0000 处 
  mov               ax , 0x7000
  mov               di , 4                                  ;;欲读入的磁道总数(1.11 , 0.12 , 1.12 , 0.13)
  mov               dh , 1
  mov               ch , 11
  
  call              read_disk_length_less_64K 
  
  ret
;--------------------------------------------------------------------------------------------------- 
read_login_bmp2:
  ;;下面继续读入第 1 面的第 5 磁道,共18扇区,(login.bmp ),存入 0x6000:0000 处  
  mov               ax , 0x6000
  mov               di , 7                                  ;;欲读入的磁道总数(1.5 , 0.6 , 1.6 , 0.7 , 1.7 , 0.8 , 1.8)
  mov               dh , 1
  mov               ch , 5
  
  call              read_disk_length_less_64K 
  
  ret
;--------------------------------------------------------------------------------------------------- 
read_logout_bmp:  
  ;;下面继续读入第 1 面的第 12 磁道,共18扇区,(login.bmp ),存入 0x2000:0000 处  
  mov               ax , 0x2000
  mov               di , 6                                  ;;欲读入的磁道总数(1.13 , 0.14 , 1.14 , 0.15 , 1.15 , 0.16)
  mov               dh , 1
  mov               ch , 13
  
  call              read_disk_length_less_64K  
  
  ret
;--------------------------------------------------------------------------------------------------- 
read_cursor:
  ;;下面继续读入第 0 面的第 9 磁道,共18扇区,(login.bmp ),存入 0x4000:0000 处
  mov               ax , 0x4000
  mov               di , 4                                  ;;欲读入的磁道总数(0.9 , 1.9 , 0.10 , 1.10)
  mov               dh , 0
  mov               ch , 9
  
  call              read_disk_length_less_64K  
  
  ret
;--------------------------------------------------------------------------------------------------- 
read_font_lib:
  push              es
  
  ;;读入中文,起始 0.11.1
  mov               di , 2                                  ;;读的总扇区数( 0.11.1 , 0.11.2 )
  mov               ax , 0x3000
  mov               es , ax
  mov               bx , 0
  mov               dh , 0
  mov               ch , 11
  mov               cl , 1                                  ;;启始 1 扇区
  
  .read_font_lib_1:
  mov               ah , 2                                  ;;功能号 2 表示读磁盘扇区
  mov               dl , [ BOOT_DRIVER ]                    ;;驱动器号
  mov               al , 1                                  ;;读入扇区数
  int               0x13
  jc                .read_font_lib_1
  
  dec               di
  cmp               di , 0 
  je                .read_font_lib_end
  inc               cl
  add               bx , 512
  jmp               .read_font_lib_1
  
  .read_font_lib_end:  
  pop               es
  ret
;--------------------------------------------------------------------------------------------------------
read_kernel:                                                ;;读入 kernel 程序
  push              es
 
  .read_kernel_1:
  mov               ax , 0x9000          
  mov               es , ax
  mov               bx , 0
  mov               ah , 2 
  mov               dl , [ BOOT_DRIVER ] 
  mov               dh , 0 
  mov               ch , 0 
  mov               cl , 4            
  mov               al , 15				                    
  int               0x13
  jc                .read_kernel_1 
  
  add               bx , 15 * 512
  
  .read_kernel_2:
  mov               dh , 1
  mov               dl , [ BOOT_DRIVER ]
  mov               ch , 0
  mov               cl , 1
  mov               ah , 2
  mov               al , 18
  int               0x13
  jc                .read_kernel_2
  
  pop               es
  ret
;------------------------------------------------------------------------------------------------------
;;存入的段起始位置放在 ax 中
;;欲读入的磁道总数放在 di 中
;;起始面放入 dh 中
;;起始磁道放入 ch 中
read_disk_length_less_64K:
  push              es
  
  mov               es , ax
  mov               bx , 0

  .read_disk_length_less_64K_1:
  mov               ah , 2                                  ;;功能号 2 表示读磁盘扇区
  mov               dl , [ BOOT_DRIVER ]                    ;;驱动器号
  mov               cl , 1                                  ;;启始扇区1扇区
  mov               al , 18                                 ;;读入扇区数
  int               0x13  
  jc                .read_disk_length_less_64K_1
  
  dec               di
  cmp               di , 0
  je                .read_disk_length_less_64K_end
  
  add               bx , 18 * 512
  xor               dh , 1
  cmp               dh , 0
  jne               .read_disk_length_less_64K_1
  inc               ch
  jmp               .read_disk_length_less_64K_1
   
  .read_disk_length_less_64K_end:
  pop               es
  ret
;--------------------------------------------------------------------------------------------------- 
read_top_bmp:
  push              es
  
  mov               ax , 0x3000
  mov               di , 2
  mov               dh , 1
  mov               ch , 16
  
  mov               es , ax
  mov               bx , 1024

  .read_top_bmp_1:
  mov               ah , 2                                  ;;功能号 2 表示读磁盘扇区
  mov               dl , [ BOOT_DRIVER ]                    ;;驱动器号
  mov               cl , 1                                  ;;启始扇区1扇区
  mov               al , 18                                 ;;读入扇区数
  int               0x13  
  jc                .read_top_bmp_1
  
  dec               di
  cmp               di , 0
  je                .read_top_bmp_end
  
  add               bx , 18 * 512
  xor               dh , 1
  cmp               dh , 0
  jne               .read_top_bmp_1
  inc               ch
  jmp               .read_top_bmp_1
   
  .read_top_bmp_end:
  pop               es
  ret
;;-----------------------------------------------------------------------------------------------
main:  
  ;;初始化寄存器,因为 Bios 中断及 call 会用到堆栈或 ss 寄存器
  ;;在 CPU 启动或复位时是由 BIOS 初始化的,而现在进行了段转移,需要我们重新设置
  mov               ax , 0x1000
  mov               ds , ax  
  mov               ax , 0x8000
  mov               ss , ax
  mov               sp , 0xffff
   
  ;;取得启动驱动器号
  call              get_boot_driver
  
  ;;设置显示模式
  call              set_vesa_model
  
  ;;读入图片
  call              read_login_bmp1
  call              read_login_bmp2
  call              read_cursor
  call              read_application_bmp
  call              read_logout_bmp
  
  ;;读入字库
  call              read_font_lib
  call              read_top_bmp
  
  ;;读入 kernel 程序
  call              read_kernel
  
  ;;下面开始为进入保护模式而进行初始化工作                                                       
  lgdt              [ gdt_descriptor ]                      ;;载入gdt的描述符  
  
  ;;下面设置进入32位保护模式运行
  cli                                                       ;;关中断
  
  mov               eax , cr0
  or                eax , 1
  mov               cr0 , eax  

  jmp dword         0x8:0x90000   
;-------------------------------------------------------------------------------------
times 1024-($-$$) db 0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -