如何在NASM x64汇编中获取真实毫秒级系统时间?
获取x64 Linux下的毫秒级系统时间(NASM汇编)
你之前使用的syscall 201是time()系统调用,仅能返回秒级时间戳。要获取真实的毫秒级精度时间,有两种常用方案:
方案一:使用gettimeofday()系统调用
gettimeofday()(syscall号仍为201)会返回包含秒和微秒的时间结构,通过计算可以得到毫秒级总时间:
section .text global _start _start: ; 调用gettimeofday(&tv, NULL) mov rax, 201 ; 指定gettimeofday的系统调用号 mov rdi, tv ; 第一个参数:指向timeval结构的指针 xor rsi, rsi ; 第二个参数:时区指针,传NULL syscall ; 计算总毫秒数:秒数*1000 + 微秒数/1000 mov rbx, [tv] ; 读取秒数到rbx mov rcx, 1000 imul rbx, rcx ; 秒数转换为毫秒 mov rdx, [tv + 8] ; 读取微秒数到rdx mov rcx, 1000 xor rax, rax div rcx ; 微秒数转换为毫秒(结果在rax) add rax, rbx ; rax中存储总毫秒数 ; 此处可使用rax的值(毫秒级时间)做后续逻辑,比如取最后一位生成随机数 ; 退出程序 mov rax, 60 mov rdi, 0 syscall section .data tv: times 16 db 0 ; 定义timeval结构,x64下占16字节(两个8字节字段)
方案二:使用clock_gettime()系统调用(推荐)
clock_gettime()是更现代的时间调用,支持纳秒级精度,syscall号为228,示例代码如下:
section .text global _start _start: ; 调用clock_gettime(CLOCK_REALTIME, &ts) mov rax, 228 ; 指定clock_gettime的系统调用号 mov rdi, 0 ; 时钟ID:CLOCK_REALTIME(对应系统实时时间) mov rsi, ts ; 第一个参数:指向timespec结构的指针 syscall ; 计算总毫秒数:秒数*1000 + 纳秒数/1000000 mov rbx, [ts] ; 读取秒数到rbx mov rcx, 1000 imul rbx, rcx ; 秒数转换为毫秒 mov rdx, [ts + 8] ; 读取纳秒数到rdx mov rcx, 1000000 xor rax, rax div rcx ; 纳秒数转换为毫秒(结果在rax) add rax, rbx ; rax中存储总毫秒数 ; 后续逻辑处理 ; 退出程序 mov rax, 60 mov rdi, 0 syscall section .data ts: times 16 db 0 ; 定义timespec结构,x64下占16字节
简化随机数获取
如果仅需要用时间的最后一位生成随机数,无需计算总毫秒数,直接取微秒/纳秒字段的最后一位即可:
- 用
gettimeofday()时,[tv + 8]是微秒数,取其最低位(and rdx, 0x0F后取最后一位) - 用
clock_gettime()时,[ts + 8]是纳秒数,同理取最后一位
另外补充:你之前的time()调用代码存在疏漏,正确的秒级时间获取应该显式设置rdi为0(表示不存储到指针,直接返回结果到rax):
mov rax, 201 xor rdi, rdi syscall
内容的提问来源于stack exchange,提问作者IsmellBeans
相关产品推荐
相关产品推荐

