325 lines
9.7 KiB
NASM
325 lines
9.7 KiB
NASM
; showdate.asm
|
|
;
|
|
; prints the date and time to stdout
|
|
; equivalent to the following C++ program:
|
|
;
|
|
;#include <iostream.h>
|
|
;#include <time.h>
|
|
;
|
|
;int main()
|
|
;{
|
|
; time_t t;
|
|
; time(&t); // get the current time
|
|
; cout << ctime(&t); // convert to string and print
|
|
; return 0;
|
|
;}
|
|
;
|
|
; This code may be assembled and linked using Borland's TASM:
|
|
; tasm /la /m2 showdate
|
|
; tlink /Tdc showdate
|
|
;
|
|
STDOUT equ 01h ; handle of standard output device
|
|
|
|
DOS_GET_DATE equ 02ah ; get system date
|
|
DOS_GET_TIME equ 02ch ; get system time
|
|
DOS_WRITE_HANDLE equ 040h ; write to handle
|
|
DOS_TERMINATE equ 04ch ; terminate with error code
|
|
|
|
DOSINT macro function, subfunction
|
|
IFB <subfunction>
|
|
mov ah,(function AND 0ffh)
|
|
ELSE
|
|
mov ax,(function SHL 8) OR (subfunction AND 0ffh)
|
|
ENDIF
|
|
int 21h ; invoke DOS function
|
|
endm
|
|
|
|
|
|
MODEL tiny
|
|
;.STACK 100h
|
|
.CODE
|
|
|
|
;****************************************************************************
|
|
; main
|
|
;
|
|
; calls showdate routne and exists with 00 error code
|
|
;
|
|
; Entry:
|
|
;
|
|
; Exit:
|
|
;
|
|
; Trashed:
|
|
; none
|
|
;
|
|
;****************************************************************************
|
|
main proc far
|
|
.STARTUP ; sets up DS and stack
|
|
call showdate ;
|
|
.EXIT 0 ; return with errcode=0
|
|
main endp
|
|
|
|
;****************************************************************************
|
|
; showdate
|
|
;
|
|
; fetches the DOS system date, prints it to stdout and exits
|
|
; the format of the output is identical to that of the Posix ctime()
|
|
; function:
|
|
;
|
|
; Thu May 11 16:11:30 2000
|
|
;
|
|
; The day of week and month are always 3 characters long. The time of
|
|
; day is in 24hour form (e.g. 16:11:30 is a few minutes after four in
|
|
; the afternoon) and the year is always four digits. The whole thing is
|
|
; followed by a newline character (line feed = 0ah), making 25
|
|
; characters total.
|
|
;
|
|
; Note that ctime() returns 26 characters which is all of the above,
|
|
; followed by a terminating NUL char but this program does not emit a
|
|
; NUL.)
|
|
;
|
|
; Entry:
|
|
; DS points to segment for our data tables
|
|
;
|
|
; Exit:
|
|
; carry may be set if last write failed
|
|
;
|
|
; Trashed:
|
|
; none
|
|
;
|
|
;****************************************************************************
|
|
showdate proc
|
|
push ax bx cx dx ;
|
|
DOSINT DOS_GET_DATE ;
|
|
; returns the following
|
|
; cx = year (1980-2099)
|
|
; dh = month (1-12) == (Jan..Dec)
|
|
; dl = day (1-31)
|
|
; al = day of week (0-6) == (Sun..Sat)
|
|
|
|
push cx ;
|
|
push dx ; save the return values
|
|
|
|
; write the day of week
|
|
mov dx, offset dayname ;
|
|
mov cx,3 ; number of bytes to write
|
|
call WriteSubstring ;
|
|
|
|
; write the month
|
|
pop ax ; recall month/day
|
|
push ax ; and save it again
|
|
mov al,ah ; isolate just month
|
|
mov dx, offset monthname - 3 ; monthname array is 1-based
|
|
mov cx,3 ; number of bytes to write
|
|
call WriteSubstring ;
|
|
|
|
; write the day of the month
|
|
pop ax ;
|
|
call WriteNumber ;
|
|
call WriteSpace ;
|
|
|
|
; write the hour
|
|
DOSINT DOS_GET_TIME ; ch = hour, cl = min,
|
|
; dh = sec, dl = hundredths
|
|
|
|
push dx ; save seconds
|
|
push cx ; save minutes
|
|
mov al,ch ;
|
|
call WriteNumber ;
|
|
call WriteColon ;
|
|
|
|
; write the minutes
|
|
pop ax ;
|
|
call WriteNumber ;
|
|
call WriteColon ;
|
|
|
|
; write the seconds
|
|
pop ax ;
|
|
mov al,ah ;
|
|
call WriteNumber ;
|
|
call WriteSpace ;
|
|
|
|
; write the year (century first)
|
|
pop ax ;
|
|
xor dx,dx ; clear other reg before divide
|
|
mov cx,100 ; ax = ax/100, dx = remainder
|
|
div cx ;
|
|
push dx ; save remainder
|
|
call WriteNumber ;
|
|
|
|
; write the year (year within century)
|
|
pop ax ;
|
|
call WriteNumber ;
|
|
mov dx,offset newlinechar
|
|
call PrintOne ;
|
|
pop dx cx bx ax ; restore stack
|
|
ret ;
|
|
showdate endp
|
|
|
|
;****************************************************************************
|
|
; WriteSubstring
|
|
;
|
|
; writes a short substring to stdout
|
|
; specifically, prints CL characters, starting at DS:(DX+CL*AL)
|
|
;
|
|
; Entry:
|
|
; DS:DX ==> pointer to base of string array
|
|
; CL = size of each string
|
|
; AL = string selector (i.e. which string)
|
|
;
|
|
; Exit:
|
|
; CY set if there was an error writing last byte
|
|
; if CY clear,
|
|
; AX = 1 (number of bytes written)
|
|
; else
|
|
; AX = error code
|
|
;
|
|
; Trashed:
|
|
; BX CX DX
|
|
;
|
|
;****************************************************************************
|
|
WriteSubstring proc
|
|
mul cl ; ax = cl * al
|
|
add dx,ax ; offset now points to appropriate day string
|
|
call PrintIt ;
|
|
WriteSubstring endp
|
|
; deliberately fall through
|
|
;****************************************************************************
|
|
; WriteSpace
|
|
;
|
|
; writes a single space character (20h) to stdout
|
|
;
|
|
; Entry:
|
|
; DS points to data table segment
|
|
;
|
|
; Exit:
|
|
; CY set if there was an error writing last byte
|
|
; if CY clear,
|
|
; AX = 1 (number of bytes written)
|
|
; else
|
|
; AX = error code
|
|
;
|
|
; Trashed:
|
|
; BX CX DX
|
|
;
|
|
;****************************************************************************
|
|
WriteSpace proc
|
|
mov dx,offset spacechar;
|
|
WriteSpace endp
|
|
; deliberately fall through
|
|
;****************************************************************************
|
|
; PrintOne
|
|
;
|
|
; prints a single character pointed to by DS:DX
|
|
;
|
|
; Entry:
|
|
; DS:DX ==> points to the character to be printed
|
|
;
|
|
; Exit:
|
|
; CY set if there was an error writing last byte
|
|
; if CY clear,
|
|
; AX = 1 (number of bytes written)
|
|
; else
|
|
; AX = error code
|
|
;
|
|
; Trashed:
|
|
; BX CX DX
|
|
;
|
|
;****************************************************************************
|
|
PrintOne proc
|
|
mov cx,1 ;
|
|
PrintOne endp
|
|
; deliberately fall through
|
|
;****************************************************************************
|
|
; PrintIt
|
|
;
|
|
; prints the passed string to stdout
|
|
;
|
|
; Entry:
|
|
; DS:DX ==> points to string to be printed
|
|
; CX = number of bytes to be printed
|
|
;
|
|
; Exit:
|
|
; CY set if there was an error writing to stdout
|
|
; if CY clear,
|
|
; AX = number of bytes written
|
|
; else
|
|
; AX = error code
|
|
;
|
|
; Trashed:
|
|
; none
|
|
;
|
|
;****************************************************************************
|
|
PrintIt proc
|
|
mov bx,STDOUT ;
|
|
DOSINT DOS_WRITE_HANDLE ; write to the file
|
|
ret ;
|
|
PrintIt endp
|
|
|
|
;****************************************************************************
|
|
; WriteColon
|
|
;
|
|
; writes a colon character to stdout
|
|
;
|
|
; Entry:
|
|
; DS points to data segment
|
|
;
|
|
; Exit:
|
|
; CY set if there was an error writing to stdout
|
|
; if CY clear,
|
|
; AX = 1 (number of bytes written)
|
|
; else
|
|
; AX = error code
|
|
;
|
|
; Trashed:
|
|
; none
|
|
;
|
|
;****************************************************************************
|
|
WriteColon proc
|
|
mov dx,offset colonchar;
|
|
jmp PrintOne ;
|
|
WriteColon endp
|
|
|
|
;****************************************************************************
|
|
; WriteNumber
|
|
;
|
|
; prints the number in AL to stdout as two decimal digits
|
|
;
|
|
; Entry:
|
|
; AL = number to be printed. It must be in the range 00-99
|
|
;
|
|
; Exit:
|
|
; CY set if there was an error writing to stdout
|
|
; if CY clear,
|
|
; AX = 2 (number of bytes written)
|
|
; else
|
|
; AX = error code
|
|
;
|
|
; Trashed:
|
|
; BX CX DX
|
|
;
|
|
;****************************************************************************
|
|
WriteNumber proc
|
|
xor ah,ah ; clear out high half
|
|
mov cl,10 ; prepare to convert to decimal (base 10)
|
|
div cl ; divide it out
|
|
or ax,3030h ; convert to ASCII digits
|
|
push ds ; remember DS for later
|
|
push ax ; push converted chars on stack
|
|
mov dx,ss ;
|
|
mov ds,dx ; ds = ss
|
|
mov dx,sp ; print data from stack
|
|
mov cx,2 ; two characters only
|
|
call PrintIt ;
|
|
pop bx ; fix stack
|
|
pop ds ; restore ds pointer
|
|
ret ;
|
|
WriteNumber endp
|
|
|
|
;.DATA
|
|
dayname db "SunMonTueWedThuFriSat"
|
|
monthname db "JanFebMarAprMayJunJulAugSepOctNovDec"
|
|
spacechar db " "
|
|
colonchar db ":"
|
|
newlinechar db 0ah ; in C this is \n
|
|
|
|
end |