程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> 匯編源碼系列之clock

匯編源碼系列之clock

編輯:匯編語言

這個都是過去DOS時代的匯編源碼,雖然已經過去了,但是對於學習匯編還是有幫助的,匯編語言只是程序員一門基礎語言,大多人掌握即可,不一定要深入研究.......

CGROUP   GROUP VECTOR,CODESEG
VECTOR   SEGMENT AT 0H
   DB  6CH DUP(?)    ;FILLER
TIME_LO DW  ?      ;DOS TIME
TIME_HI DW  ?      ;DOS TIME
VEC_IP   DW        ;CLOCK UPDATE VECTOR IP
VEC_CS   DW        ;CLOCK UPDATE VECTOR CS
VECTOR   ENDS
CODESEG SEGMENT PARA
   ASSUME CS:CODESEG,DS:CGROUP
   ORG  100H
CLK   PROC FAR
   JMP  SETUP      ;ATTACH TO DOS
INTRPT   LABEL DWORD
INT_IP   DW  0      ;OLD UPDATE VECTOR IP
INT_CS   DW  0      ;OLD UPDATE VECROR CS
TICKS   DW  0      ;TICK COUNTER
SCR_OFF DB  0,0      ;SCREEN OFFSET IN BUFFER
CRT_PORT DW  0      ;SCREEN STATUS PORT
flag   db  0
TIME   DB  8 DUP(':',0BH)    ;TIME SAVE AREA
CLK_INT LABEL NEAR
   PUSH AX      ;SAVE REGISTERS
   PUSH CX
   PUSH DI
   PUSH SI
   PUSH DS
   PUSH ES
   PUSHF        ; AND FLAGS
   CALL CS:[INTRPT]    ;DO OLD UPDATE INTERRUPT
   MOV  CX,0040H     ;GET SEGMENT OF DOS TABLE
   MOV  DS,CX      ;PUT IN DS
   MOV  CX,CS:TICKS    ;GET TICK COUNT
   INC  CX      ;INCREMENT IT
   CMP  CX,20    ;01F4H      ;HAS A MINUTE GONE BY?
   JB  NO_MINUTE    ;NO, MOVE ON
   CALL UPDATE      ;YES, UPDATE CLOCK AND
   MOV  CX,0      ; RESET TICK COUNTER
NO_MINUTE:
   MOV  CS:TICKS,CX    ;SAVE UPDATED TICK COUNT
   MOV  CX,0B000H    ;GET VIDEO SEGMENT
   MOV  ES,CX      ;PUT IN ES
   MOV  DX,CS:CRT_PORT    ;GET CRT STATUS PORT ADDR
   MOV  DI,WORD PTR CS:SCR_OFF ;GET SCREEN BUFFER OFFSET
   LEA  SI,CS:TIME    ;GET DOS TIME
   MOV  CX,16      ;SET UP TO MOVE 10 BYTES
   CLI        ;DISABLE OTHER INTERRUPTS
WAIT1:   IN  AL,DX      ;READ CRT STATUS
   TEST AL,1      ;CHECK FOR VERTICAL RETRACE
   JNZ  WAIT1      ;WAIT FOR RETRACE LOW
   MOV  AH,CS:[SI]    ;GET FIRST BYTE TO MOVE
WAIT2:   IN  AL,DX      ;GET CRT STATUS
   TEST AL,1      ;CHECK FOR VERTICAL RETRACE
   JZ  WAIT2      ;WAIT FOR RETRACE HIGH
   MOV  ES:[DI],AH    ;MOVE BYTE TO SCREEN
   INC  DI      ;INCREMENT INDEX
   INC  SI
   LOOP WAIT1      ;MOVE NEXT BYTE
   STI        ;ENABLE INTERRUPTS
   POP  ES      ;RESTORE REGISTERS
   POP  DS
   POP  SI
   POP  DI
   POP  CX
   POP  AX
   IRET        ;RETURN FROM INTERRUPT
CLK   ENDP
UPDATE   PROC NEAR
   PUSH AX      ;SAVE REGISTERS
   PUSH BX
   PUSH CX
   PUSH DX
   PUSH DS
   MOV  AX,0040H     ;GET ADDRESS OF DOS TABLE
   MOV  DS,AX      ;PUT IN DS
   MOV  AX,TIME_HI    ;GET HIGH BYTE OF DOS TIME
   mov  flag,0      ;am flag
HOUR:   CMP  AX,0CH      ;CONVERT TO HOURS
   JLE  H1
   mov  flag,1      ;set to pm
   SUB  AX,0CH
   JMP  HOUR
H1:   AAM        ;CONVERT TO ASCII
   ADD  AX,3030H
   LEA  BX,CS:TIME    ;GET ADDRESS OF TIME AREA
   MOV  CS:[BX],AH    ;SAVE HOURS FIRST DIGIT
   MOV  CS:[BX+2],AL    ;SAVE HOURS SECOND DIGIT
   MOV  AX,TIME_LO    ;GET DOS TIME LOW BYTE
   MOV  CX,8H      ;CONVERT TO MINUTES
   SHR  AX,CL
   MOV  DX,3CH
   MUL  DL
   SHR  AX,CL
   AAM        ;CONVERT TO ASCII
   ADD  AX,3030H
   MOV  CS:[BX+6],AH    ;SAVE MINUTES FIRST DIGIT
   MOV  CS:[BX+8],AL    ;SAVE MINUTES SECOND DIGIT
   mov  byte ptr cs:[bx+12],'a'
   cmp  flag,0      ;is it am?
   jz  goahead
   mov  byte ptr cs:[bx+12],'p'
goahead:
   mov  byte ptr cs:[bx+14],'m'
   POP  DS      ;RESTORE REGISTERS
   POP  DX
   POP  CX
   POP  BX
   POP  AX
   RET
UPDATE   ENDP
SETUP:   MOV  AX,0      ;GET ADDRESS OF VECTOR TABLE
   MOV  DS,AX      ;PUT IN DS
   CLI        ;DISABLE FURTHER INTERRUPTS
   MOV  AX,[VEC_IP]    ;GET ADDRESS OF OLD UPDATE IP
   MOV  CS:[INT_IP],AX    ;SAVE IT
   MOV  AX,[VEC_CS]    ;GET ADDRESS OF OLD UPDATE CS
   MOV  CS:[INT_CS],AX    ;SAVE IT
   MOV  VEC_IP,OFFSET CLK_INT ;PUT ADDRESS OF CLK IN VECTOR IP
   MOV  VEC_CS,CS    ;PUT CS OF CLK IN VECTOR CS
   STI        ;ENABLE INTERRUPTS
   MOV  AH,0FH      ;READ VIDEO STATUS
   INT  10H
   SUB  AH,8      ;SUBTRACT 8 CHAR TIME FROM NCOLS
   SHL  AH,1      ;MULTIPLY BY 2 FOR ATTRIBUTE
   MOV  CS:SCR_OFF,AH    ;SAVE SCREEN TIME LOCATION
   MOV  WORD PTR CS:CRT_PORT,03BAH ;SAVE MONO STATUS PORT ADDR
   TEST AL,4      ;CHECK FOR COLOR MONITOR
   JNZ  MONO      ;IF MONO, MOVE ON
   ADD  WORD PTR CS:SCR_OFF,8000H  ;ADD COLOR OFFSET TO TIME OFFSET
   MOV  WORD PTR CS:CRT_PORT,03DAH ;SAVE COLOR STATUS PORT ADDR
MONO:   CALL UPDATE      ;DO FIRST UPDATE & PRINT TIME
   MOV  DX,OFFSET SETUP    ;GET END ADDRESS OF NEW INTERRUPT
   INT  27H      ;TERMINATE AND REMAIN RESIDENT
   DB  117 DUP(0)    ;FILLER
CODESEG ENDS
   END  CLK


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved