Использование препроцессора GCCs в качестве ассемблера

Существуют различные ассемблеры с открытым исходным кодом, такие как gas, nasm и yasm. У них разные синтаксисы pseudo-ops и macro. Для многих проектов с открытым исходным кодом ассемблер предварительно обрабатывается для замены констант и условий платформы.

Какие ограничения будут gcc при создании ассемблера, если вы можете использовать все текущие attributes и #pragmas, за исключением производительности перевода (компиляция / сборка в двоичное время)?

Я не говорю о inline-assembly.

 #define MOV(RA,RB)  (OXFEB10000UL | RA << 16 | RB)  
 #define ADD(RA,RB)  (OXFEB20000UL | RA << 16 | RB)  
 #define RET         (OXFEB7ABCDUL)  

 unsigned long add4[] __attribute(section(".text")) =
 {
    ADD(R0,R1),
    ADD(R2,R3),
    MOV(R1,R2),
    ADD(R0,R1),
    RET()
 };

Я считаю, что использование арифметики указателей может позволить моделировать . и другие labels. Возможно, это проблема XY; Я пытаюсь понять, зачем вообще столько ассемблеров. Кажется, что все может быть сделано с помощью препроцессора, а ассемблер - действительно предпочтение программистов; или есть техническое ограничение, которое мне не хватает.

Я предполагаю, что это может быть связано с тем, что вы можете сделать с ассемблером, чего нельзя сделать с помощью кода оболочки '.

Изменить: я изменил теги с C на compiler. Меня интересуют технические детали ассемблера. Это просто перевод 1-1 и выдача перемещений (как сделает компилятор) или есть что-то еще? Я не имею в виду, чтобы люди писали код на ассемблере, как я обрисовал выше. Пытаюсь понять, что делают монтажники. Я не верю, что существует книга драконов для сборщиков. Конечно, препроцессор не может создать binary сам по себе и нуждается в дополнительном оборудовании; он только переводит текст.


person artless noise    schedule 17.03.2013    source источник
comment
Я не вижу, чтобы это работало для x86. Выбрать лучшую кодировку для конкретной инструкции нетривиально, выравнивание было бы сложным, а оптимизация размера ветки была бы совершенно невозможной, насколько я могу судить. И в любом случае вы будете использовать молоток для винта.   -  person harold    schedule 18.03.2013
comment
@ Гарольд: Не могли бы вы рассказать, как это не сработает? Для x86 это было бы намного сложнее и потребовало бы byte выравнивания. Должен ли ассемблер x86 хранить в памяти большие базовые блоки для создания кодов операций?   -  person artless noise    schedule 18.03.2013
comment
@Bill - x86 имеет инструкции переменной длины, и нет отношения 1-1 между мнемоникой и кодом операции. Например, простой MOV имеет более 20 различных вариантов, например, MOV AX,1 отличается от MOV other_reg,1.   -  person Bo Persson    schedule 18.03.2013
comment
@BillPringlemeir нет, но в конечном итоге он сохраняет большие блоки в памяти, чтобы удовлетворить ограничениям выравнивания при оптимизации размера ветки. Это только требует байтового выравнивания, но действительно любит 16-выравнивание для некоторых целей ветвления.   -  person harold    schedule 18.03.2013
comment
Вы можете найти это руководство древнего ассемблера. bitsavers.org/pdf/dec/pdp1/PDP-1_Macro.pdf < / а>   -  person luser droog    schedule 22.03.2013


Ответы (2)


Какие ограничения имел бы gcc при создании ассемблера [...]?

Много. Мы не зря используем ассемблеры для сборки и препроцессоры C для предварительной обработки.

Во-первых, как вы только что показали, вы не можете использовать обычный синтаксис ассемблера, будь то в стиле Intel или AT&T. Вы должны использовать эти уродливые скобки.

Во-вторых, те __attribute__ директивы, о которых вы говорите, не имеют ничего общего с препроцессором, он их даже не распознает. Это подсказки для компилятора, а компилятор, в свою очередь, будет создавать код сборки, руководствуясь этими атрибутами (или нет).

Возможно это проблема XY

Это точно.

Я пытаюсь понять, зачем вообще столько ассемблеров.

По той же причине существуют разные типы языков программирования, компиляторов, машин и одежды: один инструмент не подходит всем. Люди разные, они делают разные вещи со своими инструментами, они находят один более простым в использовании, чем другой (лично я бы использовал ассемблер GNU, если бы он не требовал синтаксиса AT&T, который я просто не могу поддерживать), и Т. Д.

person Community    schedule 17.03.2013
comment
Я действительно не думаю, что вы (или, может быть, кто-нибудь) поняли мой вопрос. Может в этом моя проблема? - person artless noise; 21.03.2013

Я думаю, что проблема XY - неправильное описание. Вопрос больше в том, что «концепция A необходима для оценки концепции B».


Концепция А. Что такое ассемблер?

См .: Ассемблеры и загрузчик, автор Дэвид Соломон . [несколько жемчужин мудрости, несколько архаичных мелочей]

Я очень быстро обнаружил недостаток литературы в этой области. В отличие от компиляторов, по которым существует большое количество литературы, по ассемблерам и загрузчикам написано очень мало.

Ассемблер состоит из,

  • Таблица символов для облегчения связывания через некоторый формат объекта.
  • Lexer и Parser для преобразования текста в структуру данных или непосредственно в машинный код.
  • Выполняет 2 прохода для наиболее эффективного вызова ветвей и подпрограмм.
  • Таблица кодов операций.

Ассемблер - это обычно 1-1 перевод. Однако часто существует несколько вариантов ответвлений и звонков; обычно называется длинной и короткой версией. Используемый код операции будет зависеть от расстояния до места назначения; для оптимизации прямых переходов необходим двухпроходный компилятор. На это ссылается Гарольд


Концепция B: Использование препроцессора C в качестве ассемблера.

Лучшее, что мог бы эмулировать препроцессор 'C', - это однопроходный ассемблер. Так можно закодировать большой класс ЦП / инструкций; хотя макросы могут быть громоздкими. Не было бы списков или внешних ссылок, но большинство людей не пропустили бы эти функции. Кроме того, синтаксис будет странным из-за ограничений препроцессора. Было бы сложно работать с исправлением адреса, поскольку метки будут либо повторно использовать таблицу символов 'C' с помощью указателей, либо закодированный вручную #define для смещения метки. Это ограничивает этот подход чем угодно, кроме базового блока.

Подпрограммы большого ассемблера

Маловероятно, что таким образом можно будет использовать большие программы ассемблера, такие как преобразование YUV / RGB или декодирование MP3.

Мультиархитектурный код

Код с множественной архитектурой довольно распространен. Например, чип Wi-Fi ARM может иметь свой код, встроенный в ядро ​​Linux в качестве прошивки. Не исключено, что этот прием может быть здесь полезен. Однако использование отдельных компиляторов / ассемблера для разных архитектур и последующее использование objcopy для их встраивания гораздо более разумно.

Самомодифицирующийся код

Это, наверное, самое полезное. Фактически, многие инструменты, такие как компоновщики и загрузчики, имеют функции высокого уровня, которые исправляют код во время выполнения. Его также можно использовать для условного изменения подпрограммы во время выполнения; указатели на функции почти такие же быстрые и простые для понимания, не говоря уже о проблемах согласованности кеша.

См. Также: Золотой блог, автор Ян Лэнс Тейлор < / em>. [хотя он использует <templates>]

person artless noise    schedule 21.03.2013
comment
Упущен важный момент - это переезды. Ассемблеры пишут объектные файлы, в которых объекты помечаются как перемещаемые компоновщиком или загрузчиком. Концепция использования препроцессора ограничена функциями листа, относящимися к ПК (или кодом без внешних элементов). - person artless noise; 05.07.2019