【发布时间】:2017-12-07 04:56:54
【问题描述】:
我正在尝试了解 glibc 中 time() 的实现:https://code.woboq.org/userspace/glibc/sysdeps/unix/sysv/linux/x86/time.c.html#time
如果你展开宏(悬停在它们上面),你会得到:
time_t time (time_t *t)
{
unsigned long int resultvar;
long int __arg1 = (long int) (t);
register long int _a1 asm (""rdi"") = __arg1;
asm volatile ( ""syscall\n\t"" : ""=a"" (resultvar) : ""0"" (201) , ""r"" (_a1) : ""memory"", ""cc"", ""r11"", ""cx"");
(long int) resultvar;
}
汇编命令显然必须返回当前时间,但我不明白如何。检查英特尔手动系统调用,我看到它是 clobbers r11 和 cx,其他 clobbers 是 gcc 的东西,到那里,我很好。
从我读到的 (https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html) “0” 表示某些东西被用作输入和输出,虽然我不明白“(201)” 的含义(我期待一个变量名,而不是一个数字)。有什么想法吗?
我不确定 _a1 是否需要有信息,我假设它可以是 NULL,所以汇编命令的唯一真正输入是“(201)”,但我不知道系统调用如何与201 让我可以访问内部时钟。
谢谢。
附: 额外的问题:根据我在英特尔手册上阅读的内容,我的印象是唯一可用的时钟预计将在 MoBo 上,而不是 CPU 硬件的一部分。我是不是误会了?
【问题讨论】:
-
201是系统调用号。系统调用由数字标识。参见例如this table。_a1不能是NULL,因为那是您的输出指针(从t参数初始化)。 -
其实可以是
NULL,结果也是通过rax寄存器返回的(=a就是这个意思)。 -
谢谢@Jester。我发现 201 是 sys_time,private.h 中的 sys_time 调用 time(),我发现的唯一其他时间实现调用 __gettimeofday,__gettimeofday 的实现通过调用 time() 填充 timespec 结构。我陷入了一个循环......你知道实际从硬件时钟读取时间的代码在哪里吗?
-
没关系,这是 linux 内核时间():elixir.free-electrons.com/linux/v4.11.7/source/kernel/time/…
标签: c++ linux gcc assembly glibc