系统的简单注解

来源:互联网 发布:vb语言用处 编辑:程序博客网 时间:2024/06/06 04:53


;===============================================================================
;=== 本程序为系统Core程序,其主要功能有:                                                                                       ===
;=== 1.在gdt中安装四个调用门                                                                                                                ===
;=== 2.安装core进程                                                                                                                                ===
;=== 3.安装两个用户进程                                                                                                                         ===
;=== 4.启动中断功能                                                                                                                                ===
;=== 5.用户进程和系统进程以40ms的间隔切换                                                                                       ===
;=== 6.两个进程分别在界面上显示图形                                                                                                   ===
;=== 7.通过鼠标的点击控制用户进程图形的显示                                                                                    ===
;===============================================================================
%include "00_header.asm"
 
;===============================================================================
;===                                                        该处开始Core代码                                                                    ===
;===============================================================================
SECTION  core  vstart=0xc0010000
  [bits 32]

;-------------------------------------------------------------------------------
     ;初始化调色板
     call Set_color_palette            

;-------------------------------------------------------------------------------
     ;安装所有外部调用接口
     call install_all_external_handle  
 
;-------------------------------------------------------------------------------
     ;启动中断功能
  call interrupt_init

;-------------------------------------------------------------------------------
     ;安装系统进程结构
     call Load_core_task

;-------------------------------------------------------------------------------
  ;创建用户任务1
     mov eax, 100                       ;用户进程代码起始扇区号
     mov ebx, 8                         ;用户进程代码扇区个数
     mov ecx, USR1_PROC                 ;用户进程控制模块proc_ctrl的偏移地址
     mov word [ecx + proc_ctrl.left_x], 1
     mov word [ecx + proc_ctrl.left_y], 101
     mov word [ecx + proc_ctrl.len_x], 157
     mov word [ecx + proc_ctrl.len_y], 97 
     call Load_usr_task 

  ;创建用户任务2
     mov eax, 200                       ;用户进程代码起始扇区号
     mov ebx, 8                         ;用户进程代码扇区个数
     mov ecx, USR2_PROC                 ;用户进程控制模块proc_ctrl的偏移地址
     mov word [ecx + proc_ctrl.left_x], 161
     mov word [ecx + proc_ctrl.left_y], 101
     mov word [ecx + proc_ctrl.len_x], 157
     mov word [ecx + proc_ctrl.len_y], 97
     call Load_usr_task
   
;-------------------------------------------------------------------------------
     ;安装实时时钟中断
     call install_0x20_interrupt
 
;-------------------------------------------------------------------------------
     ;安装鼠标中断
     call install_0x74_interrupt

     ;启动鼠标
     call enable_mouse 
 
;-------------------------------------------------------------------------------
     ;安装BS声卡中断
  call install_0x25_interrupt
 
  ;启动声音的播放
     call play_sound
 
;-------------------------------------------------------------------------------
     ;绘制系统进程窗口
     mov ecx, SYS_PROC                 ;系统进程控制模块proc_ctrl的偏移地址
     mov word [ecx + proc_ctrl.left_x], 1
     mov word [ecx + proc_ctrl.left_y], 1
     mov word [ecx + proc_ctrl.len_x], 317
     mov word [ecx + proc_ctrl.len_y], 98
     mov edx, SYS_PROC
     call draw_task_window    

;-------------------------------------------------------------------------------
     ;安装键盘中断 
     call install_0x21_interrupt 
   
;-------------------------------------------------------------------------------
     ;启动控制台
     call start_console
       
;-------------------------------------------------------------------------------        
_sleep:
     call move_mouse                       ;处理鼠标动作
     call handle_keyboard_input            ;读取并显示键盘输入字符
     call sys_clock                        ;显示系统时间
  hlt
  jmp _sleep

;-------------------------------------------------------------------------------
make_gate_descriptor:                   ;构造门的描述符(调用门等)
          ;输入:EAX=门代码在段内偏移地址
          ;       BX=门代码所在段的选择子
          ;       CX=段类型及属性等(各属
          ;          性位都在原始位置)
          ;返回:EDX:EAX=完整的描述符
  push ebx
  push ecx
 
  mov edx,eax
  and edx,0xffff0000                 ;得到偏移地址高16位
  or dx,cx                           ;组装属性部分到EDX
  
  and eax,0x0000ffff                 ;得到偏移地址低16位
  shl ebx,16                         
  or eax,ebx                         ;组装段选择子部分
 
  pop ecx
  pop ebx
 
  ret

;-------------------------------------------------------------------------------
Set_gate_sel:                             ;安装系统调用门
                                          ;输入参数: eax-—offset, ebx-—sector
                                          ;输出参数: cx—-gdt中的选择子

     push edx                              ;保存edx寄存器

     xor ecx, ecx                          ;ecx清零
     sgdt [pgdt]                           ;获取gdt表长度和基址
     mov cx, word [pgdt]                   ;段界限
     mov edx, dword [pgdt+2]               ;段基址
     inc cx                                ;gdt表长度
     add edx, ecx                          ;安装地址
     mov word [edx], ax                    ;低16位offset
     shr eax, 16
     mov word [edx+6], ax                  ;高16位offset
     mov word [edx+2], bx                  ;安装Selecter
     mov word [edx+4], 0x0ec00             ;安装属性。P-1,DPL-3,TYPE-12
     add word [pgdt], 8                    ;gdt表长度增加8字节
     lgdt [pgdt]                           ;重新安装gdt表到系统

     pop edx                               ;弹出edx
  ret  


;-------------------------------------------------------------------------------
start_console:                              ;启动控制台(其实就是在系统窗口的第一排显示一个‘>’)
     xor eax, eax
     mov ax, [key_y_point]
     shl eax, 16
     mov ax, [key_x_point]
     mov bl, [key_code_mem + 0x34]          ;该字符对应的扫描码为0x34,为'>'
     mov cl, 7
     call disp_letter_font
 
     ;调整显示位置
     mov ax, [key_x_point]
     add ax, 8
     mov [key_x_point], ax
     mov cl, 1                              ;设置光标为红色
     call disp_cursor                       ;显示光标
     ret 
 
;-------------------------------------------------------------------------------
handle_keyboard_input:                      ;处理键盘输入
     pushad
 
     mov al, 0xff 
     call keyboard_output                   ;读取一个键盘输入字符
     cmp al, 0xff                           ;如果为0xff,说明没有读取到字符
     jz _end_handle_keyboard_input

     ;判断字符的类型 -- 功能键、可显示字符
     call keyboard_char_type
     cmp bl, 0x0                            ;是功能键吗
     jz _char_isfunction

     ;是可显示字符,显示它,同时调整下一个显示字符对应的位置
     and eax, 0x0ff
     xor ebx, ebx
     mov bl, [key_code_mem + eax]          ;使用键盘输入码从编码表中找到按键对应的编码    
     call disp_one_char
     popad
     ret
 
_char_isfunction:                          ;是功能键,处理之    
     call handle_function_key

_end_handle_keyboard_input: 
     popad
     ret 

;-------------------------------------------------------------------------------
disp_one_char:                              ;显示一个字符,并调整显示位置
                                            ;输入:bl - 需要显示的字符
     ;在对应的位置显示字符
     xor eax, eax
     mov ax, [key_y_point]
     shl eax, 16
     mov ax, [key_x_point]
     mov cl, 7
     call disp_letter_font
    
     ;防止字符写出右边框
     mov ax, [key_x_point]
     add ax, 8
     cmp ax, 310
     jb _rewrite_x_point
     mov ax, 2                              ;x回到最左边
     mov bx, [key_y_point]          
     add bx, 16                             ;y下移一行
     cmp bx, 68                             ;判断是否超出系统进程的窗口
     jb _rewrite_y_point             
     mov bx, 6                              ;y回到最上一行
_rewrite_y_point: 
     mov [key_y_point], bx
_rewrite_x_point: 
     mov [key_x_point], ax
 
     ;如果x回到一行的最左边,显示‘>’
     cmp ax, 2
     jz _disp_left_console 
     mov cl, 1                              ;设置光标颜色为红色
     call disp_cursor                       ;显示光标
     ret
 
_disp_left_console:
     xor eax, eax
     mov ax, [key_y_point]
     shl eax, 16
     mov ax, [key_x_point]
     mov bl, [key_code_mem + 0x34]          ;该字符对应的扫描码为0x34,为'>'
     mov cl, 7
     call disp_letter_font
 
     ;调整显示位置
     mov ax, [key_x_point]
     add ax, 8
     mov [key_x_point], ax
     mov cl, 1                              ;设置光标为红色
     call disp_cursor                       ;显示光标    
     ret

;-------------------------------------------------------------------------------
disp_cursor:                                ;显示光标
                                            ;输入:cl - 光标颜色

     pushad
     mov bl, [key_code_mem + 12]            ;光标对应的编码为12
     xor eax, eax
     mov ax, [key_y_point]
     shl eax, 16
     mov ax, [key_x_point]
     call disp_letter_font
     popad
     ret 

;-------------------------------------------------------------------------------
handle_function_key:                        ;处理功能键
                                            ;输入:al - 扫描码

     cmp al, 0x1c                           ;是否是“回车”键
     jnz _end_handle_function_key

     ;首先将原光标变黑
     mov cl, 0                              ;设置光标为黑色
     call disp_cursor                       ;显示光标 
 
     ;下面处理回车键。首先调整光标到下一行的最左边
     mov word [key_x_point], 2              ;x回到最左边
     mov bx, [key_y_point]    
     add bx, 16                             ;y下移一行
     cmp bx, 68                             ;判断是否超出系统进程的窗口
     jb _function_rewrite_y_point             
     mov bx, 6                              ;y回到最上一行
_function_rewrite_y_point: 
     mov [key_y_point], bx

     ;坐标调整完毕,显示“>”
     xor eax, eax
     mov ax, [key_y_point]
     shl eax, 16
     mov ax, [key_x_point]
     mov bl, [key_code_mem + 0x34]          ;该字符对应的扫描码为0x34,为'>'
     mov cl, 7
     call disp_letter_font
 
     ;调整显示位置
     mov ax, [key_x_point]
     add ax, 8
     mov [key_x_point], ax
     mov cl, 1                              ;设置光标为红色
     call disp_cursor                       ;显示光标
 
_end_handle_function_key: 
     ret
 
;------------------------------嵌入代码文件------------------------------------- 
align 4 
%include "01_interrupt.asm"
%include "02_mouse.asm" 
%include "03_timer.asm"
%include "04_process.asm" 
%include "05_memory.asm"
%include "06_color.asm"
%include "07_external_interface.asm"
%include "08_bs16.asm"
%include "09_font.asm"
%include "10_keyboard.asm"

;--------------------------------全局变量---------------------------------------
align 4
  pidt             dw 0
       dd 0
  pgdt             dw 0
       dd gdt_base_address     ;GDT的性地址
                        
     _sys_ponit_x     dw 0                    ;亮点在X轴的值
     _sys_color       db 1,0                  ;亮点的颜色

     key_x_point      dw 2                    ;x的初始值为2
     key_y_point      dw 6                   ;y的初始值为6
   
     key_code_mem     db 0x0,   0x0,   0x1,   0x2,   0x3,   0x4,   0x5,   0x6,
                      db 0x7,   0x8,   0x9,   0x0,   0x24,  0x0,   0x0,   0x0,
                      db 0x1a,  0x20,  0x0e,  0x1b,  0x1d,  0x22,  0x1e,  0x12,
                      db 0x18,  0x19,  0x0,   0x0,   0x0,   0x0,   0x0a,  0x1c,
                      db 0x0d,  0x0f,  0x10,  0x11,  0x13,  0x14,  0x15,  0x0,      
                      db 0x0,   0x0,   0x0,   0x0,   0x23,  0x21,  0x0c,  0x1f,
                      db 0x0b,  0x16,  0x17,  0x0,   0x25,  0x0,   0x0,   0x0,
                      db 0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,
                      db 0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0
      
;-------------------------------------------------------------------------------
SECTION core_trail
;-------------------------------------------------------------------------------
core_end:




core.asm文件的被投影到0xc0010000地址处开始运行。系统的运行流程是:


  1. 初始化调色板;

  2. 安装用户进程可调用的系统接口;

  3. 启动中断功能;

  4. 安装系统进程结构,并设置为当前运行进程;

  5. 创建用户进程12。在这里,用户进程的控制结构已经写入了进程的运行链表,每隔40毫秒,时钟中断程序会自动切换链表中的进程;

  6. 安装并启动时钟中断;

  7. 安装并启动鼠标中断;

  8. 安装SoundBlaster声卡中断,并启动声音的播放;

  9. 绘制系统进程的窗口;

  10. 安装键盘中断;

  11. 启动控制台;

  12. 进入系统进程的循环中。在该循环中,鼠标输入和键盘输入会被处理,同时在系统窗口的右下角显示流逝的秒数;


 


简单介绍一下各个接口的功能。


  1. start_console。在系统窗口的第一排最左显示一个‘>’提示符,并显示一个红色光标;

  2. handle_keyboard_input。读取键盘输入的扫描码,判断是功能键还是显示字符,并在系统进程的窗口中显示。当前功能键仅处理了“回车”键;

  3. disp_one_char。如果键盘输入的是一个可显示字符,调用该接口。该接口显示一个字符,并调整光标的位置;

  4. disp_cursor。显示光标。光标的颜色可有bl设置;

  5. handle_function_key。如果键盘输入的是一个功能字符,调用该接口。当前仅处理了回车键。


 


下面部分为嵌入实现各个功能的asm文件。


;------------------------------嵌入代码文件-------------------------------------  


align 4     


%include"01_interrupt.asm"


%include"02_mouse.asm"    


%include"03_timer.asm"


%include "04_process.asm"  


%include"05_memory.asm"


%include"06_color.asm"


%include"07_external_interface.asm"


%include"08_bs16.asm"


%include"09_font.asm"


%include"10_keyboard.asm"


 


key_code_mem这个数组,用于保存键盘扫描码对应的字符点阵的地址。例如,‘1’这个按键对应的扫描码为0x02。在以0x2为偏移,在key_code_mem数组中对应的值为0x1。而又将0x1作为偏移量,在09_font.asm文件中的font_letter_mem数组中,找到‘1’这个按键对应的点阵的地址。


 


下面是整个系统运行时的画面:



  1. 最上面为系统进程窗口,下面两个分别为用户进程1和用户进程2的窗口;

  2. 用户进程1展示一颗四季变换的树,用户进程2展示一个变化的方形;

  3. 进程窗口中可以看到输入的字符、光标以及计时器;

  4. 中间的四个像素的小点为鼠标,可以全屏移动;


0 0