user176121
user176121

Reputation: 720

How can I access system time using NASM?

How can I access the system time using NASM, on Linux?

(Editor's note: the accepted answer is for 16-bit DOS with direct hardware access; it would work inside DOSBox. The other answers are actually for Linux.)

Upvotes: 6

Views: 9262

Answers (5)

Kyle Rosendo
Kyle Rosendo

Reputation: 25277

On bare metal (in a custom OS), or in a DOS program:

%define RTCaddress  0x70
%define RTCdata     0x71

;Get time and date from RTC

.l1:    mov al,10           ;Get RTC register A
    out RTCaddress,al
    in al,RTCdata
    test al,0x80            ;Is update in progress?
    jne .l1             ; yes, wait

    mov al,0            ;Get seconds (00 to 59)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeSecond],al

    mov al,0x02         ;Get minutes (00 to 59)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeMinute],al

    mov al,0x04         ;Get hours (see notes)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeHour],al

    mov al,0x07         ;Get day of month (01 to 31)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeDay],al

    mov al,0x08         ;Get month (01 to 12)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeMonth],al

    mov al,0x09         ;Get year (00 to 99)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeYear],al

    ret

This uses NASM, and is from here.

This will not work under a normal OS like Linux that stops user-space processes from directly accessing hardware. You could maybe get this to work as root, with an ioperm(2) system call to allow access to that I/O port. Linux only updates the BIOS/hardware RTC to match the current system time during shutdown, not continuously, so don't expect it to be perfectly in sync, especially if the motherboard battery is dead.

Upvotes: 5

jpowell
jpowell

Reputation: 365

Using 32-bit code under Linux:

mov  eax, 13         ; call number = __NR_time
xor  ebx, ebx        ; tloc = NULL
int  0x80
; 32-bit time_t in EAX

This is a system call to time(2) (system call number 13), and it returns the signed 32-bit time_t in EAX.

(Unlike other system calls, return values >= -4095U (MAX_ERRNO) are still successes, and simply small negative numbers that represent times just before Jan 1, 1970. With a NULL pointer arg, time(2) can't fail. See the man page for details.)

Upvotes: 7

John Moore
John Moore

Reputation: 8274

As an addendum to the answer by Pyves above (using x86-64/NASM/Linux), if you want to get better clock resolution than a second, you can syscall with 228 instead of 201 to get seconds in one 64-bit variable and additional nanoseconds (beyond the seconds) in another 64-bit variable.

default rel
section .bss
    time: resq 2   ; 2 qwords for seconds and nanoseconds

section .text
    mov rax, 228   ; 228 is system call for sys_clock_gettime
    xor edi, edi   ; 0 for system clock (preferred over "mov rdi, 0")
    lea rsi, [time]
    syscall        ; [time] contains number of seconds
                   ; [time + 8] contains number of nanoseconds

From the man page, the system call is
int clock_gettime(clockid_t clock_id, struct timespec *tp);
struct timespec on x86-64 is a pair of unsigned 64-bit integers, with seconds at the low address, nanos at the higher address.

Upvotes: 2

Pyves
Pyves

Reputation: 6483

With NASM, if you are targeting Linux x86-64, you can simply do the following:

mov rax, 201
xor rdi, rdi        
syscall

201 corresponds to the 64-bit system call number for sys_time (as listed here). Register rdi is set to 0 so the return value after performing the system call is stored in rax, but you could also make it point to a memory location of your choosing. The result is expressed in seconds since the Epoch.

More information about this system call can be found in the time man page.

Upvotes: 5

PhiS
PhiS

Reputation: 4650

I'd say, depending on what platform you're on, you'll have to use an OS function.

On windows, try GetSystemTime. On linux, try gettimeofday - see related question here.

Upvotes: 0

Related Questions