Kar*_*zki 2 linux x86 assembly x86-64 nasm
我正在为我的大学做一个项目。任务是打印当前日期和时间。我成功地创建了一个打印数字的子程序,我现在需要的只是获取日期。我试过这种方法:
%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
Run Code Online (Sandbox Code Playgroud)
但只是打电话:
.l1: mov al,10 ;Get RTC register A
out RTCaddress,al
Run Code Online (Sandbox Code Playgroud)
足以导致崩溃。您知道如何解决这种方法吗,或者我可以使用任何不同的方法。我正在 Linux 64 位上使用 Nasm。
正如 Jester 指出的,Jpowel回答了一个类似的 问题。JPowel 提供了适用于 32 位和 64 位的答案。调用的兼容性(在 64 位 Linux 上)int 0x80有少量与之相关的额外开销。64位的具体方法是使用64位指令SYSCALL给sys_time内核例程。Linuxsys_time联机帮助页在这里。它定义sys_time为:
概要
Run Code Online (Sandbox Code Playgroud)#include <time.h> time_t time(time_t *t);描述
Run Code Online (Sandbox Code Playgroud)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.
syscall可以在Ryan Chapmans 博客上找到64 位 Linux 的良好资源。此信息对于sys_time使用 64 位 System V ABI 内核调用约定设置调用非常有用。他的表有:
Run Code Online (Sandbox Code Playgroud)%rax System call %rdi --------------------------------- 201 sys_time time_t *tloc
此代码提供了sys_time使用指向time_t类型 (long long)的指针进行调用的示例,并显示了将 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
Run Code Online (Sandbox Code Playgroud)
这个Stackoverflow 答案建议了一个基于 C 库gmtime函数源代码的合理的 C 实现。将其转换为 X86_64 汇编程序并不困难。代码非常简单。有了这样的功能,将时间分解为单独的组件进行格式化根本不困难。