繁体   English   中英

程序集 aarch64 获取当前的 unix 时间戳

[英]assembly aarch64 get current unix timestamp

我希望我可以从系统调用中获取当前的纳秒或微秒 unix 时间戳,然后将其存储到寄存器中,例如寄存器x0

我读了这个arch64 系统调用表,似乎我可以将它用于x8寄存器中的0x99 ,但我不知道如何使用它。 似乎时间戳的返回值将作为struct tms __user *tbuf存储在寄存器x0

我试过这个简单的asm代码

_start:
mov x8, 0x99
svc 0

在调试器中,在svc执行后,它的值1725984227x00x66e06de3的十六进制形式。

这是什么意思? 当前时间戳应该是 16xxx...xx 但它以 17xxx..xx 开头

正如@PeterCordes 提到的,您可以使用timesclock_gettime

但是根据您的参考表,我更喜欢在寄存器x8中具有内核约定0x71clock_gettime

这是我的代码,请注意我使用的是模块化编程程序集,因此需要.include

.data
//reseve 8 bytes for second and 8 bytes for nanosecond
TIME_OUTPUT: .zero 16

//line feed alloc for print newline
LF: .ascii "\n"

.text
.global _start
.include "exit.s" // import exit
.include "print.s" // import print library

_start:

 // getting current timestamp
 mov x0, 0 // x0=0 means CLOCK_REALTIME
 ldr x1, =TIME_OUTPUT // store output in specified addres
 mov x8, 0x71 // kernel convention
 svc 0 //execute

 // processing output
 ldr x2, [x1] // load second
 ldr x3, [x1, 8] // load nanosecond
 ldr x4, =1000000000 //nanosecond unit for multiplier
 mul x2, x2, x4 // multiply second
 add x0, x2, x3 // add second + nanosecond store in x0

 // print Unsigned Integer 64bit
 bl _print_u64 // the argument is in x0 which unsigned integer in bin>

 // print Line Feed (newline)
 ldr x0, =LF
 mov x1, 1
 bl _print

_exit:
 exit 0 // just exit gracefully with exit code 0

输出:

1657248826648171250

因此,如果您还没有制作打印功能,则必须制作print.s

/* Function Usage
_print <x0: start address> <x1: length>
 "Print string based on address offset and length."
eg: mov x0, 0x12345; mov x1, 5; bl _print

_print_uint64 <x0: uint64 in binary form>
 "Print string char format from uint64."
eg: mov x0, #12345; bl _print_uint64 // 12345
*/

/* Macro Usage
print_str <string>
 "Print string to the standard output."
eg: print_str "Hello world!\n"

print_uint64 <uint64>
 "Print string char format from uint64 to the stdout."
eg: print_uint64 123456
*/

// Register Dependencies: x0 until x8


.type _print, @function
.global _print
_print: //args: x0 start_address, x1 length
  mov x2, x1; mov x1, x0 //moving arguments x0, x1
  mov x0, 1; mov x8, 0x40; svc 0 //system call
  ret //void

.type _print_u64, @function
_print_u64: //args: x0 uint64 in binary form
 mov x1, 10 //divisor
 mov x5, 0 //total digit
 _dividing:
  udiv x2, x0, x1; msub x3, x2, x1, x0 //x2 quotient, x3 remainder
  add x4, x3, 0x30 //convert remainder to ascii char
  sub x5, x5, 1; strb w4, [sp,x5] //store ascii char
  mov x0, x2; cmp x0, 0; b.ne _dividing //jump if quotient not zero
 mov x0, sp; add x0, x0, x5 //x0 args
 neg x1, x5 //x1 args
 mov x6, lr //backup lr
 bl _print
 mov lr, x6 //restore lr
 ret //void

.macro print_str string
 .pushsection .data
 str\@: .ascii "\string"
 len\@= .-str\@
 .popsection
 ldr x0, =str\@
 mov x1, len\@
 bl _print
.endm

.macro print_u64 unsigned_int64
 .pushsection .data
 uint64\@: .8byte \unsigned_int64
 .popsection
 ldr x0, uint64\@
 bl _print_uint64
.endm

exit.s

/*
exit <code>
  "Exit the program with code, 0 means success."
eg: exit 0
*/

.macro exit code
 mov x0, #\code
 mov x8, #0x5d
 svc #0
.endm

这是摘要说明:您只需要专注于getting current timestamp和处理输出(可选)。

您将获得返回值,该值将存储在存储在寄存器x1中的内存地址中。 例如,当前秒是[x1]中的1657248826 当前纳秒为 [ 648171250 ] 中的 648171250

然后在processing output你只需要这样

ts = 1657248826
ts = ts * 1000000000 // because there are 9 zeros for nano unit
ts = ts + 648171250
/So the final is
ts = 1657248826648171250

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM