Самьюэл Алекс
Шрифт:
Иногда одна или две ассемблерные команды способны заменить целую группу высокоуровневых инструкций. Например, чтобы определить позицию самого старшего значащего бита целого числа в языке С, требуется написать цикл, тогда как во многих ассемблерных языках для этой цели существует операция
9.2. Простая ассемблерная вставка
Вот как с помощью функции
Выражение в скобках состоит из секций, разделенных двоеточиями. В первой секции указана ассемблерная инструкция и ее операнды. Команда
Во второй секции задаются выходные операнды. Единственный такой операнд будет помещен в C-переменную
В третьей секции перечислены входные операнды. Переменная
Выражение
9.2.1. Преобразование функции asm в ассемблерные инструкции
Компилятор
Например, следующий фрагмент программы:
будет преобразован в такую последовательность команд x86:
Переменные
Первые две команды копируют переменную foo в регистры
9.3. Расширенный синтаксис ассемблерных вставок
В следующих подразделах будет описан синтаксис правил, по которым строятся выражения в функции
Сначала инструкция
9.3.1. Ассемблерные инструкции
Первая секция содержит ассемблерные инструкции, заключенные в кавычки. В рассматриваемом примере таких инструкций две:
Компилятор игнорирует содержимое первого раздела, разве что один уровень символов процента удаляется, т.е. вместо
Если при компиляции программы, содержащей функцию
9.3.2. Выходные операнды
Во второй секции указаны выходные операнды инструкции. Каждому операнду соответствует строка адресации и выражение языка С, записанное в скобках. В случае выходных операндов (все они должны быть левосторонними значениями) строка адресации должна начинаться со знака равенства. Компилятор проверяет, действительно ли каждый выходной операнд является левосторонним значением (т.е может стоять в левой части оператора присваивания).
Список обозначений регистров для конкретной архитектуры можно найти в исходных текстах компилятора