关于指令精简,这方面的事是由于loop,je,ja老报错,说越界多少字节。搜索了这方面信息才知道mov,dx,0,与sub
dx,dx的区别。这个看来是以后的学习内容 。
另外想找份工作, 本人linux开发3年,主要用c,pro*c,自动编译用的是大伙都知道 的make与架子。对计算机底层技术特别感兴趣。
说实话对成为什么 样的人还真没太大印象(没法有印象),目前的想法是成为由努力而成的技术型人才。说努力是因为天赋不够好。
本人现在一家金融公司后任高级(有帽子哟)开发人员,工作风平浪静,属于学习的时机。公司对技术诚然没太大要求,加上本人对技术的执着,再加上以往浪费了太多时间,所以想学点东西,再找个有技术层次的平台。
; display system time. press f1 to change the color
displayed, press esc to return main list. f3 exit
;
clear_screen 清空屏幕
;
把磁盘上0道0面1扇区内容移动到0:200处,再把本程序的工作部分代码移动到0道0面1扇区。(暂时未实现)
assume
cs:codesg
stacksg segment
dw 128 dup(0)
stacksg
ends
codesg segment
line db
6
csip dw 0,0
exitflag db
0 ; f3-2, esc-1. 只有在主界面才能退出,所以每次从时钟返回都会重置此值
color db 2
num
dw 0
start:
mov ax, stacksg
mov ss,
ax
mov sp, 128
mov ax, cs
mov
ds, ax
mov ax, 0
mov
es, ax
push es:[9*4]
pop csip[0]
push es:[9*4 + 2]
pop
csip[2]
cli
mov word
ptr es:[9*4], offset int9
mov es:[9*4 +
2], cs
sti
;###############################################################
main:
mov exitflag, 0
mov color, 2
call
display_main_list ;主菜单
;
在主菜单获取输入
get_main_input:
cmp
exitflag, 2
je
main_exit
; 1,2,3,4为有效输入,1-clock,2-set
clock,3-restart pc,4-start system
mov
ah, 0
int 16h
mov color, 2
cmp ah, 02h ; 通码 1-9:02-0a
je main_display_clock
cmp ah, 03h
je
main_set_clock
cmp ah, 04h
je
main_restart
cmp ah,
05h
je
main_start_system
;
其它情况,对比是否有功能键触发事件或忽略无效按键
jmp
get_main_input
main_exit:
jmp near
ptr exit ; 程序退出
main_display_clock:
;
显示时钟,返回后,则显示主界面
mov ah,
0
call clock
jmp near ptr main
main_set_clock:
mov ah, 1
call
clock
jmp near ptr
main
main_restart:
mov ax,
0ffffh
sub bx,bx
push ax
push
bx
retf
main_start_system:
mov
ax, 0
mov es, ax
call dword ptr es:200h
exit:
;
恢复向量表
push csip[0]
pop es:[9*4]
push csip[2]
pop es:[9*4 +
2]
mov ax, 4c00h
int 21h
;
主菜单功能
display_main_list:
jmp main_list
mainlist dw
display, setclock, resetpc, startsystem,
f3exit,escfunctiondes,null
display db
‘1) clock‘
setclock db ‘2) set
clock‘
resetpc db ‘3) reset
pc‘
startsystem db ‘4) start
system‘
f3exit
db ‘press f3 to exit this process‘
escfunctiondes db ‘press esc to return superior menu on
any page‘
null db 0
; 显示主菜单
main_list:
push cx
push dx
push bx
push
si
push ax
call clear_screen
mov cx, 6
mov dh,
line ; dh 行号
mov dl,
8 ; 列号主菜单不用变
mov bx, 0
loop_main_list:
mov si, mainlist[bx]
mov di, mainlist[bx + 2]
sub di,
si
mov num, di
call strshow
add bx,2
inc dh
loop loop_main_list
pop
ax
pop si
pop bx
pop
dx
pop cx
ret
; clock子函数,ah 传递功能号, 0- 显示时钟,1-
设置时钟
clock:
jmp short
do_clock
clocktable dw dis_clock,
set_clock
clock_str
db ‘20yy/mm/dd hh:mm:ss‘
row db 9,8,7,4,2,0
prompot dw year, month, day, hour, minite, second,
inputstr
year db
‘(YY):‘
month db
‘(MM):‘
day db ‘(DD):‘
hour db ‘(HH):‘
minite db ‘(mm):‘
second db
‘(ss):‘
inputstr db 3
dup(0)
validnum db 99h, 12h, 31h, 23h,
59h, 59h
; 秒: 0 分:2 时: 4 日 : 7 月:8
年:9
do_clock:
push
bx
push ax
push si
push
di
push cx
push ds
cmp ah, 1
ja do_clock_exit
cmp ah, 0
jb
do_clock_exit
mov bl,
ah
mov bh, 0
add bx,bx
jmp
word ptr clocktable[bx]
do_clock_exit:
jmp clock_ret
; 每1s显示一次时钟
dis_clock:
call clear_screen
mov dl, 8
mov dh,
line
mov num,
19
dis_per_second:
cmp exitflag,
1 ; only esc can return from clock screen
je dis_clock_ret
mov di, 2
mov si,
0
mov cx, 6
; 设置时钟字符串
_dis_get_clock:
mov al, row[si]
call _sys_readclock
mov
clock_str[di], ah
mov clock_str[di +
1], al
add di, 3
inc si
loop
_dis_get_clock
mov si, offset
clock_str
call strshow
call delay
jmp
short dis_per_second
dis_clock_ret:
jmp clock_ret
;
设置时钟
set_clock:
call
clear_screen
mov cx, 6
sub bx,bx
mov
dh, line
sub
di,di
set_clock_loop:
mov dl,
8
; 打印提示符
mov si,
prompot[bx]
mov num,
5
call strshow
add dl, 5
;
获取两次输入
set_clock_back:
mov
inputstr[0], 0
mov inputstr[1],
0
mov inputstr[2], 0
mov si, offset inputstr
mov num, 2
call strshow
mov num,
0
;
获取输入
set_clock_getnum:
cmp exitflag,
1
je set_clock_exit
mov ah, 0
int
16h
cmp ah, 02h ;
小于字符1
jb
set_clock_getnum
cmp ah,
1ch ; enter
je
set_clock_getnum_enter ; 响应回车
cmp ah, 0eh ; backspace
; 退格符
je
set_clock_getnum_backspace
cmp ah, 0bh
; 0 不符合以上情况下还大于字符0的,则忽略输入
ja set_clock_getnum
;
字符入栈
jmp near ptr
set_clock_getnum_push
set_clock_getnum_out:
call strshow
jmp set_clock_getnum
;
ah为要设置的数据,al为设置的地址
set_clock_getnum_next:
mov al, row[di] ;
call _sys_setclock
add bx, 2
inc dh
inc di
loop
set_clock_loop
jmp short
clock_ret
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
set_clock_getnum_enter:
push cx
mov
ah, inputstr[0]
mov cl,
4
shl ah, cl
mov al, inputstr[1]
and al, 00001111b
or ah,
al
;
校验输入是否合法,否则重新输入
pop cx
cmp ah, validnum[di]
ja set_clock_getnum_back
jmp near ptr
set_clock_getnum_next
set_clock_getnum_push:
cmp num, 2
je
set_clock_getnum_out
push
bx
mov bx, num
mov [si][bx], al
pop bx
inc num
jmp short set_clock_getnum_out
;
要输入字符在inputstr[0],[1]中
set_clock_exit:
jmp
clock_ret
set_clock_getnum_backspace:
; pop al
cmp num,
0
je
getnum_backspace_out
dec
num
push di
mov di, num
mov inputstr[di], 0
pop
di
getnum_backspace_out:
jmp short
set_clock_getnum_out
set_clock_getnum_back:
jmp set_clock_back
clock_ret:
pop ds
pop
cx
pop di
pop si
pop
ax
pop bx
ret
;
al要写入的地址,ah要写入的数据
_sys_setclock:
push
ax
out 70h, al
mov al,
ah
out 71h, al
pop
ax
ret
; input :al
,向70h端口写入的地址
; ouput ah, al,
_sys_readclock:
push cx
out 70h, al
in al, 71h
mov ah,
al
mov cl, 4
shr ah, cl
add
ah, 30h
and al,
00001111b
add al, 30h
pop cx
ret
delay:
push
ax
push dx
mov dx, 0BFFh
mov ax, 0
s_delay:
sub ax, 1
sbb
dx, 0
cmp ax, 0
jne s_delay
cmp dx, 0
jne
s_delay
pop dx
pop ax
ret
clear_screen:
push
bx
push cx
push ax
push
es
mov ax, 0b800h
mov es, ax
mov
cx, 1500
mov al, ‘ ‘
mov ah, 0
mov
bx, 0
s_clear_screen:
mov es:[bx],
ax
add bx, 2
loop s_clear_screen
pop es
pop ax
pop
cx
pop bx
ret
; int9
中断程序替代程序,esc置exitflag为1.f1改变颜色,无脑增加color的值,f3设置exitflag为2
int9:
push ax
in al, 60h
pushf
call dword ptr csip
; check if equal esc:01, f1:3b, f1 change color. esc
exit function
cmp al, 01h
;esc
je _int9_esc
cmp al,
3bh
je _int9_f1
cmp al,
3dh ;
F3 退出
je _int9_f3
mov exitflag, 0
jmp int9ret
_int9_f1:
inc color
jmp int9ret
_int9_f3:
mov exitflag, 2
jmp
int9ret
_int9_esc:
mov exitflag,
1
int9ret:
pop ax
iret
; dh,
dl 字符串在屏幕上显示的行与列
;
其中color为颜色
; num
传递要打印的字符数,打印bx个字符后或遇到0停止打印
; charstack:
strshow:
push bx
push
dx
push
di
push
es
push
ax
push
cx
;dh 行号, dl列号,
个数
mov ax,
0b800h
mov es,
ax
mov
al,160 ; 每行160字节
sub ah, ah
mul dh
add dl, dl
sub dh,
dh
add ax,
dx
mov di,
ax
mov ah,
color
mov cx,
num
sub bx,
bx
charshows:
mov al, [si][bx]
cmp al, 0
jne charstack_print
mov al, ‘ ‘
charstack_print:
mov es:[di], ax
add di, 2
inc
bx
loop
charshows
charstack_ret:
mov byte ptr es:[di], ‘
‘
pop
cx
pop
ax
pop
es
pop
di
pop
dx
pop
bx
ret
codesg
ends
end start