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

时间:2015-11-30 18:35:39

标签: linux x86 system-calls

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

Disassembly of section .text:

00000000000bd460 <__nanosleep>:
    cmpl   $0x0,__libc_multiple_threads
    jne    10

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

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

40: cmp    $0xfffffffffffff001,%rax
    jae    40

在执行此循环时,rax的值如何变化?它不会永远循环或根本不循环?这个循环意味着什么?

我怀疑这与syscall指令有关,因为syscall的返回值已放入注册rax,但我不确定这是如何完全相关的。编写代码的方式使得看起来就像syscall没有阻止而rax中的值会自发地发生变化,但这看起来并不正确。< / p>

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

1 个答案:

答案 0 :(得分:2)

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

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

00000000000c0f10 <__nanosleep>:
   c0f10:       83 3d 5d 31 30 00 00    cmpl   $0x0,0x30315d(%rip)        # 3c4074 <argp_program_version_hook+0x1cc>
   c0f17:       75 10                   jne    c0f29 <__nanosleep+0x19>
   c0f19:       b8 23 00 00 00          mov    $0x23,%eax
   c0f1e:       0f 05                   syscall 
   c0f20:       48 3d 01 f0 ff ff       cmp    $0xfffffffffffff001,%rax
** c0f26:       73 31                   jae    c0f59 <__nanosleep+0x49>
   c0f28:       c3                      retq   
   c0f29:       48 83 ec 08             sub    $0x8,%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    $0x23,%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    $0x8,%rsp
   c0f50:       48 3d 01 f0 ff ff       cmp    $0xfffffffffffff001,%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     $0xffffffffffffffff,%rax
   c0f69:       c3                      retq   
   c0f6a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

其余代码类似。也许这是反汇编的问题?