[x86_64汇编指令在GCC的链接阶段已更改

问题描述 投票:1回答:1

我正在使用Linux(centos7_64)中的sqlite3库编译程序。由于用户的CPU较旧,我在GCC中设置了-march = nehalem标志(-march = nehalem -mtune = nehalem -m64 -O3)。我发现我不能将汇编指令限制为nehalem,最终的二进制文件中仍然存在一些BMI操作。

按照输出步骤,发现问题来自链接器(ld)。

libsqlite3.a:

   632c2:       66 41 83 4f 26 01       orw    $0x1,0x26(%r15)
   632c8:       0f b6 84 24 80 00 00    movzbl 0x80(%rsp),%eax
   632cf:       00
   632d0:       c1 e0 08                shl    $0x8,%eax
   632d3:       89 c2                   mov    %eax,%edx
   632d5:       0f b6 84 24 81 00 00    movzbl 0x81(%rsp),%eax
   632dc:       00
   632dd:       c1 e0 10                shl    $0x10,%eax
   632e0:       09 d0                   or     %edx,%eax
   632e2:       8d 90 00 fe ff ff       lea    -0x200(%rax),%edx
   632e8:       41 89 47 30             mov    %eax,0x30(%r15)
   632ec:       81 fa 00 fe 00 00       cmp    $0xfe00,%edx
   632f2:       0f 87 d1 05 00 00       ja     638c9 <sqlite3BtreeOpen+0xb29>
   632f8:       8d 50 ff                lea    -0x1(%rax),%edx
   632fb:       85 c2                   test   %eax,%edx
   632fd:       0f 85 c6 05 00 00       jne    638c9 <sqlite3BtreeOpen+0xb29>

但是,在最后的二进制文件中:

  9499f2:       66 41 83 4f 26 01       orw    $0x1,0x26(%r15)
  9499f8:       0f b6 84 24 80 00 00    movzbl 0x80(%rsp),%eax
  9499ff:       00
  949a00:       0f b6 94 24 81 00 00    movzbl 0x81(%rsp),%edx
  949a07:       00
  949a08:       c1 e0 08                shl    $0x8,%eax
  949a0b:       89 c1                   mov    %eax,%ecx
  949a0d:       89 d0                   mov    %edx,%eax
  949a0f:       c1 e0 10                shl    $0x10,%eax
  949a12:       09 c8                   or     %ecx,%eax
  949a14:       8d 90 00 fe ff ff       lea    -0x200(%rax),%edx
  949a1a:       41 89 47 30             mov    %eax,0x30(%r15)
  949a1e:       81 fa 00 fe 00 00       cmp    $0xfe00,%edx
  949a24:       0f 87 cf 05 00 00       ja     949ff9 <sqlite3BtreeOpen+0xb09>
  949a2a:       c4 e2 78 f3 c8          blsr   %eax,%eax
  949a2f:       85 c0                   test   %eax,%eax
  949a31:       0f 85 c2 05 00 00       jne    949ff9 <sqlite3BtreeOpen+0xb09>

注意最后几行,链接器将lea更改为blsr,这是意外的。

因此,为什么会这样。链接程序(ld)会进一步优化代码吗?如何限制链接器使用的指令?

gcc assembly optimization linker ld
1个回答
0
投票

非常感谢您的评论。正如彼得·科德斯(Peter Cordes)在评论中所说,我已经找到问题了,我链接到另一套sqlite库。我安装了太多套GCC编译器环境,并且每个编译器在其默认库路径中都有自己的sqlite。我的项目由cmake管理,它记得以前所有的GCC设置...

发现步骤:

  1. 向gcc命令添加-v标志。

  2. 复制ld命令,并添加标志“ --print-map -Map = demo.map”,再次运行完整的ld命令。

  3. 在demo.map中搜索库名称(在此处为sqlite),我清楚地发现另一组sqlite库已链接。意识到我是多么愚蠢...

更新:我有一个新问题:如果library.a是使用高级CPU指令编译的,如何在链接阶段降级,看来那些指令将被复制为二进制而不检查GCC中的-march标志。

© www.soinside.com 2019 - 2024. All rights reserved.