📄 05.htm
字号:
mov bp, sp ; 保存kernel的堆栈指针。
mov sp, dx ; 切换到进程的堆栈空间中
pushf ; 在进程的堆栈空间中压入标志寄存器Flag
push cs ; 在进程的堆栈空间中压入代码段值
push ax ; 在进程的堆栈空间中压入进程的入口地址偏移
pusha
push es
push ds ; 在进程的堆栈空间中保护CPU寄存器值
; 按公式:进程堆栈指针的存放地址=sptable+2*进程号
; 得到进程堆栈指针的存放地址,将进程堆栈指针的值存
; 到该内存单元中,
mov dx, sp
mov bx, [taskcount]
shl bx, 1
lea si, [sptable]
mov [ds:si + bx], dx
inc word [taskcount] ; 将进程号增1,指向下一个将被初始化的进程
mov sp, bp ; SP恢复为kernel的堆栈指针
pop ds
pop es
popa ; 恢复现场
ret ; 返回到kernel
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;进程调度子程序scheduler
;功能:1。保存被剥夺运行权的进程的堆栈指针
; 2。恢复下一个将被调度运行的进程的堆栈指针
; 3。从将被调度运行的进程的堆栈中恢复断点信息,
; 使CPU转到该进程去执行
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
scheduler:
pusha
push es
push ds ; 在当前进程的堆栈中保存断点处的CPU寄存器值
mov al, 0x20
out 0x20, al ; 给中断控制器8259送EOI指令
pushf
call 0xF000:0xFEA5 ; 使原系统时钟中断处理运行
mov ax, [current_task]
mov bx, ax
shl bx, 1
lea si, [sptable]
mov [ds:si + bx], sp ; 保存将被剥夺执行权的进程的堆栈指针
inc ax ; 取得下一将被调度的进程的进程号
cmp ax, MAXTASKS ; 该进程号是否超过最大进程数
jb move_on ; 若没超过,跳到 move_on 继续
xor ax, ax ; 超过最大进程数,清0,从第一个进程开始调度
move_on:
mov [current_task], ax ; 将更改后进程号的送入current_task单元保存
;按公式 进程堆栈指针的存放地址=sptable+2*进程号 取得进程堆栈指针
mov bx, ax
shl bx, 1
lea si, [sptable]
mov sp, [ds:si + bx] ; 将进程堆栈指针送到SP,切换到进程的堆栈空间
pop ds
pop es
popa ; 进程的堆栈空间从恢复上次进程被中断时
; 所有被保存的CPU寄存器
iret ; 激活被调度进程运行
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;键盘中断子程序keybd
;功能:读入键盘扫描码,转换为ASCII码后在显示器上输出
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
keybd:
sti
push ax
push bx
push cx
push di
push es
mov ax,0
in al,60h ; 读入键盘扫描码
cmp al,80h ; 是按键压入码还是释放码?
jb .l1 ; 是按键压入码则转 .l1处理
jmp .l2 ; 否则结束中断
.l1:
mov ah,0
mov si,ax
mov al,[si+asctab] ; 查表,转换为ASCII码
mov ah,0eh
int 10h ; 在显示器上输出转换后的ASCII码
cmp al,0dh ; 是否为回车键?
jnz .l2 ; 否,则结束中断
mov ax,0e0ah
mov bh,07h
int 10h ; 是回车键,则产生换行动作。
in al,61h
.l2
or al,80h
out 61h,al
and al,0x7f
out 61h,al ; 给键盘内的单片机发复位信号
pop es
pop di
pop cx
pop bx
pop ax
mov al,20h
out 20h,al ; 给中断控制器8259送EOI信号
iret ; 键盘中断结束
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;printhex:16 进制数显示子程序
;; 参数: 参数1=显示行坐标
;; 参数2=显示列坐标
;; 参数3=显示的一个字数值
;; 参数通过堆栈进行传递
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
printhex:
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push di
push es ;保存现场
mov ax,VIDEORAM
mov es,ax ;显示缓存段地址 0xb800 -> es
;按公式 (行号*80+列号)*2 将行列值转换为显示缓存的绝对地址
xor ax, ax
mov ax, word [bp+8] ; 从堆栈中取得行号
xor cx,cx
mov cl,80
mul cl ;行号*80 -> ax
add ax,[bp+6] ;从堆栈中取得列号,将列号+行号*80 -> ax
add ax,ax ;(行号*80+列号)*2
sub ax,2 ;显示缓存从0编址,调整为实际地址。
mov di, ax ;实际地址送di保存
mov ax, word [ss:bp+4] ; 从堆栈中取得要输出的16位数据
;将要输出的数据从低到高每4位一组转换为16进制数,转换规则为
;若数值<=9,则加0x30,否则加0x37.
;写到指定的显存中输出;
mov cx, 0x08
add di,cx
std
.continue
mov bx, ax
and bl, 0x0F
cmp bl, 0x9
ja .hex
add bl, 0x30
jmp .print
.hex:
add bl, 0x37
.print:
push ax
mov al,bl
mov ah,7
stosw
pop ax
sub cx, 2
shr ax, 4
cmp cx, 0
jnz .continue
pop es
pop di
pop dx
pop cx
pop bx
pop ax
pop bp ; 恢复现场
ret 6 ; 返回,清除参数,平衡堆栈
; End of printhex
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 数据区
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
task1ctr dw 0 ;task1计数器
task1ctra dw 0 ;task1时间延迟计数器
task2ctr dw 0 ;task2计数器
task2ctra dw 0 ;task2时间延迟计数器
task3ctr dw 0 ;task3计数器
task3ctra dw 0 ;task3时间延迟计数器
current_task dw MAXTASKS ;当前任务索引号
taskcount dw 0 ;当前kernel内的任务总数
sptable: resw MAXTASKS ;sptable 数组
;键盘扫描码/ascii码对照表
asctab db 0xff,0x1b,"1234567890-=",08h,09h,"qwertyuiop[]asdfghjkl;'zxcvbnm,./"
;;kernel 结束</CCID_CODE></PRE></TD></TR></TBODY></TABLE></CCID_NOBR></SPAN>
<P align=center> <BR><SPAN class=content01><A class=content01
href="http://developer.ccidnet.com/pub/disp/Article?columnID=303&articleID=35453&pageNO=1"><<上一页</A></SPAN>
<A class=content01
href="http://developer.ccidnet.com/pub/disp/Article?columnID=303&articleID=35453&pageNO=1">1</A>
<FONT color=#ff0000>2</FONT> <A class=content01
href="http://developer.ccidnet.com/pub/disp/Article?columnID=303&articleID=35453&pageNO=3">3</A>
<SPAN class=content01><A class=content01
href="http://developer.ccidnet.com/pub/disp/Article?columnID=303&articleID=35453&pageNO=3">下一页>></A></SPAN>
</P></TD></TR><!-- 包含文章结束--></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=580 align=center border=0>
<TBODY>
<TR>
<TD><A class=content
href="http://market.ccidnet.com/pub/disp/Column?columnID=380"><FONT
color=#0000ff>“中国IT市场情报中心”会员注册优惠月</FONT></A></TD></TR></TBODY></TABLE><!-- 包含相关文章开始-->
<TABLE
style="BORDER-RIGHT: #e2e3e4 1px solid; BORDER-TOP: #e2e3e4 1px solid; BORDER-LEFT: #e2e3e4 1px solid; BORDER-BOTTOM: #e2e3e4 1px solid"
cellSpacing=0 cellPadding=0 width=580 align=center border=0>
<TBODY>
<TR>
<TD class=content bgColor=#e2e3e4 height=21>相关文章</TD></TR>
<TR>
<TD bgColor=#ffffff>
<TABLE class=Name02 cellSpacing=2 cellPadding=2 width="100%"
border=0>
<TBODY>
<TR>
<TD height=23><IMG height=7 src="05.files/a_nav.gif"
width=7><A class=Name02
href="http://developer.ccidnet.com/pub/disp/Article?columnID=302&articleID=35451&pageNO=1">
编写实模式多任务操作系统模型之一</A> <SPAN
class=content01>(2002.12.31)</SPAN></TD></TR>
<TR>
<TD height=23><IMG height=7 src="05.files/a_nav.gif"
width=7><A class=Name02
href="http://developer.ccidnet.com/pub/disp/Article?columnID=743&articleID=35411&pageNO=1">
推进Linux发展 服务信息化</A> <SPAN
class=content01>(2002.12.31)</SPAN></TD></TR>
<TR>
<TD height=23><IMG height=7 src="05.files/a_nav.gif"
width=7><A class=Name02
href="http://developer.ccidnet.com/pub/disp/Article?columnID=308&articleID=35029&pageNO=1">
Linux时代来临,您的企业准备好了吗?</A> <SPAN
class=content01>(2002.12.26)</SPAN></TD></TR>
<TR>
<TD height=23><IMG height=7 src="05.files/a_nav.gif"
width=7><A class=Name02
href="http://developer.ccidnet.com/pub/disp/Article?columnID=302&articleID=35019&pageNO=1">
Linux、开放源码软件与公共政策</A> <SPAN
class=content01>(2002.12.26)</SPAN></TD></TR>
<TR>
<TD height=23><IMG height=7 src="05.files/a_nav.gif"
width=7><A class=Name02
href="http://developer.ccidnet.com/pub/disp/Article?columnID=382&articleID=34520&pageNO=1">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -