You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AArch64汇编调用syscall获取Unix时间戳返回值异常问题

问题原因
  • 你选错了系统调用号:AArch64 架构Linux环境下,0x99(十进制153)对应的是times()系统调用,这个接口的作用是获取进程自身及已回收子进程占用的CPU时间,根本不是用来获取Unix纪元墙上时间的。
  • 你对系统调用的返回规则理解有误:所有需要返回多字段结构体的系统调用,都不会把结构体内容直接存在通用寄存器里。系统调用返回时x0寄存器仅存储整数类型的返回值:成功时通常是0或者正整数结果,失败时是负的错误码;结构体类型的返回数据,需要你提前向内核传入一块自己拥有写权限的内存地址,内核会把数据拷贝到这块内存中。
  • 你调试时拿到的1725984227本身是2024年9月前后的秒级Unix时间戳,但这不是times()系统调用的标准返回结果——标准实现中times()返回的是从系统启动等固定参考点开始计算的时钟滴答数,和Unix纪元时间无关,你拿到这个值属于运行环境(如用户态模拟器、定制内核)的非标准行为,不能作为正确调用的参考。
正确实现方法

要获取纳秒/微秒级Unix时间戳,你需要调用clock_gettime接口,AArch64 Linux下对应的系统调用号是0x71(十进制113),参数规则如下:

  • x0:时钟类型ID,传0即CLOCK_REALTIME,代表获取从1970-01-01 00:00:00 UTC开始计算的真实Unix时间
  • x1:指向struct timespec结构的内存指针,结构总长度16字节,前8字节存储秒级时间戳,后8字节存储纳秒级偏移(取值范围0~999999999)
  • 系统调用返回后x0为0代表调用成功,你可以直接从传入的内存地址中读取时间值。

如果你不需要长期保存时间结构,直接用栈空间做临时缓冲区就能把秒级时间戳直接读到x0寄存器,示例代码如下:

_start:
    mov x8, #0x71       // 加载clock_gettime系统调用号
    mov x0, #0          // 指定时钟类型为CLOCK_REALTIME
    sub sp, sp, #16     // 在栈上分配16字节空间存timespec结构
    mov x1, sp          // 把缓冲区地址作为第二个参数传入
    svc #0              // 触发系统调用
    ldp x0, x1, [sp], #16  // 把秒值加载到x0,纳秒值加载到x1,同时回收栈空间
    // 此时x0就是你要的秒级Unix时间戳,x1是对应的纳秒偏移,除以1000即可得微秒偏移

注意:如果你运行的不是Linux环境(比如BSD、macOS、专用RTOS),系统调用号和传参规则会有差异,需要对应环境的调用表调整参数。

内容的提问来源于stack exchange,提问作者Citra Dewi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:58:01