Асемблерні вставки в gcc
Мова C ++ підтримує асемблерні вставки, що відображено в Стандарті мови.
Однак дана можливість глибоко специфічна індивідуальним компілятору / архітектурі, тому Стандарт небагатослівний і обмежується наступним текстом:
7.4 The asm declaration [dcl.asm]
An asm declaration has the form
asm-definition:
asm (string-literal);
The asm declaration is conditionally-supported; its meaning is implementation-defined. [Note: Typically it is used to pass information through the implementation to an assembler. -end note]
Стандарт мови C асемблерні вставки взагалі не визначає, і згадує їх тільки в списку поширених розширень:
Більшість популярних компіляторів підтримують цю можливість в тому чи іншому вигляді.
Компілятор MSVC підтримує їх для 32-бітного, але не для 64-бітного коду. Також, як можна помітити, синтаксис ассемблерних вставок MSVC відрізняється від зазначеного в Стандарті.
отримаємо файл test_asm.s (традиційним розширенням файлів на мові асемблера для GCC є .s):
Дана модель досить природним чином призводить до логіки ассемблерних вставок, яку і використовує GCC.
GCC вставляє, після можливих макропідстановок, текст ассемблерной вставки безпосередньо у вихідний файл на мові асемблера.
Приклад (про конкретний синтаксисі ассемблерних вставок див. Нижче):
Як бачимо, GCC зазначив вставку в коді явно.
Модель, яка використовується GCC має кілька важливих властивостей.
По-перше, компілятор майже не "підглядає" в зазначений програмістом код ассемблерной вставки. Він при необхідності проводить макропідстановки (див. Нижче), але в загальному передає код асемблеру майже "як є", і майже не має уявлення про те, що відбувається всередині. Зокрема, виявленням помилок займається саме асемблер (GCC передає програмісту повідомлення про помилки від асемблера).
По-друге, як наслідок, асемблерна вставка є для компілятора (і зокрема оптимізатора) єдиної непрозорою командою (чорним ящиком). Все потрібну йому інформацію про те, як цей блок взаємодіє з навколишнім світом, компілятор отримує безпосередньо від програміста, з явно зазначених операндів ассемблерной вставки (задають зв'язку ассемблерного коду зі змінними C ++ і список задіяних ресурсів (регістрів і т. Д.) І змін ( стану прапорів, пам'яті і т. д.) в ассемблерной вставці), а не з детального розгляду тексту ассемблерной вставки (якого він не виробляє). Технічно кажучи, GCC надає програмісту інтерфейс до Register Transfer Language. Відповідальність про відповідність дійсності інформації, зазначеної в операндах, цілком лежить на програмістові.
В рамках цих обмежень, компілятор вільний звертатися з ассемблерной вставкою (як і з іншими командами) так, як йому заманеться: переміщати, дублювати (напр. При підстановці inline-функцій), або взагалі викинути, якщо оптимізатор прийде до такого рішення.