6

如何在 Linux 上使用NASM访问系统时间?

(编者注:接受的答案是针对具有直接硬件访问权限的 16 位 DOS;它可以在 DOSBox 中工作。其他答案实际上是针对 Linux 的。)

4

5 回答 5

7

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.)

于 2011-07-09T17:39:27.510 回答
5

在裸机上(在自定义操作系统中)或在 DOS 程序中:

%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

这使用 NASM,并且来自这里

这在像 Linux 这样阻止用户空间进程直接访问硬件的普通操作系统下是行不通的您可以通过ioperm(2)系统调用以允许访问该 I/O 端口的方式使其以 root 身份工作。Linux 仅在关机期间更新 BIOS/硬件 RTC 以匹配当前系统时间,而不是连续更新,因此不要期望它完全同步,尤其是在主板电池没电的情况下。

于 2009-09-23T13:17:34.963 回答
4

使用 NASM,如果您的目标是 Linux x86-64,您可以简单地执行以下操作:

mov rax, 201
xor rdi, rdi        
syscall

201对应于 64 位系统调用号(如此sys_time所列)。Register设置为 0,因此执行系统调用后的返回值存储在 中,但您也可以将其指向您选择的内存位置。结果以自纪元以​​来的秒数表示。rdirax

有关此系统调用的更多信息可以在time 手册页中找到。

于 2017-04-15T10:21:44.387 回答
2

作为上述 Pyves 答案的附录(使用 x86-64/NASM/Linux),如果您想获得比一秒更好的时钟分辨率,您可以使用 228 而不是 201 进行系统调用以在一个 64 位变量中获得秒数,并且另一个 64 位变量中的额外纳秒(超过秒)。

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

手册页来看,x86-64 上的系统调用是
int clock_gettime(clockid_t clock_id, struct timespec *tp);
struct timespec一对无符号的 64 位整数,低地址为秒,高地址为纳秒。

于 2021-05-12T17:02:19.097 回答
0

我想说,根据您使用的平台,您必须使用操作系统功能。

在 Windows 上,尝试GetSystemTime。在 linux 上,尝试 gettimeofday -在此处查看相关问题。

于 2009-09-23T21:18:14.690 回答