Ассемблерные вставки в c - IT Справочник
Llscompany.ru

IT Справочник
6 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Ассемблерные вставки в c

Ассемблерные вставки в GCC

Статья является попыткой систематизировать brain-dump известной автору информации по ассемблерным вставкам в GCC.

Автор не считает себя авторитетом в данном вопросе, и статья может содержать неточности. Замечания, дополнения и исправления приветствуются.
Вопрос, зачем вообще использовать встроенный ассемблер, выходит за рамки данной статьи.
Предполагается, что читатель знаком с каким-либо ассемблером: учебником по языку per se статья не является.
За исключением случаев, когда явно оговорено обратное, информация в равном мере применима к C и к C++.
Все примеры в статье — для архитектуры x86 (и x86_64), но сама поддержка ассемблерных вставок в GCC не ограничивается этой архитектурой, и большинство информации применимо и для других.
Все отрывки кода, если явно не оговорено обратное и не указано авторство, находятся в общем доступе (public domain).

Общие сведения

Язык C++ поддерживает ассемблерные вставки, что отражено в Стандарте языка.
Однако данная возможность глубоко специфична индивидуальным компилятору/архитектуре, поэтому Стандарт немногословен и ограничивается следующим текстом:

Стандарт языка C ассемблерные вставки вообще не определяет, и упоминает их только в списке распространённых расширений:

Под GCC здесь и далее (если не оговорено обратное) подразумевается компилятор, поддерживающий набор расширений GCC. Это, с некоторых пор, официальное определение макро __GNUC__ (см. https://gcc.gnu.org/… d-Macros.html , https://sourceforge.… ki/Compilers/ и далее по ссылкам). В частности компиляторы clang и icc определяют __GNUC__; оба этих компилятора (так же как и сам GCC) поддерживают ассемблерные вставки в синтаксисе GCC.

Концептуальная модель

Типично, компилятор превращает исходный код в объектный код, который потом сборщиком (линкером) собирается в исполняемый файл.
GCC использует несколько необычное решение: компиляторы C и C++ во многом близки к языковым трансляторам ( https://en.wikipedia… urce_compiler ), и результатом их работы является файл на языке ассемблера (именно на текстовом (мнемоническом) ассемблере, а не в машинном коде), который далее преобразуется в объектный код штатным ассемблером (утилита as ; ассемблер, входящий в состав GNU, обычно в документации называют GNU Assembler, сокращённо gas, несмотря на то, что сама утилита называется именно as).
Обычно при вызове компилятор GCC сам производит соответствующие действия (вызов as и т. д.) «под капотом», и для создания объектного файла никаких дополнительных указаний не требуется.
Можно указать компилятору опцию -S (большая буква S; у малой s другое значение), для того чтобы произвести только перевод программы на ассемблер.
Рассмотрим пример. Создадим файл test_asm.cpp со следующим кодом:

При желании, можно получить несколько более подробный код (с дополнительными комментариями), воспользовавшись опцией -fverbose-asm.
Построчный листинг (в файле test_asm.lst) C++ и ассемблера можно получить, воспользовавшись командой (подробнее см. http://www.delorie.c… /faq8_20.html ):

Данная модель достаточно естественным образом приводит к логике ассемблерных вставок, которую и использует GCC.
GCC вставляет, после возможных макроподстановок, текст ассемблерной вставки непосредственно в выходной файл на языке ассемблера.
Пример (о конкретном синтаксисе ассемблерных вставок см. ниже):

Модель, используемая GCC имеет несколько важных свойств.

Во-первых, компилятор почти не «подглядывает» в указанный программистом код ассемблерной вставки. Он при необходимости проводит макроподстановки (см. ниже), но в общем передаёт код ассемблеру почти «как есть», и почти не имеет представления о происходящем внутри. В частности, обнаружением ошибок занимается именно ассемблер (GCC передаёт программисту сообщения об ошибках от ассемблера).

Во-вторых, как следствие, ассемблерная вставка является для компилятора (и в частности оптимизатора) единой непрозрачной командой (чёрным ящиком). Всё нужную ему информацию о том, как этот блок взаимодействует с окружающим миром, компилятор получает напрямую от программиста, из явно указанных операндов ассемблерной вставки (задающих связи ассемблерного кода с переменными C++ и список задействованных ресурсов (регистров и т. д.) и изменений (состояния флагов, памяти и т. д.) в ассемблерной вставке), а не из детального рассмотрения текста ассемблерной вставки (которого он не производит). Технически говоря, GCC предоставляет программисту интерфейс к Register Transfer Language. Ответственность о соответствии действительности информации, указанной в операндах, целиком лежит на программисте.
В рамках этих ограничений, компилятор волен обращаться с ассемблерной вставкой (как и с другими командами) так, как ему вздумается: перемещать, дублировать (напр. при подстановке inline-функций), или вообще выбросить, если оптимизатор придёт к такому решению.

Связь ассемблера с языками высокого уровня

Существуют следующие формы комбинирования программ на языках высокого уровня с ассемблером:

  • Использование ассемблерных вставок (встроенный ассемблер, режим inline ). Ассемблерные коды в виде команд ассемблера вставляются в текст программы на языке высокого уровня. Компилятор языка распознает их как команды ассемблера и без изменений включает в формируемый им объектный код. Эта форма удобна, если надо вставить небольшой фрагмент.
  • Использование внешних процедур и функций. Это более универсальная форма комбинирования. У нее есть ряд преимуществ:
    — написание и отладку программ можно производить независимо;
    — написанные подпрограммы можно использовать в других проектах;
    — облегчаются модификация и сопровождение подпрограмм.
Встроенный ассемблер

При написании ассемблерных вставок используется следующий синтаксис:

КодОперации задает команду ассемблера,
операнды – это операнды команды.
В конце записывается ;, как и в любой команде языка Си.
Комментарии записываются в той форме, которая принята для языка Си.
Если требуется в текст программы на языке Си вставить несколько идущих подряд команд ассемблера, то их объединяют в блок:

Внутри блока текст программы пишется с использованием синтаксиса ассемблера, при необходимости можно использовать метки и идентификаторы. Комментарии в этом случае можно записывать как после ;, так и после //.

Пример Даны целые числа а и b. Вычислить выражение a+5b.
Для вывода приглашений Введите a: и Введите b: используем функцию CharToOem(_T(«Введите «),s) ,
где s – указатель на строку, которая перекодирует русскоязычные сообщения.

Для компоновки и запуска программы создаем проект как описано в разделе Создание консольных приложений .
Проект будет содержать 1 файл исходного кода с расширением cpp.
Результат выполнения программы:

Использование внешних процедур

Для связи посредством внешних процедур создается многофайловая программа. При этом в общем случае возможны два варианта вызова:

  • программа на языке высокого уровня вызывает процедуру на языке ассемблера;
  • программа на языке ассемблера вызывает процедуру на языке высокого уровня.

Рассмотрим более подробно первый вариант.
В таблице ниже представлены основные соглашения по передаче параметров в процедуру.
В программах, написанных на языке ассемблера, используется соглашение передачи параметров stdcall . Однако по сути получение и передача параметров в языке ассемблера производится явно, без помощи транслятора.
При связи процедуры, написанной на языке ассемблера, с языком высокого уровня, необходимо учитывать соглашение по передаче параметров.

Конвенция Pascal заключается в том, что параметры из программы на языке высокого уровня передаются в стеке и возвращаются в регистре АХ/ЕАХ, — это способ, принятый в языке PASCAL (а также в BASIC, FORTRAN, ADA, OBERON, MODULA2), — просто поместить параметры в стек в естественном порядке. В этом случае запись

Читать еще:  Снять защиту листа пароль

Процедура some_proc , во-первых, должна очистить стек по окончании работы (например, командой ret 16 ) и, во-вторых, параметры, переданные ей, находятся в стеке в обратном порядке:

Этот код в точности соответствует полной форме директивы proc .
Однако можно использовать упрощенную форму, которую поддерживают все современные ассемблеры:

Главный недостаток этого подхода — сложность создания функции с изменяемым числом параметров, аналогичных функции языка С printf . Чтобы определить число параметров, переданных printf , процедура должна сначала прочитать первый параметр, но она не знает его расположения в стеке. Эту проблему решает подход, используемый в С, где параметры передаются в обратном порядке.

Конвенция С используется, в первую очередь, в языках С и C++, а также в PROLOG и других. Параметры помещаются в стек в обратном порядке, и, в противоположность PASCAL-конвенции, удаление параметров из стека выполняет вызывающая процедура.
Запись some_proc(a,b,c,d)
будет выглядеть как

Вызванная таким образом процедура может инициализироваться так:

Трансляторы ассемблера поддерживают и такой формат вызова при помощи полной формы директивы proc с указанием языка С:

Регистр EВР используется для хранения параметров, и его нельзя изменять программно при использовании упрощенной формы директивы proc .
Преимущество по сравнению с PASCAL-конвенцией заключается в том, что освобождение стека от параметров в конвенции С возлагается на вызывающую процедуру, что позволяет лучше оптимизировать код программы. Например, если необходимо вызвать несколько функций, принимающих одни и те же параметры подряд, можно не заполнять стек каждый раз заново, и это — одна из причин, по которой компиляторы с языка С создают более компактный и быстрый код по сравнению с компиляторами с других языков.

Смешанные конвенции
Существует конвенция передачи параметров STDCALL , отличающаяся и от C , и от PASCAL -конвенций, которая применяется для всех системных функций Win32 API. Здесь параметры помещаются в стек в обратном порядке, как в С, но процедуры должны очищать стек сами, как в PASCAL.
Еще одно отличие от С-конвенции – это быстрое или регистровое соглашение FASTCALL . В этом случае параметры в функции также передаются по возможности через регистры. Например, при вызове функции с шестью параметрами

первые три параметра передаются соответственно в ЕАХ , EDX , ЕСХ , а только начиная с четвертого, параметры помещают в стек в обычном обратном порядке:

В случае если стек был задействован, освобождение его возлагается на вызываемую процедуру.
В случае быстрого вызова транслятор Си добавляет к имени значок @ спереди, что искажает имена при обращении к ним в ассемблерном модуле.

Возврат результата из процедуры

Чтобы возвратить результат в программу на С из процедуры на ассемблере, перед возвратом управления в вызываемой процедуре (на языке ассемблера) необходимо поместить результат в соответствующий регистр:

Пример Умножить на 2 первый элемент массива (нумерация элементов ведется с 0).




Добавляем в дерево проекта два файла исходного кода:

  • вызывающая процедура на языке C++;
  • вызываемая процедура на языке ассемблера.

Для этого выбираем по правой кнопке мыши Файлы исходного кода -> Добавить -> Создать элемент и задаем имя файла программы на языке С++.

Второй добавляемый файл исходного кода будет иметь расширение .asm, которое необходимо указать явно.

Важно, чтобы файлы программ на C++ и ассемблере имели не только разные расширения, но и имена. В случае совпадающих имен файлов возникнет ошибка при компоновке проекта, поскольку оба файла будут иметь одно и то же имя объектного файла.

Набираем код программы для файлов вызывающей и вызываемой процедур соответственно на C++ и ассемблере.


Подключаем инструмент Microsoft Macro Assembler. По правой кнопке мыши для проекта выбираем Настройки построения.

В появившемся окне ставим галочку в строке masm.


Выбираем меню Свойства для файла на языке ассемблера по правой кнопке мыши и выбираем для этого файла инструмент Microsoft Macro Assembler.


Выполняем построение проекта, выбрав меню Отладка -> Построить решение.


Результат построения отображается в нижней части окна проекта.


Запуск проекта на выполнение осуществляется через меню Отладка -> Начать отладку.

Результат выполнения программы

Перед вызовом процедуры всегда нужно сохранять содержимое регистров ebp , esp , а перед выходом из процедуры – восстанавливать содержимое этих регистров. Это делается компилятором языка Си. Остальные регистры нужно сохранять при необходимости (если содержимое регистра подвергается изменению в вызванной процедуре, а далее может использоваться в вызывающей программе) Это может быть сделано с помощью команды pusha .
Передача аргументов в процедуру на ассемблере из программы на Си осуществляется через стек. При этом вызывающая программа записывает передаваемые параметры в стек, а вызываемая программа извлекает их из стека.

Работа с аргументами вещественного типа

При вызове функции с аргументами вещественного типа конфигурация проекта ничем не отличается от описанной выше. Для передачи аргументов необходимо указать их тип.

Ассемблерные вставки в программы на С++

Господа, объясните, пожалуйста, как делать ассемблерные вставки в C++-программах (gcc 4.8.1). Желательно с примером, там дальше разберусь как-нибудь.

Хеллоуворлд на С из ассемблерных вставок там я хелловорлд на ассемблерных вставках делал, в качестве примера вполне подойдет

там я хелловорлд на ассемблерных вставках делал, в качестве примера вполне подойдет

А почему там такой синтаксис страшный, что каждую строку с ассемблером в кавычки пихать?

А ещё syscall — почему не int 80h?

Кстати, а что лучше, gas или fasm по-твоему?

Тут, вероятно, больше вопрос синтаксиса — AT&T vs Intel. Я, например, не перевариваю AT&T. И да, у fasm на порядок круче язык макросов.

На 64-битной системе используется только syscall, ибо быстрее. На 32-битной тоже имеет смысл его использовать для скорости.

Какой смысл ассемблерных вставок, интересно мне. Напиши отдельно функцию на ассемблере и дёргай её там где тебе нужна вставка. По-моему пролог не сложно и ручками написать.

А почему там такой синтаксис страшный, что каждую строку с ассемблером в кавычки пихать?

Потому что так устроены ассемблерные вставки в GCC

Кстати, а что лучше, gas или fasm по-твоему?

GAS поддерживает больше, им можно под ARM, MIPS и под кучу других архитектур программировать, FASM же умеет только в x86 и x86-64, насколько я знаю. С этой точки зрения, GAS предпочтительней. Насчет макросов, я FASM не использовал и насчет его макроязыка ничего сказать не могу. В любом случае, встраивать куски, написанные на FASM непосредственно в код C/C++ для GCC не выйдет, там только GAS можно. Но можно написать библиотеку на FASM и линковать ее

Читать еще:  Возведение в степень в delphi 7

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

Напиши отдельно функцию на ассемблере и дёргай её там где тебе нужна вставка

Это тогда будет уже вызов функции, непосредственного встраивания в код так сделать не получится.

Какой смысл ассемблерных вставок, интересно мне.

Потому что можно сделать static inline. Потому что можно использовать переменные на стеке без плясок с бубном. Потому что компилятор может оптимизировать использование регистров.

Прикольно. тогда тем более.

что лучше, gas или fasm

Под x86 лучше fasm. Но gas дефолтнее и линуксовее. Еще yasm ничего.

А ещё syscall — почему не int 80h?

потому что syscall быстрее, и это стандартный способ использования системных вызовов. Посмотри на выхлоп gcc.

Тут, вероятно, больше вопрос синтаксиса — AT&T vs Intel. Я, например, не перевариваю AT&T. И да, у fasm на порядок круче язык макросов.

gas умеет сишные макросы.

На 64-битной системе используется только syscall, ибо быстрее. На 32-битной тоже имеет смысл его использовать для скорости.

Intelовские процессоры не поддерживают инструкцию syscall в 32-битном режиме.

Какой смысл ассемблерных вставок, интересно мне. Напиши отдельно функцию на ассемблере и дёргай её там где тебе нужна вставка.

И огреби проблем с раскруткой стека.

Intelовские процессоры не поддерживают инструкцию syscall в 32-битном режиме.

схренабы, если syscall появился задолго до amd64?

Intelовские процессоры не поддерживают инструкцию syscall в 32-битном режиме.

Так и быть, у меня сегодня толерантное настроение. Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 2, SYSCALL—Fast System Call:

ну так SCE в EFER выставь-то.

См. syscall_init() в ядре, она инициализирует MSRы для поддержки syscall. Всё это делается только в 64-битном ядре (под CONFIG_X86_64).

ну так SCE в EFER выставь-то

Об том и речь. Если выставить IA32_EFER.LMA, то это уже не 32-битный режим процессора.

Не надо делать вставки. Надо делать отдельные файлы *.S

gas умеет сишные макросы.

*.S принято прогонять через CPP. gcc делает это.

Если выставить IA32_EFER.LMA, то это уже не 32-битный режим процессора.

во время выполнения 32-битных бинарников LMA==0, так что это 32-битный режим.

P.S. EFER и syscall были запилены вместе с K6, и для использования syscall нужно было тот самый бит SCE в EFER выставить. Это можно делать и в 32-битном режиме.

Под x86 лучше fasm. Но gas дефолтнее и линуксовее. Еще yasm ничего.

Есть fasm же и для ARM

А Yasm — это какая-то мутная попытка переписать NASM вроде. лучше бы их слили.

А что такое syscall, новая инструкция? А в каком процессоре она появилась? Я думал, это макрос, подставляющий int 80h. Какой у него опкод, не CD80?

SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) SYSCALL also saves RFLAGS into R11 and then masks RFLAGS using the IA32_FMASK MSR (MSR address C0000084H); specifically, the processor clears in RFLAGS every bit corresponding to a bit that is set in the IA32_FMASK MSR.

SYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the IA32_STAR MSR. However, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the respon- sibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values corre- spond to the fixed values loaded into the descriptor caches; the SYSCALL instruction does not ensure this correspondence.

The SYSCALL instruction does not save the stack pointer (RSP). If the OS system-call handler will change the stack pointer, it is the responsibility of software to save the previous value of the stack pointer. This might be done prior to executing SYSCALL, with software restoring the stack pointer with the instruction following SYSCALL (which will be executed after SYSRET). Alternatively, the OS system-call handler may save the stack pointer and restore it before executing SYSRET.

во время выполнения 32-битных бинарников LMA==0, так что это 32-битный режим

EFER и syscall были запилены вместе с K6, и для использования syscall нужно было тот самый бит SCE в EFER выставить. Это можно делать и в 32-битном режиме.

Это да. Но речь была про Intel.

с разморозкой, блин. Это отдельная инструкция, появилась в 1997 году.

Это да. Но речь была про Intel.

ты хочешь сказать, что интел криво реализует чужие спеки больше одного раза? (/me вспомнил дыру sysret). В любом случае похер, и никто не мешает юзать sysenter вместо syscall, из юзерспейса разницы нет, разве что регистры самому надо сохранить.

Ассемблерные вставки в c

Системное программирование

Главная страница

Младший специалист

Бакалавр

О сайте

Дополнительные материалы

Пройти тест

Лекция 4. Основы языка Ассемблер. Синтаксис языка Ассемблер. Ассемблерные вставки в языке C/C++.

4.1. Назначение языков ассемблера.

Ассемблер (от англ. assemble — собирать) — компилятор с языка ассемблера в команды машинного языка.

Сейчас разработка программ на ассемблере применяется в основном в программировании небольших микропроцессорных систем (микроконтроллеров), как правило, встраиваемых в какое-либо оборудование. Очень редко возникает потребность использования ассемблера в разрабатываемых программах в тех случаях, когда необходимо, например, получить наивысшую скорость выполнения определенного участка программы, выполнить операцию, которую невозможно реализовать средствами языков высокого уровня, либо уместить программу в память ограниченного объема (типичное требование для загрузчиков операционной системы).

Под каждую архитектуру процессора и под каждую ОС или семейство ОС существует свой ассемблер. Есть также так называемые кроссассемблеры, позволяющие на машинах с одной архитектурой (или в среде одной ОС) ассемблировать программы для другой целевой архитектуры или другой ОС и получать исполняемый код в формате, пригодном к исполнению на целевой архитектуре или в среде целевой ОС.

Язык ассемблера — тип языка программирования низкого уровня. Команды языка ассемблера один в один соответствуют командам процессора и представляют собой удобную символьную форму записи (мнемокод) команд и аргументов. Язык ассемблера обеспечивает связывание частей программы и данных через метки, выполняемое при ассемблировании (для каждой метки высчитывается адрес, после чего каждое вхождение метки заменяется на этот адрес).

Читать еще:  Delphi тип single

Каждая модель процессора имеет свой набор команд и соответствующий ему язык (или диалект) ассемблера.

Обычно программы или участки кода пишутся на языке ассемблера в случаях, когда разработчику критически важно оптимизировать такие параметры, как быстродействие (например, при создании драйверов) и размер кода (загрузочные секторы, программное обеспечение для микроконтроллеров и процессоров с ограниченными ресурсами, вирусы, навесные защиты).

Связывание ассемблерного кода с другими языками. Большинство современных компиляторов позволяют комбинировать в одной программе код, написанный на разных языках программирования. Это дает возможность быстро писать сложные программы, используя высокоуровневый язык, не теряя быстродействия в критических ко времени задачах, применяя для них части, написанные на языке ассемблера. Комбинирование достигается несколькими приемами:

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

2. Модульная компиляция. Большинство современных компиляторов работают в два этапа. На первом этапе каждый файл программы компилируется в объектный модуль. А на втором объектные модули линкуются (связываются) в готовую программу. Прелесть модульной компиляции состоит в том, что каждый объектный модуль будущей программы может быть полноценно написан на своем языке программирования и скомпилирован своим компилятором (ассемблером).

Достоинства языков ассемблера.

1. Максимально оптимальное использование средств процессора, использование меньшего количества команд и обращений в память и, как следствие, большая скорость и меньший размер программы.

2. Использование расширенных наборов инструкций процессора (MMX, SSE, SSE2, SSE3).

3. Доступ к портам ввода-вывода и особым регистрам процессора (в большинстве ОС эта возможность доступна только на уровне модулей ядра и драйверов)

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

5. Максимальная адаптация для нужной платформы.

Однако следует отметить, что последние технологии безопасности, внедряемые в операционные системы и компиляторы, не позволяют делать самомодифицирующего кода, так как исключают одновременную возможность исполнения программы и запись в одном и том же участке памяти (технология W^X).

Технология W^X используется в OpenBSD , в других BSD-системах, в Linux. В Microsoft Windows (начиная с Windows XP SP2) применяется схожая технология DEP.

Недостатки языков ассемблера.

1. Большие объемы кода, большое число дополнительных мелких задач, меньшее количество доступных для использования библиотек по сравнению с языками высокого уровня.

2. Трудоемкость чтения и поиска ошибок (хотя здесь многое зависит от комментариев и стиля программирования).

3. Часто компилятор языка высокого уровня, благодаря современным алгоритмам оптимизации, даёт более эффективную программу (по соотношению качество/время разработки).

4. Непереносимость на другие платформы (кроме совместимых).

5. Ассемблер более сложен для совместных проектов.

4.2. Синтаксис ассемблера.

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

Синтаксис строки имеет следующий общий вид:

Все эти четыре поля необязательны, в программе вполне могут присутствовать и полностью пустые строки для выделения каких либо блоков кода. Метка может быть любой комбинацией букв английского алфавита, цифр и символов _, $, @, ?, но цифра не может быть первым символом метки, а символы $ и ? иногда имеют специальные значения и обычно не рекомендуются к использованию. Большие и маленькие буквы по умолчанию не различаются, но различие можно включить, задав ту или иную опцию в командной строке ассемблера. Во втором поле, поле команды, может располагаться команда процессора, которая транслируется в исполняемый код, или директива, которая не приводит к появлению нового кода, а управляет работой самого ассемблера. В поле операндов располагаются требуемые командой или директивой операнды (то есть нельзя указать операнды и не указать команду или директиву). И наконец, в поле комментариев, начало которого отмечается символом ; (точка с запятой), можно написать все что угодно — текст от символа «;» до конца строки не анализируется ассемблером.

4.3. Ассемблерные вставки в языках высокого уровня.

Языки высокого уровня поддерживают возможность вставки ассемблерного кода. Последовательность команд Ассемблера в С-программе размещается в asm-блоке:

Ассемблерные вставки в c

Лучший отвечающий

Вопрос

  • Перемещено Yatajga Editor 11 октября 2014 г. 5:54
  • Изменено Yatajga Editor 11 октября 2014 г. 5:55 Title

Ответы

Чисто теоретически, вы можете написать dll на ассемблере (или на языке типа C/C++/Delphi со вставками ассемблера), а далее вызывать её в C# с помощью PInvoke.

Или может вы имели в виду CIL?

  • Предложено в качестве ответа Yatajga Editor 21 октября 2014 г. 6:26
  • Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 6 ноября 2014 г. 8:05

Сделаем содержимое сообщества лучше, вместе!

  • Предложено в качестве ответа Yatajga Editor 21 октября 2014 г. 6:26
  • Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 6 ноября 2014 г. 8:05

Все ответы

Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

Сделаем содержимое сообщества лучше, вместе!

  • Предложено в качестве ответа Yatajga Editor 21 октября 2014 г. 6:26
  • Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 6 ноября 2014 г. 8:05

Чисто теоретически, вы можете написать dll на ассемблере (или на языке типа C/C++/Delphi со вставками ассемблера), а далее вызывать её в C# с помощью PInvoke.

Или может вы имели в виду CIL?

  • Предложено в качестве ответа Yatajga Editor 21 октября 2014 г. 6:26
  • Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 6 ноября 2014 г. 8:05

Вопрос, конечно, интересный.
Тем более, что что-то в MSDN-е на эту тему есть —

Но сделать что-либо лично мне пока не удалось,
правда, и времени на это нет,
хотя очень нужно было бы.

QazRdx, скорее всего по вашей ссылке ошибочная информация. Аналогичная статья для VS2013 уже не содержит упоминаний C#.

Есть ещё один способ использовать ассемблер в дотнете: взять C++.NET (managed C++, C++/CLI). В нём можно писать функции на асме.

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector