Acrnel V0.1.zero
2020-10-18 | 日常 | 暂无评论 | 2371 次阅读 | 2055字
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
本篇文章未指定许可协议。