Инструкция по сборке x86_64 изменена на этапе компоновки GCC - PullRequest
1 голос
/ 14 февраля 2020

Я компилирую программу с использованием библиотеки sqlite3 в Linux (centos7_64). Поскольку у пользователя старый ЦП, я установил флаг -march = nehalem в G CC (-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) оптимизировать код дальше? Как ограничить инструкции для компоновщика для использования?

1 Ответ

0 голосов
/ 14 февраля 2020

Большое спасибо за комментарии. Я обнаружил, что проблема, как сказал Питер Кордес в комментарии, связана с другим набором библиотек sqlite. Я установил слишком много наборов среды компилятора G CC, и каждый компилятор имеет свой собственный sqlite в своем пути к библиотеке по умолчанию. Мой проект управлялся cmake, он запомнил все предыдущие настройки G CC ...

Шаги, чтобы обнаружить:

  1. добавить флаг -v к g cc команды.

  2. скопировать команды ld и добавить флаг "--print-map -Map = demo.map", снова запустить команду full ld.

  3. поиск имени библиотеки (sqlite здесь) в demo.map, я ясно обнаружил, что был связан другой набор библиотеки sqlite. Поймите, насколько я глуп ...

Обновление: у меня новая проблема: если библиотека .a скомпилирована с продвинутой инструкцией процессора, кажется, как понизить ее на этапе компоновки эти инструкции будут скопированы в двоичный файл без проверки флагов -march в G CC.

...