为什么在 libc nanosleep 中的寄存器 rax 上有一个紧密的轮询循环?

Why is there a tight polling loop on register rax in libc nanosleep?

libc-2 中 nanosleep 的反汇编。7.so 在 64 位 Linux 上看起来像这样:

Disassembly of section .text:

00000000000bd460 <__nanosleep>:
    cmpl   [=10=]x0,__libc_multiple_threads
    jne    10

00000000000bd469 <__nanosleep_nocancel>:
    mov    [=10=]x23,%eax
    syscal
10: cmp    [=10=]xfffffffffffff001,%rax
    jae    40
    retq
    sub    [=10=]x8,%rsp
    callq  __libc_enable_asynccancel
    mov    %rax,(%rsp)
    mov    [=10=]x23,%eax
    syscal
    mov    (%rsp),%rdi
    mov    %rax,%rdx
    callq  __libc_disable_asynccancel
    mov    %rdx,%rax
    add    [=10=]x8,%rsp
40: cmp    [=10=]xfffffffffffff001,%rax
    jae    40
    retq
    mov    _DYNAMIC+0x2e0,%rcx
    neg    %eax
    mov    %eax,%fs:(%rcx)
    or     [=10=]xffffffffffffffff,%rax
    retq

在这段汇编代码的底部附近,有这个轮询循环:

40: cmp    [=11=]xfffffffffffff001,%rax
    jae    40

在执行此循环时,rax 的值将如何变化?它不会永远循环还是根本不循环?这个循环是为了完成什么?

我怀疑这与 syscall 指令有关,因为 syscall 的 return 值被放入寄存器 rax,但我不确定这是怎么回事完全相关。代码的编写方式使它 看起来 就像 syscall 不会阻塞并且 rax 中的值会自发更改,但这似乎不正确。

我很想知道这里发生了什么。

我没有看到这些自旋循环。

这是我从 objdump -d /lib/x86_64-linux-gnu/libc.so.6 获得的内容,您显示的循环用 ** 突出显示,它们跳转到的地址用 ->

00000000000c0f10 <__nanosleep>:
   c0f10:       83 3d 5d 31 30 00 00    cmpl   [=10=]x0,0x30315d(%rip)        # 3c4074 <argp_program_version_hook+0x1cc>
   c0f17:       75 10                   jne    c0f29 <__nanosleep+0x19>
   c0f19:       b8 23 00 00 00          mov    [=10=]x23,%eax
   c0f1e:       0f 05                   syscall 
   c0f20:       48 3d 01 f0 ff ff       cmp    [=10=]xfffffffffffff001,%rax
** c0f26:       73 31                   jae    c0f59 <__nanosleep+0x49>
   c0f28:       c3                      retq   
   c0f29:       48 83 ec 08             sub    [=10=]x8,%rsp
   c0f2d:       e8 3e 72 04 00          callq  108170 <pthread_setcanceltype+0x80>
   c0f32:       48 89 04 24             mov    %rax,(%rsp)
   c0f36:       b8 23 00 00 00          mov    [=10=]x23,%eax
   c0f3b:       0f 05                   syscall 
   c0f3d:       48 8b 3c 24             mov    (%rsp),%rdi
   c0f41:       48 89 c2                mov    %rax,%rdx
   c0f44:       e8 87 72 04 00          callq  1081d0 <pthread_setcanceltype+0xe0>
   c0f49:       48 89 d0                mov    %rdx,%rax
   c0f4c:       48 83 c4 08             add    [=10=]x8,%rsp
   c0f50:       48 3d 01 f0 ff ff       cmp    [=10=]xfffffffffffff001,%rax
** c0f56:       73 01                   jae    c0f59 <__nanosleep+0x49>
   c0f58:       c3                      retq   
-> c0f59:       48 8b 0d 08 cf 2f 00    mov    0x2fcf08(%rip),%rcx        # 3bde68 <_IO_file_jumps+0x7c8>
   c0f60:       f7 d8                   neg    %eax
   c0f62:       64 89 01                mov    %eax,%fs:(%rcx)
   c0f65:       48 83 c8 ff             or     [=10=]xffffffffffffffff,%rax
   c0f69:       c3                      retq   
   c0f6a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

其余代码类似。可能是反汇编的问题?