gpt4 book ai didi

linux - 如何在不使用从 C 导出的函数的情况下在 Linux 中使用 NASM 程序集获取系统时间?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:17:37 25 4
gpt4 key购买 nike

我正在为我的大学做一个项目。任务是打印当前日期和时间。我成功地完全设法创建了一个打印数字的子程序,我现在需要的只是获取日期。我试过 this approach:

%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

但只是调用:

.l1:    mov al,10           ;Get RTC register A
out RTCaddress,al

足以导致崩溃。您是否知道如何解决此方法,或者我可以使用任何不同的方法。我在 Linux 64 位上使用 Nasm。

最佳答案

正如 Jester 指出的那样 Jpowel answered 相似 question . JPowel 提供了适用于 32 位和 64 位的答案。通过 int 0x80 调用的兼容性(在 64 位 Linux 上)有少量与之相关的额外开销。 64位的具体方法是对sys_time内核例程使用64位指令SYSCALL。 Linux sys_time 联机帮助页是 here .它将 sys_time 定义为:

SYNOPSIS

  #include <time.h>

time_t time(time_t *t);

DESCRIPTION

  time() returns the time as the number of seconds since the Epoch,
1970-01-01 00:00:00 +0000 (UTC).

If t is non-NULL, the return value is also stored in the memory
pointed to by t.

可在 Ryan Chapmans blog 上找到有关 64 位 Linux syscall 的良好资源。 .此信息对于使用 64 位系统 V ABI 内核调用约定设置 sys_time 调用很有用。他的 table 有:

%rax  System call    %rdi
---------------------------------
201 sys_time time_t *tloc

此代码提供了一个使用指向 time_t 类型(long long)的指针调用 sys_time 的示例,并显示了将 0 作为第一个参数传递的第二种方法返回 rax 中的时间。

        section .data
time: dq 0

global _start
section .text

_start:
; Method 1: pass a pointer to a time_t (long long) to return time in
; sys_time = syscall(201, *long long)

mov rax, 201 ; system call 0xC9(201) = sys_time
mov rdi, time ; address of long long (qword) to return
; a time_t val
syscall ; make Linux system call

; Method 2: pass zero as the time_t parameter. sys_time returns
; value in rax .
; sys_time = syscall(201, *long long = 0)

mov rax, 201 ; system call 0xC9(201) = sys_time
xor rdi, rdi ; address of long long (qword) set to zero
syscall ; make Linux system call

; Do something useful with time
; Seconds since 1970-01-01 00:00:00 +0000 (UTC)

; Exit with the time
mov rdi, rax ; return least sig byte of time as return code
mov rax, 60 ; system call 0x3C(60) is exit
syscall ; make Linux system call

Stackoverflow answer建议基于 C 库 gmtime 函数的源代码在 C 中进行合理的实现。将其转换为 X86_64 汇编程序并不困难。代码非常简单。有了这样的功能,将时间分解成单独的组件进行格式化就一点都不困难了。

关于linux - 如何在不使用从 C 导出的函数的情况下在 Linux 中使用 NASM 程序集获取系统时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27777649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com