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

本程序是利用对端口对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内部信息图

 

用AT&T汇编写的一个时钟_第1张图片

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 源码学习笔记(一)内核引导

下图为运行结果

 

用AT&T汇编写的一个时钟_第2张图片

你可能感兴趣的:(c,linux,汇编,AT&T)