двоичный код x86 - 32-битные смещения, когда 8-битные - PullRequest
2 голосов
/ 02 июля 2011

Я использую clang + LLVM 2.9 для компиляции различных рабочих нагрузок для x86 с опцией -Os. Маленький двоичный размер важен, и я должен использовать статическое связывание. Все двоичные файлы являются 32-разрядными.

Я заметил, что многие инструкции используют режимы адресации с 32-битными смещениями, когда фактически используются только 8 бит. Например:

89 84 24 d4 00 00 00     mov    %eax,0xd4(%esp)

Почему компилятор / ассемблер не выбрал компактное 8-битное смещение?

89 44 24 d4              mov    %eax,0xd4(%esp)

На самом деле эти потраченные впустую байты адресации составляют более 2% всего моего двоичного файла!

Я посмотрел на оптимизацию времени соединения LLVM и попробовал --emit-llvm, но это не затронуло и не помогло.

Существует ли некоторая оптимизация во время соединения, которая может использовать знание фактических перемещений, чтобы выбрать меньшую форму инструкции?

Спасибо за любую помощь!

1 Ответ

6 голосов
/ 02 июля 2011

В x86 смещения подписаны. Это позволяет получить доступ к данным с обеих сторон базового адреса. Поэтому диапазон 8-битного смещения составляет от -128 до 127. Ваша инструкция ссылается на данные вперед на 212 байт (значение 0xD4 в десятичном формате). Если бы он был закодирован с использованием 8-битного смещения, он был бы -44 в десятичном виде, а это не то, что вы хотели.

...