Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Linux中使用NASM汇编获得系统时间,而不使用从C导出的函数?_Linux_Assembly_X86_Nasm_X86 64 - Fatal编程技术网

如何在Linux中使用NASM汇编获得系统时间,而不使用从C导出的函数?

如何在Linux中使用NASM汇编获得系统时间,而不使用从C导出的函数?,linux,assembly,x86,nasm,x86-64,Linux,Assembly,X86,Nasm,X86 64,我正在为我的大学做一个项目。任务是打印当前日期和时间。 我成功地创建了一个打印数字的子程序,现在我只需要得到日期。 我试过了 但我只是打电话: .l1: mov al,10 ;Get RTC register A out RTCaddress,al 这足以让飞机坠毁。您是否知道如何修复此方法,或者我是否可以使用其他方法。 我在64位Linux上与Nasm合作。正如Jester所指出的,Jpowel也有类似的想法。JPowel提供了一个适用于32位和64

我正在为我的大学做一个项目。任务是打印当前日期和时间。 我成功地创建了一个打印数字的子程序,现在我只需要得到日期。 我试过了

但我只是打电话:

.l1:    mov al,10           ;Get RTC register A
        out RTCaddress,al
这足以让飞机坠毁。您是否知道如何修复此方法,或者我是否可以使用其他方法。
我在64位Linux上与Nasm合作。

正如Jester所指出的,Jpowel也有类似的想法。JPowel提供了一个适用于32位和64位的答案。64位Linux上通过int 0x80调用的兼容性带来了少量额外开销。64位特定的方法是使用64位指令SYSCALL调用sys_time内核例程。Linux系统时间手册页为。它将系统时间定义为:

概要

  #include <time.h>

  time_t time(time_t *t);
可以在上找到适合64位Linux系统调用的资源。此信息对于使用64位System V ABI内核调用约定设置sys_时间调用非常有用。他的桌子上有:

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


这建议在C库gmtimefunction的源代码的基础上使用C进行合理的实现。将其转换为X86_64汇编程序并不困难。代码非常简单。有了这样一个函数,将时间分解成单独的组件进行格式化一点也不困难。

正如Jester所指出的,Jpowel也有类似的功能。JPowel提供了一个适用于32位和64位的答案。64位Linux上通过int 0x80调用的兼容性带来了少量额外开销。64位特定的方法是使用64位指令SYSCALL调用sys_time内核例程。Linux系统时间手册页为。它将系统时间定义为:

概要

  #include <time.h>

  time_t time(time_t *t);
可以在上找到适合64位Linux系统调用的资源。此信息对于使用64位System V ABI内核调用约定设置sys_时间调用非常有用。他的桌子上有:

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


这建议在C库gmtimefunction的源代码的基础上使用C进行合理的实现。将其转换为X86_64汇编程序并不困难。代码非常简单。有了这样一个函数,将时间分解为单独的组件进行格式化一点也不困难。

使用@jpowel在链接问题中的答案来调用系统调用。您通常无法从用户模式访问RTC硬件,除非您以root用户身份运行并请求IO权限(这也是一个系统调用),因此,@Jester的可能副本感谢您的回答。问题是我需要一个完整的日期日/月/年+HH:MM:SS,据我所知,sys_time call从某个时间点返回的时间仅为秒。将其转换为日/月/年是您的工作。时间上的某个点是1970-01-01。剩下的只是算术。@Jester不是花费时间的最佳方式,但至少我现在知道怎么做了:ThanksUse@jpowel在调用系统调用的链接问题中给出的答案。您通常无法从用户模式访问RTC硬件,除非您以root用户身份运行并请求IO权限(这也是一个系统调用),因此,@Jester的可能副本感谢您的回答。问题是我需要一个完整的日期日/月/年+HH:MM:SS,据我所知,sys_time call从某个时间点返回的时间仅为秒。将其转换为日/月/年是您的工作。时间上的某个点是1970-01-01。剩下的只是算术。@Jester不是最好的消磨时间的方式,但至少我现在知道怎么做了:谢谢
  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.
%rax  System call    %rdi
---------------------------------
201   sys_time       time_t *tloc
        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