本程序是利用对端口对CMOS RAM进行读写,调用内部时钟,获取时间信息。
1、先对端口的读写进行简单的介绍
(1)、读操作代码片段
mov n,%al #要访问单元地址
out %al,$0x70 #把地址发送到端口
jmp 1f #延时
1: in $0x71,%al #从端口读数据
(2)、写操作代码片段
mov n,%al #n是要访问的单元地址
out %al,$0x70 #把地址发送到端口
jmp 1f # 延时
1: mov m,%al #要写入的数据
out %al,$0x71h #写入端口
下图是CMOS RAM内部信息图
2、程序源码 timer.S
.code16
.text
.globl main
BOOTSEG=0x07c0
main: ljmp $BOOTSEG,$go
go:
mov %cs,%ax
mov %ax,%es
mov %ax,%ds
mov %ax,%ss
mov $500,%sp
mov $0x03,%ah#取得光标位置,存入$point
xor %bh,%bh
int $0x10
movw %dx,point
gettimer:
mov $0x0002,%dx#获取秒,分存入$time:4处
call getmessage
mov $time,%bp
movw %ax,4(%bp)
mov $0x0407,%dx#获取日,时
call getmessage
mov %ax,2(%bp)
mov $0x0809,%dx#获取年、月
call getmessage
movw %ax,(%bp)
movw point,%dx
mov $0x02,%ah #设置光标位置
xor %bx,%bx
int $0x10
mov $0x06,%cx
mov $time,%bp
printymd: #打印时间格式:yy MM dd hh mm ss
push %cx
call print_shi
pop %cx
add $0x01,%bp
loop printymd
end: jmp gettimer
print_shi:#从ss:%bp取一个字节,打印一个两位的十进制数
mov $2,%cx
mov (%bp),%dl
print_digit:
rol $4,%dl
movb $0x0e,%ah
movb %dl,%al
and $0x0f,%al
add $0x30,%al
int $0x10
loop print_digit
call printnull#打印一个空格
ret
getmessage: #dx为参数(要获取的参数基址)
mov %dh,%al
call getm
mov %al,%ah
mov %dl,%al
call getm
ret
getm:#从端口获取数据
out %al,$0x70
jmp 1f
1: in $0x71,%al
ret
printnull:#打印空格
mov $0x0e,%ah
mov $0x0,%al
int $0x10
ret
time:.word 0,0,0,0
point:.word 0
.org 510
.word 0xaa55
.code16
.text
.globl main
BOOTSEG=0x07c0
main: ljmp $BOOTSEG,$go
go:
mov %cs,%ax
mov %ax,%es
mov %ax,%ds
mov %ax,%ss
mov $500,%sp
mov $0x03,%ah#取得光标位置,存入$point
xor %bh,%bh
int $0x10
movw %dx,point
gettimer:
mov $0x0002,%dx#获取秒,分存入$time:0处
call getmessage
mov $time,%bp
movw %ax,4(%bp)
mov $0x0407,%dx#获取日,时
call getmessage
mov %ax,2(%bp)
mov $0x0809,%dx#获取年、月
call getmessage
movw %ax,(%bp)
movw point,%dx
mov $0x02,%ah #设置光标位置
xor %bx,%bx
int $0x10
mov $0x06,%cx
mov $time,%bp
printymd: #打印时间格式:yy MM dd hh mm ss
push %cx
call print_shi
pop %cx
add $0x01,%bp
loop printymd
end: jmp gettimer
print_shi:#从ss:%bp取一个字节,打印一个两位的十进制数
mov $2,%cx
mov (%bp),%dl
print_digit:
rol $4,%dl
movb $0x0e,%ah
movb %dl,%al
and $0x0f,%al
add $0x30,%al
int $0x10
loop print_digit
call printnull#打印一个空格
ret
getmessage: #dx为参数(要获取的参数基址)
mov %dh,%al
call getm
mov %al,%ah
mov %dl,%al
call getm
ret
getm:#从端口获取数据
out %al,$0x70
jmp 1f
1: in $0x71,%al
ret
printnull:#打印空格
mov $0x0e,%ah
mov $0x0,%al
int $0x10
ret
time:.word 0x1111,0,0,0
point:.word 0
.org 510
.word 0xaa55
本程序是一个带有引导的启动程序,主要是为了学习linux源码的需要,具体的编译、进行方法 ,请参见linux 0.12 源码学习笔记(一)内核引导
下图为运行结果