menu Andy's Blog
more_vert
Acrnel V0.1.zero
2020-10-18 | 日常 | 暂无评论 | 2177 次阅读 | 2055字
Andy
author
NUMsector      EQU    18       ; 最大扇区编号
NUMheader      EQU    1        ; 最大磁头编号
NUMcylind      EQU    5        ; 设置读取到的柱面编号

mbrseg         equ    7c0h     ; 启动扇区存放段地址
loaderseg      equ    800h     ; 从软盘读取LOADER到内存的段地址
kernalseg      equ    0c20h    ; 内核段地址 

jmp    short start             ; 为了制作PBP,第3个字节必须是 0x90。这里采用jmp short来占2字节 

        DB        0x90
        DB        "JIANGIPL"        ; 启动区的名称可以是任意字符串(8字节)
        DW        512                ; 每个扇区(sector)的大小必须为512字节
        DB        1                ; 簇(cluster)的大小必须为1个扇区
        DW        1                ; FAT的起始位置(一般从第一个扇区开始)
        DB        2                ; FAT的个数(必须为2)
        DW        224                ; 根目录的大小(一般设为244项)
        DW        2880            ; 该磁盘的的大小(必须为2880扇区)
        DB        0xf0            ; 磁盘的种类(必须为0xfd)
        DW        9                ; FAT的长度(必须为9扇区)
        DW        18                ; 一个磁道(track)有几个扇区(必须为18)
        DW        2                ; 磁头数(必须为2)
        DD        0                ; 不使用分区(必须为0)
        DD        2880            ; 重写一次磁盘大小
        DB        0,0,0x29        ; 意义不明,固定
        DD        0xffffffff        ; (可能是)卷标号码
        DB        "JIANG OS   "    ; 磁盘名称(11字节)
        DB        "FAT12   "        ; 磁盘格式名称(8字节)
        RESB    18                ; 先腾出18字节



start:

call showwelcome    ;初始化寄存器,打印必要信息 
call loader         ;执行loader,把现在这张软盘的数据全部读到8000h开始。 
jmp  kernalseg:0    ;跳转到内核。物理地址为c200h=8000h+4200h;8000为loader的
;开始地址,4200为kernal在FAT文件中的偏移地址
;注意jmp指令的操作后果,该跳转之后,CS=kernalseg=0c20h,IP=0,DS,ES保持不变。 

showwelcome: 
     mov   ax,mbrseg 
     mov   ds,ax   ;为显示各种提示信息做准备 
     mov   ax,loaderseg 
     mov   es,ax   ;为读软盘数据到内存做准备,因为读软盘需地址控制---ES:BX
     
     mov   si,welcome
     call  printstr
     call  newline
     ret

loader:
     mov   si, fyread
     call  printstr
     call  newline
     call  folppyload    ;将软盘的数据全部load到内存,从物理地址8000h开始 
     mov   si, Fycontent
     call  printstr
     call  showdata      ;可以验证一下从软盘读入的kernal程序数据是否正确(二进制) 
     ret



folppyload:                       
     call    read1sector
     MOV     AX,ES
     ADD     AX,0x0020
     MOV     ES,AX                ;一个扇区占512B=200H,刚好能被整除成完整的段,因此只需改变ES值,无需改变BP即可。 
     inc   byte [sector+11]
     cmp   byte [sector+11],NUMsector+1
     jne   folppyload             ;读完一个扇区
     mov   byte [sector+11],1
     inc   byte [header+11]
     cmp   byte [header+11],NUMheader+1
     jne   folppyload             ;读完一个磁头
     mov   byte [header+11],0
     inc   byte [cylind+11]
     cmp   byte [cylind+11],NUMcylind+1
     jne   folppyload             ;读完一个柱面

     ret
     
     
numtoascii:     ;将2位数的10进制数分解成ASII码才能正常显示。如柱面56 分解成出口ascii: al:35,ah:36
     mov ax,0
     mov al,cl  ;输入cl
     mov bl,10
     div bl
     add ax,3030h
     ret

readinfo:       ;显示当前读到哪个扇区、哪个磁头、哪个柱面 
     mov si,cylind
     call  printstr
     mov si,header
     call  printstr
     mov si,sector
     call  printstr
     ret


 
read1sector:                      ;读取一个扇区的通用程序。扇区参数由 sector header  cylind控制

       mov   cl, [sector+11]      ;为了能实时显示读到的物理位置
       call  numtoascii
       mov   [sector+7],al
       mov   [sector+8],ah

       mov   cl,[header+11]
       call  numtoascii
       mov   [header+7],al
       mov   [header+8],ah

       mov   cl,[cylind+11]
       call  numtoascii
       mov   [cylind+7],al
       mov   [cylind+8],ah

       MOV        CH,[cylind+11]    ; 柱面从0开始读
       MOV        DH,[header+11]    ; 磁头从0开始读
       mov        cl,[sector+11]    ; 扇区从1开始读        

        call       readinfo        ;显示软盘读到的物理位置
        mov        di,0
retry:
        MOV        AH,02H            ; AH=0x02 : AH设置为0x02表示读取磁盘
        MOV        AL,1            ; 要读取的扇区数
        mov        BX,    0         ; ES:BX表示读到内存的地址 0x0800*16 + 0 = 0x8000
        MOV        DL,00H           ; 驱动器号,0表示第一个软盘,是的,软盘。。硬盘C:80H C 硬盘D:81H
        INT        13H               ; 调用BIOS 13号中断,磁盘相关功能
        JNC        READOK           ; 未出错则跳转到READOK,出错的话则会使EFLAGS寄存器的CF位置1
           inc     di
           MOV     AH,0x00
           MOV     DL,0x00         ; A驱动器
           INT     0x13            ; 重置驱动器
           cmp     di, 5           ; 软盘很脆弱,同一扇区如果重读5次都失败就放弃 
           jne     retry

           mov     si, Fyerror
           call    printstr
           call    newline
           jmp     exitread
READOK:    mov     si, FloppyOK
           call    printstr
           call    newline
exitread:
           ret


printstr:                  ;显示指定的字符串, 以'$'为结束标记 
      mov al,[si]
      cmp al,'$'
      je disover
      mov ah,0eh
      int 10h
      inc si
      jmp printstr
disover:
      ret

newline:                     ;显示回车换行
      mov ah,0eh
      mov al,0dh
      int 10h
      mov al,0ah
      int 10h
      ret

showdata:  mov  si,0             ;验证显示从软盘读取到内存的数据 
           mov  ax, kernalseg 
           mov  es,ax
           mov  cx,9             ;控制输出的数据长度 
nextchar:  mov al,[es:si]
           mov ah,0eh
           int 10h
           inc si
           loop nextchar
           RET

welcome db 'Welcome Jiang OS!','$'
fyread  db 'Now Floppy Read Loader:','$'
cylind  db 'cylind:?? $',0    ; 设置开始读取的柱面编号
header  db 'header:?? $',0    ; 设置开始读取的磁头编号
sector  db 'sector:?? $',1    ; 设置开始读取的扇区编号
FloppyOK db '---Floppy Read OK','$'
Fyerror db '---Floppy Read Error' ,'$'
Fycontent db 'Floppy Content is:' ,'$'


times 510-($-$$) db 0
                 db 0x55,0xaa
(2) Kernel.asm

jmp near start

%macro   pos_get 0                           ;读取光标位置
         mov ah,03h
         mov bh,0
         int 10h
%endmacro

%macro win 6     ;建立窗口

         mov ah,06h
         mov al,%1
         mov bh,%2
         mov ch,%3
         mov cl,%4
         mov dh,%5
         mov dl,%6
         int 10h
%endmacro



%macro pos_curse 3            ;设置光标位置
         mov ah,2
         mov bh,%1
         mov dh,%2
         mov dl,%3
         int 10h
%endmacro

%macro printstr  4
       ;lea BP,welcome;ES:BP = 串地址  ;显示内存中的连续字符串(用指针)
       mov cx,%1  ;字符数量
       mov ah,13h
       mov al,01h ;前移光标
       mov bh,0   ;页
       mov bl,%2  ;颜色属性16h
       mov dh,%3  ;行
       mov dl,%4  ;列
       int 10h

%endmacro


%macro printbuf 0        ;显示内存中的连续字符串(不用指针)
      mov si,0
      mov cl,[keybuf+1]     ;cl为控制需要输出的字符数量
again:
      mov ah,0eh
      mov al,[keybuf+2+si]
      int 10h
      inc si
      loop again
%endmacro


officemsg db 'Welcome OFFICE Program,Press Esc to Exit'
gamesmsg db 'Welcome GAMES Program,Press Esc to Exit'
videomsg db 'Welcome VIDEO Program,Press Esc to Exit'
networkmsg db 'Welcome NETWORK Program,Press Esc to Exit'

tabinfo  db 'Please Input Tab Key to Select,Press Esc to Exit'

         manu_1   db '1. OFFICE   '
         manu_2   db '2. GAMES    '
         manu_3   db '3. VIDEO    '
         manu_4   db '4. NETWORK  '

firstinfo db 'Now You Have Comed OS Kernal,Please Press Enter Key to Run'
welcome db 'Welcome Jiang OS'
datetime  db  '????/??/?? ??:??:??'
dataend  db  '?'
row      db 0


start:
     
mov  ax, cs     ;从MBR跳转到此内核之后,CS=c20h ,IP=0。也即程序从偏移地址为0的地方开始放置 
mov  ds, ax     ;那么就无需指定ORG,只需要把DS,ES和CS指向同一段即可。 
mov  es, ax     ;这三句话在ORG 100H调试内核的时候同样适用,因此调试完成之后正式启用也无需修改程序。 


first:  call mainwin
        call shwelcome
        call showtime
        mov ah,0
        int 16h                        ;从键盘读字符 ah=扫描码 al=字符码
        cmp   ah,1ch                   ;enter键
        jz   firstenter
        jmp  first

submenu:
         mov  bp, manu_1
         mov  cx, manu_2-manu_1
         printstr  cx,16h,6,32

              mov  bp, manu_2
         mov  cx, manu_3-manu_2
         printstr  cx,16h,10,32

            mov  bp, manu_3
         mov  cx, manu_4-manu_3
         printstr  cx,16h,14,32

                  mov  bp, manu_4
         mov  cx, firstinfo-manu_4
         printstr  cx,16h,18,32

         ret

firstenter:

         win 0,3eh,1,0,23,79           ;按 enter键后刷新窗口

         mov bp, tabinfo
         mov cx,  manu_1- tabinfo
         printstr  cx,3eh,3,18

         win 0,65h,6,32,6,42
         win 0,65h,10,32,10,42
         win 0,65h,14,32,14,42
         win 0,65h,18,32,18,42

         call submenu

         pos_curse 0,6,32               ;光标设置在第1个菜单处

tabselect:mov  ah,0
         int  16h
         cmp  ah,0fh                    ;TAB键
         jz   inputtab

         cmp   ah,1ch                   ;选择之后按下enter键
         jz   nextenter

         cmp   ah,01h                   ;ESC键
         jz    first

         jmp  firstenter                ;不选择就一直等待

inputtab:pos_get                ;TAB键
         mov [row],dh

         add byte [row],4              ;挪到下一个菜单处
         cmp byte [row],22
         je  tabend
         jmp noend
tabend:  mov byte [row],6                     ;向下选择超界
noend:   win 0,6dh,[row],32,[row],40
         call submenu
         pos_curse 0,[row],32
         jmp tabselect

nextenter:
        pos_get                       ;定位什么地方按的ENTER
        mov  [row],dh

        CMP byte [row],6
        je  office

        CMP  byte [row],10
        je  games

        CMP  byte [row],14
        je  video

         CMP  byte [row],18
        je  network

        jmp  inputtab

office: win 0,3eh,1,0,23,79

         mov bp, officemsg
         mov cx,  gamesmsg- officemsg
         printstr  cx,3eh,3,22

         mov  ah,0
         int  16h
         cmp  ah,01h                    ;ESC功能
         jz   firstenter
         jmp  office


games:  win 0,3eh,1,0,23,79

         mov bp, gamesmsg
         mov cx,  videomsg- gamesmsg
         printstr  cx,3eh,3,22

         mov  ah,0
         int  16h
         cmp  ah,01h                    ;ESC功能
         jz   firstenter
         jmp  games

video:   win 0,3eh,1,0,23,79

         mov bp, videomsg
         mov cx,  networkmsg- videomsg
         printstr  cx,3eh,3,22

         mov  ah,0
         int  16h
         cmp  ah,01h                    ;ESC功能
         jz   firstenter
         jmp  video

network:win 0,3eh,1,0,23,79

         mov bp, networkmsg
         mov cx,  tabinfo- networkmsg
         printstr  cx,3eh,3,22

         mov  ah,0
         int  16h
         cmp  ah,01h                    ;ESC功能
         jz   firstenter
         jmp  network


shwelcome:
     mov bp,welcome
     mov cx, datetime-welcome
     printstr  cx,16h,0,30

     mov bp, firstinfo
     mov cx,  welcome- firstinfo
     printstr  cx,3eh,5,10
     ret

mainwin:
     win 0,3eh,0,0,24,79           ;定义窗口背景
     win 0,1fh,0,0,0,79            ;第一行
     win 0,1fh,24,0,24,79          ;最后一行
      ret



showtime:

        mov ah,04H             ;DH:DL=月:日 01:02   ch:cl=世纪:年,20:19
        int 1ah

        mov  bh,ch
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        add  bh,30h            ;Ch的高4位to ascii
        and  ch,0000_1111b
        add  ch,30h            ;Ch的低4位to ascii

        mov [datetime],bh
        mov [datetime+1],ch

        mov  bh,cl
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        add bh,30h            ;Cl的高4位to ascii
        and cl,0000_1111b
        add cl,30h            ;Cl的低4位to ascii

        mov [datetime+2],bh
        mov [datetime+3],cl

        mov  bh,dh
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        add  bh,30h            ;dh的高4位to ascii
        and  dh,0000_1111b
        add  dh,30h            ;dh的低4位to ascii

        mov [datetime+5],bh
        mov [datetime+6],dh

        mov  bh,dl
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        add  bh,30h            ;dl的高4位to ascii
        and  dl,0000_1111b
        add  dl,30h            ;dl的低4位to ascii

        mov [datetime+8],bh
        mov [datetime+9],dl

        mov ah,02H             ;CH:CL=时:分 DH=秒
        int 1ah

        mov  bh,ch
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        add  bh,30h            ;Ch的高4位to ascii
        and  ch,0000_1111b
        add  ch,30h            ;Ch的低4位to ascii

        mov [datetime+11],bh
        mov [datetime+12],ch

        mov  bh,cl
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        add bh,30h            ;Cl的高4位to ascii
        and cl,0000_1111b
        add cl,30h            ;Cl的低4位to ascii

        mov [datetime+14],bh
        mov [datetime+15],cl

        mov  bh,dh
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        SHR  bh,1
        add  bh,30h            ;dh的高4位to ascii
        and  dh,0000_1111b
        add  dh,30h            ;dh的低4位to ascii

        mov [datetime+17],bh
        mov [datetime+18],dh


        win 0,1dh,24,60,24,79     ;设置窗口颜色

             mov bp,datetime
     mov cx, dataend-datetime
     printstr  cx,16h,24,60

       ret

此乃Loader.asm

xnumadd    equ   0x7d00   ;分辨率x存放地址 
colorfuncport equ 3c8h   ;设置调色板功能端口
colorsetport equ 3c9h    ;设置调色板颜色端口
displayadd equ 0xa000    ;低分辨率640*480下显示缓冲区地址 
displayaddhigh equ 0x9000    ;存放高分辨率640*480下"显存线性缓冲区地址"的地址 
dptseg         equ    7e0h     ;DPT区段地址
VESA       equ  0


jmp   start  

gdt_size dw 80-1     ;GDT 表的大小 ;(总字节数减一,共5个描述符)
gdt_base dd 0x00007e00 ;GDT的物理地址

showmsg1     db '      Please Select Windows Resolution:$'
showmsg2     db '      1:1024X768$'
showmsg3     db '      2:640X480$'
inputcom     db '?'
noword       db '      :$'
megerror     db '      Input Error,Please Retry$'


start:    
mov  ax, cs     ;从MBR跳转到此内核之后,CS=c20h ,IP=0。也即程序从偏移地址为0的地方开始放置    
mov  ds, ax     ;那么就无需指定ORG,只需要把DS,ES和CS指向同一段即可。

mov  ax, xnumadd/10h  ;用于存放分辨率数据 
mov  es, ax

call   showmsg
call   userinput

call  setmode
call  backgroud
call  colorset

call  getdisplayaddr

mov     ax,dptseg
mov     es,ax          ;es用于gpt区寻址    gpt存放起始地址:0x00007e00h
call    createdpt   
jmp     protectmode

showmsg:
mov    cx,25
clear:
call   newline
loop   clear

mov    si, showmsg1
call   printstr
call   newline
call   newline
mov    si, showmsg2
call   printstr
call   newline
call   newline
mov    si, showmsg3
call   printstr
call   newline
call   newline

mov    cx,10
clear2:
call   newline
loop   clear2
ret

printstr:                  ;显示指定的字符串, 以'$'为结束标记
      mov al,[si]
      cmp al,'$'
      je disover
      mov ah,0eh
      int 10h
      inc si
      jmp printstr
disover:
      ret

newline:                     ;显示回车换行
      mov ah,0eh
      mov al,0dh
      int 10h
      mov al,0ah
      int 10h
      ret

          
userinput: mov     si, 0
input: 
           mov ah,0
           int 16h                        ;从键盘读字符 ah=扫描码 al=字符码
           mov ah,0eh                     ;把键盘输入的字符显示出来 
           int 10h
           cmp    al, 0dh                 ;回车作为输入结束标记
           je     inputover
           mov    [inputcom+si],al
           inc    si
           jmp    input

inputover: mov  bl, [inputcom]
           cmp  bl,'1'
           jne  inputislow
           mov word [es:0],1024
           mov word [es:2],768
           jmp totalover
inputislow:cmp  bl, '2'
           jne inputerror
           mov word [es:0],640
           mov word [es:2],480
           jmp totalover      
  inputerror: mov si, megerror
              call printstr  
              call newline
              mov  si,noword
              call printstr 
              jmp  userinput
   totalover: ret  


setmode:   
mov AX,4F02H
mov dx,word [es:0] 
cmp dx,1024
jne lowmode
mov bx,4105H   
jmp setover     ;1024*768 256色   第1个值4表示为要使用线性地址模式
lowmode:
mov bx,4101H        ;640*480  256色   第1个值4表示为要使用线性地址模式
setover: 
int 10h
ret


;取得该模式下显存线性地址,存入:90040处。调用0x4F01 功能号,获得信息
getdisplayaddr:
mov ax,displayaddhigh
mov es,ax
mov di,  0

mov ax , 0x4f01
mov cx , 0x101
int 0x10
;返回的结构体中偏移量为40 的地方,即es:di+40 处,用4字节存放了一个线性地址,
;这就是这个显卡在此模式下显存的线性地址
;dw  0x1234 --- 0x34 0x12  注意DWORD的内存放置顺序,低地址为低位,高地址为高位 
;[ es:VESA+40 ]低位,[ es:VESA+42 ] 高位,所以显存起始地址是: 0xe0000000
mov ebx,  [ es:VESA+40 ]   ;显卡线性地址送入ebx,后面创建GDT使用 
ret
   

;通过普通的0xa000方式演示画图 
drawimg:           ;满屏画同一颜色 
mov bl,3
mov ax,displayadd
mov es,ax
mov cx,0xffff
mov di,0
nextpoint:
mov  [es:di],bl   ;调色板颜色索引送往显存地址
inc di
loop  nextpoint
ret


backgroud:         ;背景色设置
mov dx,  colorfuncport
mov al,  0           ;建调色板索引0号
out dx,al

mov dx,  colorsetport   ;设置蓝色背景
mov al,0           ;R分量
out dx,al
mov al,0           ;G分量
out dx,al
mov al,35          ;B分量
out dx,al
ret

colorset:             ;显示色设置
mov dx,  colorfuncport
mov al,  1              ;建调色板索引1号
out dx,al

mov dx,  colorsetport     ;设置白色调色板
mov al,63           ;R分量
out dx,al
mov al,63           ;G分量
out dx,al
mov al,63          ;B分量
out dx,al

mov dx,  colorfuncport
mov al,  2                 ;建调色板索引2号
out dx,al

mov dx,  colorsetport     ;设置红色调色板
mov al,63           ;R分量
out dx,al
mov al,0           ;G分量
out dx,al
mov al,0          ;B分量
out dx,al

mov dx,  colorfuncport
mov al, 3           ;建调色板索引3号
out dx,al

mov dx,  colorsetport     ;设置黄色
mov al,30           ;R分量
out dx,al
mov al,30           ;G分量
out dx,al
mov al,0          ;B分量
out dx,al

mov dx,  colorfuncport
mov al, 4              ;建调色板索引4号
out dx,al

mov dx,  colorsetport     ;设置黑色
mov al,0           ;R分量
out dx,al
mov al,0           ;G分量
out dx,al
mov al,0          ;B分量
out dx,al

ret


;创建DPT子程序
createdpt:

lgdt [gdt_size] ;将DPT的地址和大小写入gdtr生效     默认DS


;创建0#描述符,它是空描述符,这是处理器的要求
mov dword [es:0x00],0x00             ;00
mov dword [es:0x04],0x00

;创建#1描述符,保护模式下的代码段描述符:CS
mov dword [es:0x08],0xc200ffff       ;01
mov dword [es:0x0c],0x00409800  ;0x0000_c200

;创建#2描述符,保护模式下的数据段描述符:DS(文本模式下的显示缓冲区) 10
mov dword [es:0x10],0x8000ffff
mov dword [es:0x14],0x0040920b  ;0x000b_8000    

;创建#3描述符,保护模式下的数据段2描述符:ES (图形模式下的线性地址显示缓冲区)11

;mov dword [es:0x18],0x0000ffff  
;mov dword [es:0x1c],0xe04f9200  ;0xe000_0000 
                           
mov word [es:0x18],0xffff  ;显卡线性地址的低16位
mov byte [es:0x1a],bl      ;0x00  ;由于象素较多,段界限设置成0xfffff
mov byte [es:0x1b],bh      ;0x00

shr ebx,16  ;取出ebx的高16位,显卡线性地址的高16位 
mov byte [es:0x1c],bl          ;0x00     
mov word [es:0x1d],0x4f92      ;f位段界限最高位
mov byte [es:0x1f],bh          ;0xe0    


;创建#4描述符,保护模式下的数据段描述符:DS(用户设置的分辨率) 100
mov dword [es:0x20],0x7d000100
mov dword [es:0x24],0x00409200  ;0x0000_7d00

;创建#5描述符,保护模式下的堆栈段描述符:SS
mov dword [es:0x28],0x00007a00  ;0x0000_7a00
mov dword [es:0x2c],0x00409600

ret


protectmode:
in al,0x92    ;打开A20地址线
or al,0000_0010B
out 0x92,al

cli ;保护模式下中断机制尚未建立,应禁止中断

mov eax,cr0  ;打开保护模式开关
or eax,1
mov cr0,eax 

;进入保护模式... ...

jmp dword 0x0008:inprotectmode ;16位的描述符选择子:
;32位偏移;这里需要扣除掉512B的MBR偏移量

[bits 32]
inprotectmode:

mov ax,00000000000_11_000B ;加载数据段选择子(0x11)
mov es,ax

call getmode
jmp  $


getmode:
mov ax,00000000001_00_000B ;加载数据段选择子(0x11)
mov ds,ax
mov bp,[00]   ;x     640
mov si,[02]   ;y     480
;mov bp,1024
cmp bp,1024
jne low
call win11024
call win21024
call win31024
call win41024
jmp  modeover
low:
call win1640
call win2640
call win3640
call win4640
modeover:
ret


;通过线性显存地址的方式绘制矩形 

win1640:  
mov edx,0             ;起始行 y坐标 
win1line:   
 
imul ebx,edx,640   ;edx*100放入ebx

mov edi,0           ;起始列 x 坐标
mov eax,edi         ;dx+edi
add eax,ebx
mov edi,eax
mov ecx,0
win1point:
mov  byte [es:edi],1   ;调色板颜色索引送往显存地址 
inc  edi
inc ecx
cmp ecx,640/2-640/30      ;矩形长度
jne win1point

inc edx

cmp edx,480/2-480/30       ;矩形高度
jne win1line
ret  


win2640:
mov edx,0             ;起始行 y坐标
win2line:

imul ebx,edx,640   ;edx*100放入ebx

mov edi,640/2           ;起始列 x 坐标
mov eax,edi         ;dx+edi
add eax,ebx
mov edi,eax
mov ecx,0
win2point:
mov  byte [es:edi],2   ;调色板颜色索引送往显存地址
inc  edi
inc ecx
cmp ecx,640/2      ;矩形长度
jne win2point

inc edx

cmp edx,480/2       ;矩形高度
jne win2line
ret


win3640:
mov edx,480/2            ;起始行 y坐标
win3line:

imul ebx,edx,640   ;edx*100放入ebx

mov edi,0           ;起始列 x 坐标
mov eax,edi         ;dx+edi
add eax,ebx
mov edi,eax
mov ecx,0
win3point:
mov  byte [es:edi],3   ;调色板颜色索引送往显存地址
inc  edi
inc ecx
cmp ecx,640/2      ;矩形长度
jne win3point

inc edx

cmp edx,640       ;矩形高度
jne win3line
ret

win4640:
mov edx,480/2+480/30            ;起始行 y坐标
win4line:

imul ebx,edx,640   ;edx*100放入ebx

mov edi,640/2+640/30           ;起始列 x 坐标
mov eax,edi         ;dx+edi
add eax,ebx
mov edi,eax
mov ecx,0
win4point:
mov  byte [es:edi],4   ;调色板颜色索引送往显存地址
inc  edi
inc ecx
cmp ecx,640/2-640/30      ;矩形长度
jne win4point

inc edx

cmp edx,480       ;矩形高度
jne win4line
ret


win11024:
mov edx,0             ;起始行 y坐标
win1line1024:

imul ebx,edx,1024   ;edx*100放入ebx

mov edi,0           ;起始列 x 坐标
mov eax,edi         ;dx+edi
add eax,ebx
mov edi,eax
mov ecx,0
win1point1024:
mov  byte [es:edi],1   ;调色板颜色索引送往显存地址
inc  edi
inc ecx
cmp ecx,1024/2-1024/30      ;矩形长度
jne win1point1024

inc edx

cmp edx,768/2-768/30       ;矩形高度
jne win1line1024
ret


win21024:
mov edx,0             ;起始行 y坐标
win2line1024:

imul ebx,edx,1024   ;edx*100放入ebx

mov edi,1024/2           ;起始列 x 坐标
mov eax,edi         ;dx+edi
add eax,ebx
mov edi,eax
mov ecx,0
win2point1024:
mov  byte [es:edi],2   ;调色板颜色索引送往显存地址
inc  edi
inc ecx
cmp ecx,1024/2      ;矩形长度
jne win2point1024

inc edx

cmp edx,768/2       ;矩形高度
jne win2line1024
ret


win31024:
mov edx,768/2            ;起始行 y坐标
win3line1024:

imul ebx,edx,1024   ;edx*100放入ebx

mov edi,0           ;起始列 x 坐标
mov eax,edi         ;dx+edi
add eax,ebx
mov edi,eax
mov ecx,0
win3point1024:
mov  byte [es:edi],3   ;调色板颜色索引送往显存地址
inc  edi
inc ecx
cmp ecx,1024/2      ;矩形长度
jne win3point1024

inc edx

cmp edx,768       ;矩形高度
jne win3line1024
ret


win41024:
mov edx,768/2+768/30            ;起始行 y坐标
win4line1024:

imul ebx,edx,1024   ;edx*100放入ebx

mov edi,1024/2+1024/30           ;起始列 x 坐标
mov eax,edi         ;dx+edi
add eax,ebx
mov edi,eax
mov ecx,0
win4point1024:
mov  byte [es:edi],4   ;调色板颜色索引送往显存地址
inc  edi
inc ecx
cmp ecx,1024/2-1024/30      ;矩形长度
jne win4point1024

inc edx

cmp edx,768       ;矩形高度
jne win4line1024
ret

此乃kernel.asm

发表评论
暂无评论
textsms
account_circle
email
link