本程序是利用对端口对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 源码学习笔记(一)内核引导
下图为运行结果