为什么 lea 将显然是随机地址移动到 rdi?

Why does lea moves apparently random address to rdi?

我有如下一段C代码:

#include <stdio.h>

int main()
{
    int i;
    for(i=0; i<10; i++)
        puts("hello, friend");

    return 0;
}

我是这样编译的:gcc firstprog.c -o firstprog

然后用gdb反汇编的时候看到:

(gdb) disassemble 
Dump of assembler code for function main:
=> 0x0000555555555149 <+0>: endbr64 
   0x000055555555514d <+4>: push   rbp
   0x000055555555514e <+5>: mov    rbp,rsp
   0x0000555555555151 <+8>: sub    rsp,0x10
   0x0000555555555155 <+12>:    mov    DWORD PTR [rbp-0x4],0x0
   0x000055555555515c <+19>:    jmp    0x55555555516e <main+37>
   0x000055555555515e <+21>:    lea    rdi,[rip+0xe9f]        # 0x555555556004
   0x0000555555555165 <+28>:    call   0x555555555050 <puts@plt>
   0x000055555555516a <+33>:    add    DWORD PTR [rbp-0x4],0x1
   0x000055555555516e <+37>:    cmp    DWORD PTR [rbp-0x4],0x9
   0x0000555555555172 <+41>:    jle    0x55555555515e <main+21>
   0x0000555555555174 <+43>:    mov    eax,0x0
   0x0000555555555179 <+48>:    leave  
   0x000055555555517a <+49>:    ret    
End of assembler dump.

所以我的问题是:rip+0xe9f 指的是什么?

如果我在同一个文件上使用 objdump,我会得到以下输出:

$ objdump -M intel -D firstprog | grep -A16 main.:
0000000000001149 <main>:
    1149:   f3 0f 1e fa             endbr64 
    114d:   55                      push   rbp
    114e:   48 89 e5                mov    rbp,rsp
    1151:   48 83 ec 10             sub    rsp,0x10
    1155:   c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
    115c:   eb 10                   jmp    116e <main+0x25>
    115e:   48 8d 3d 9f 0e 00 00    lea    rdi,[rip+0xe9f]        # 2004 <_IO_stdin_used+0x4>
    1165:   e8 e6 fe ff ff          call   1050 <puts@plt>
    116a:   83 45 fc 01             add    DWORD PTR [rbp-0x4],0x1
    116e:   83 7d fc 09             cmp    DWORD PTR [rbp-0x4],0x9
    1172:   7e ea                   jle    115e <main+0x15>
    1174:   b8 00 00 00 00          mov    eax,0x0
    1179:   c9                      leave  
    117a:   c3                      ret    
    117b:   0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]

好像跟文件描述符有关,但是当puts写入stdout时,没想到会看到IO_stdin.

So my question is: what is rip+0xe9f referring to at <main+21> ?

你可以看看:x/s 0x555555556004会给你答案

(gdb) x/s 0x555555556004
0x555555556004: "hello, friend"