Как я сказал вчера, ia64 - это очень требовательная архитектура. Сегодня я буду обсуждать ещё один способ наврать компилятору так, что ему потом придётся вас за это стукнуть.
В ia64 нет режима абсолютной адресации. Вместо этого вы обращаетесь к своим глобальным данным через регистр r1, который имеет псевдоним "gp" (global pointer - глобальный указатель). Этот регистр всегда указывает на ваши глобальные переменные. Например, если у вас есть три глобальные переменные, то одна из них может лежать по адресу [gp+0], вторая по [gp+8], а третья - [gp+16].
(Мне кажется, что соглашение вызова на Win32 MIPS также использовало такую технику).
На ia64 есть также ограничение инструкции "addl": вы можете прибавлять константы только размером меньше 22-х битов, что равно 4 Мб. Поэтому вы можете иметь только 4 Мб глобальных переменных.
Ну, оказывается, что некоторые люди хотят иметь больше, чем 4 Мб глобальных переменных. К счастью, у этих людей нет одного миллиона переменных размером с DWORD. Вместо этого у них есть несколько очень больших глобальных массивов.
Компилятор ia64 решает эту проблему разделением глобальных переменных по двум категориям: "маленькие" и "большие" (граница между категориями может устанавливаться флагом компилятора. Я думаю, что значение по-умолчанию рассматривало любые данные размером больше 8-ми байт как большие).
Код для доступа к "маленьким" данным получается таким:
addl r30 = -205584, gp;; // r30 -> глобальную переменную(Регистр gp на самом деле указывает в середину ваших глобальных данных, так что можно использовать и положительные и отрицательные смещения. В нашем случае переменная живёт по отрицательному смещению от gp).
ld4 r30 = [r30] // загрузить значение DWORD из глоабльной переменной
Сравним это с двухшаговым доступом к "большим" переменным. Сначала сама переменная должна быть найдена в отдельной секции файла. Затем указатель на переменную копируется в область для "маленьких" глобальных переменных. В результате доступ к "большим" глобальным переменным добавляет ещё один слой адресации:
addl r30 = -205584, gp;; // r30 -> указатель на глобальную переменнуюЕсли вы не станете указывать размер объекта, как, например
ld8 r30 = [r30];; // r30 -> глобальную переменную
ld4 r30 = [r30] // загружает значение DWORD из глобальной переменной
extern BYTE b[];то тогда компилятор решит перестраховаться и предполагает, что переменная - "большая". Если окажется, что переменная на самом деле маленькая, то дополнительный указатель всё равно будет доступен, и коду программы придётся делать три шага для доступа к переменной, которая могла бы быть доступна в две инструкции. Код получится чуть менее эффективным, но по крайней мере он будет работать.
С другой стороны, если вы неверно объявите объект как маленький, когда он в действительности большой, то тогда у вас будут неприятности. Например, если вы напишете
extern BYTE b;в одном файле и
extern BYTE b[256];в другом, то тогда файлы, которые включают в себя первое объявление будут думать, что объект - "маленький" и генерировать две инструкции для доступа, а файлы, которые включают в себя первое объявление, будут считать этот объект большим. И если в итоге объект окажется всё же большим, то код, который использовал первое объявление, будет весьма впечатляюще вылетать.
Поэтому не делайте так никогда. Когда вы объявляете переменную - убедитесь, что вы объявляете её аккуратно. Иначе ia64 поймает вас на лжи и стукнет по лбу.
Комментариев нет:
Отправить комментарий
Можно использовать некоторые HTML-теги, например:
<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>
Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.
Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.
Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.
Примечание. Отправлять комментарии могут только участники этого блога.