为什么值通过无用的副本传递?

逆向工程 linux x64
2021-07-02 09:00:39

所以,假设我有以下代码,它给出了我认为是不必要的值副本的三个示例。

mov    QWORD PTR [rbp-0x18],rdi
mov    rdx,QWORD PTR [rbp-0x18]
lea    rax,[rbp-0x10]
mov    rsi,rdx
mov    rdi,rax
call   4003e0 <strcpy@plt>

为什么将 中的值rdi复制到内存中rbp-0x18,然后再复制回rdx然后将其复制到rsi(2 个额外副本)。

最后,为什么lea + movfor rbp-0x10to rax, then to rdi是否有任何原因未生成以下代码?

mov    rsi,rdi
lea    rdi,[rbp-0x10]
call   4003e0 <strcpy@plt>

(我的猜测是这只是编译器中代码生成的一个工件,但我确保没有我遗漏的 x86-64 的一些规则。)

1个回答

没有人工制品,当然编译器,我的意思是GCC,如果被告知,可以生成更好更快的代码。您生成的代码的第一个版本未优化。为什么 ?要么是因为指定了-O0标志(0 级优化 ==> 无优化),要么是因为未指定优化标志并且默认情况下GCC关闭优化。

您会在下面找到相同代码的两个版本。带有-O0标志的版本 1 带有-O2标志的版本 2

  • 版本 1:

     55                      push   rbp
     48 89 e5                mov    rbp,rsp
     48 81 ec 10 04 00 00    sub    rsp,0x410
     89 bd fc fb ff ff       mov    DWORD PTR [rbp-0x404],edi
     48 89 b5 f0 fb ff ff    mov    QWORD PTR [rbp-0x410],rsi
     48 8b 85 f0 fb ff ff    mov    rax,QWORD PTR [rbp-0x410]
     48 83 c0 08             add    rax,0x8
     48 8b 10                mov    rdx,QWORD PTR [rax]
     48 8d 85 00 fc ff ff    lea    rax,[rbp-0x400]
     48 89 d6                mov    rsi,rdx
     48 89 c7                mov    rdi,rax
     e8 40 fe ff ff          call   400400 <strcpy@plt>
     48 8d 85 00 fc ff ff    lea    rax,[rbp-0x400]
     48 89 c7                mov    rdi,rax
     e8 41 fe ff ff          call   400410 <puts@plt>
     b8 00 00 00 00          mov    eax,0x0
     c9                      leave
     c3                      ret
     66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
     00 00 00  
    
  • 版本 2:

     48 81 ec 08 04 00 00    sub    rsp,0x408
     48 8b 76 08             mov    rsi,QWORD PTR [rsi+0x8]
     48 89 e7                mov    rdi,rsp
     e8 ad ff ff ff          call   400400 <strcpy@plt>
     48 89 e7                mov    rdi,rsp
     e8 b5 ff ff ff          call   400410 <puts@plt>
     31 c0                   xor    eax,eax
     48 81 c4 08 04 00 00    add    rsp,0x408
     c3                      ret
     0f 1f 00                nop    DWORD PTR [rax]
    

如果您对所执行的优化感兴趣,GCC则应阅读链接以及链接您还可以查看GCC峰会出版物