6

LinuxでNASMを使用してシステム時刻にアクセスするにはどうすればよいですか?

(編集者注:受け入れられた答えは、ハードウェアに直接アクセスできる16ビットDOS用です。DOSBox内で機能します。他の答えは実際にはLinux用です。)

4

5 に答える 5

7

Linuxで32ビットコードを使用する:

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

これは(システムコール番号13)へのシステムコールであり、EAXでtime(2)署名された32ビットを返します。time_t

(他のシステムコールとは異なり、戻り値> = -4095U(MAX_ERRNO)は引き続き成功し、1970年1月1日直前の時間を表す単純な小さな負の数です。NULLポインター引数を使用するとtime(2)、失敗することはありません。詳細。)

于 2011-07-09T17:39:27.510 に答える
5

ベアメタル(カスタムOSの場合)または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などの通常のOSでは機能しません。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(ここsys_timeにリストされている)の64ビットシステムコール番号に対応します。レジスタは0に設定されているため、システムコールを実行した後の戻り値はに格納されますが、選択したメモリ位置を指すようにすることもできます。結果は、エポックからの秒数で表されます。rdirax

このシステムコールの詳細については、タイムマンページを参照してください。

于 2017-04-15T10:21:44.387 に答える
2

上記のPyvesによる回答の補足として(x86-64 / NASM / Linuxを使用)、1秒よりも優れたクロック解像度を取得したい場合は、201ではなく228でsyscallを実行して、1つの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

マニュアルページから、システムコールは
int clock_gettime(clockid_t clock_id, struct timespec *tp);
struct timespecx86にあります-64は符号なし64ビット整数のペアであり、下位アドレスに秒、上位アドレスにnanosがあります。

于 2021-05-12T17:02:19.097 に答える
0

使用しているプラ​​ットフォームによっては、OS機能を使用する必要があると思います。

Windowsでは、GetSystemTimeを試してください。Linuxでは、gettimeofdayを試してください。関連する質問はこちらをご覧ください。

于 2009-09-23T21:18:14.690 に答える