用AT&T汇编写的一个时钟

    技术2022-05-20  38

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

    下图为运行结果

     


    最新回复(0)