Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 53, средняя оценка - 4.85
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
#1

Ошибка компиляции ассемблерной вставки - C++

08.11.2009, 16:39. Просмотров 6699. Ответов 21
Метки нет (Все метки)

Добрый вечер. Захотелось мне сделать ассемблерную вставку в C++ код. Сделал. Но компилятору MinGW чето не нравится. Выдает следующие ошибки в 8 строке:

error: expected `(' before '{' token
error: expected asm body before '{' token


Что я сделал не так ?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
using namespace std;
int main ()
{
    cout << "Сейчас будет звонить!" << endl;
    asm
    {
        /*MOV AH,2
        MOV DL,7
        INT 21H*/
    }
    cout << "Есть!" << endl;
    return 0;
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.11.2009, 16:39     Ошибка компиляции ассемблерной вставки
Посмотрите здесь:

Выполнить с использованием ассемблерной вставки - C++
Нужно подсчитать кол-во цифр в троке из 10 символов. Реализовать в виде ассемблерной вставки. Подскажите пожалуйста как сделать!

Как вывести числа в цикле ассемблерной вставки? - C++
Доброго времени, суток! Мне нужно вывести каждый результат получившийся в цикле, как это можно сделать? _asm { metka: .... ftp...

Получение значения элемента массива с помощью ассемблерной вставки - C++
У меня есть функция int kontr(char* str1, int len) { __asm{ lea esi, ; xor ebx, ebx; mov eax, ; //ну и дальше } ...

Определить размер кеша инструкций первого уровня с помощью ассемблерной вставки - C++
Не знал в каком разделе создать тему, но думаю этот вопрос будет понятен программистам С++. Встала такая задача: определить размер кеша...

С помощью ассемблерной вставки найти отрицательные элементы в массиве, и среднее положительных элементов - C++
Создать массив X. Определить среднее арифметическое положительных чисел, из отрицательных создать массив Y. При этом максимальное и...

С помощью ассемблерной вставки сложить a+b, вывести результат, в переменную bool записать было ли переполнение - C++
Нужно написать ассемблерную вставку Есть переменные unsigned char a,b; bool c; Как с помощью ассемблерной вставки сложить a+b,...

Ошибка с ассемблерной вставкой - C++
#include &lt;iostream&gt; int main() { char src = &quot;hello&quot;, dst; int a = strlen(src); for (int i = 0; i &lt; a; ++i) _asm...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
HIMen
4125 / 1374 / 39
Регистрация: 12.04.2009
Сообщений: 2,346
08.11.2009, 17:50     Ошибка компиляции ассемблерной вставки #2
__asm
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
08.11.2009, 17:54  [ТС]     Ошибка компиляции ассемблерной вставки #3
Цитата Сообщение от HIMen Посмотреть сообщение
__asm
Те же ошибки
Goodwin98
2517 / 813 / 9
Регистрация: 31.05.2009
Сообщений: 1,671
10.11.2009, 19:03     Ошибка компиляции ассемблерной вставки #4
Почитайте тут.

Добавлено через 2 минуты
Цитата Сообщение от RNT Посмотреть сообщение
Но компилятору MinGW чето не нравится. Выдает следующие ошибки в 8 строке:
У него вроде AT&T синтаксис, а не интеловский и команды будут выглядеть по другому.

Примерно так
C++
1
2
3
4
5
    asm ( 
"movb $2,%ah \n" 
"movb $7,%dl\n" 
"int $0x21\n"
);
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
10.11.2009, 19:45  [ТС]     Ошибка компиляции ассемблерной вставки #5
Цитата Сообщение от Goodwin98 Посмотреть сообщение
asm (
"movb $2,%ah \n"
"movb $7,%dl\n"
"int $0x21\n"
);
Компилится. Но возникли следующие вопросы:

1) Как сделать нормальный Intel синтаксис ?
2) Почему команды в круглых скобках а не в фигурных ?
3) Почему каждая команда в кавычках ?
4) Почему в конце каждой команды стоит знак переноса строки ?
5) Почему при построчной отладке программы все ассемблерные команды пропускаются ?
6) Почему после "выполнения" команд в регистрах не оказывается нужного значения ?
Gravity
562 / 556 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
10.11.2009, 20:47     Ошибка компиляции ассемблерной вставки #6
RNT, у каждого компилятора свой синтаксис асм-вставок. MinGW это портированный в винду GCC со своими особенностями. Если понимаешь по англицки, то вот тебе туториал на эту тему http://www.ibiblio.org/gferg/ldp/GCC...bly-HOWTO.html.
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,669
Записей в блоге: 26
10.11.2009, 23:54     Ошибка компиляции ассемблерной вставки #7
Если что - обращайся. Правда я в intel'овском ассемблере ничерта не понимаю, но если объяснишь, что да как должно быть - попробую написать или объяснить. Почитай ещё эту тему. В конечном итоге в посте 49 я наваял конкретную реализацию для поставленного вопроса, но попробуй всю тему прочитать, может среди этого бардака какое-то общее понимание появится
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
11.11.2009, 00:22  [ТС]     Ошибка компиляции ассемблерной вставки #8
Я не понимаю, почему в компилятор GCC засунули ассемблер GAS с чудо-юдо синтаксисом AT&T ? Для него даже книжек почти нет.
Gravity
562 / 556 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
11.11.2009, 00:46     Ошибка компиляции ассемблерной вставки #9
У AT&T нормальный синтаксис и в чем-то даже удобнее интеловского. AT&T асм появился в UNIX, когда интела еще в помине не было и так и остался классическим асмом для юникс-систем. Книги для него, кстати, есть, но все в английском варианте, а на русском можешь почитать статью http://wasm.ru/article.php?article=asm_linux_for_c
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
11.11.2009, 00:56  [ТС]     Ошибка компиляции ассемблерной вставки #10
Цитата Сообщение от Gravity Посмотреть сообщение
Книги для него, кстати, есть, но все в английском варианте


Добавлено через 2 минуты
Значит буду изучать intel`овский синтаксис, я еще не настолько хорошо знаю инглиш
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,669
Записей в блоге: 26
11.11.2009, 09:47     Ошибка компиляции ассемблерной вставки #11
В gcc НЕ "интеловский" или какой-либо другой синтаксис (а точнее, "ФОРМАТ АССЕМЛЕРНОЙ ВСТАВКИ"). Этот синтаксис - единый для ВСЕХ архитектур. Отличие идёт только в constraint'ах (ну и, понятное дело, в самом ассемблерном тексте). Мне уже приходилось писать документацию по формату gnu вставки, сегодня постараюсь на работе найти. Если вдруг случится, что ты это просечёшь досконально, то тогда поймёшь, что более идеально придумать сложно.
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
11.11.2009, 10:37  [ТС]     Ошибка компиляции ассемблерной вставки #12
Не понимаю, объясни пожалуйста попроще.

Цитата Сообщение от Evg Посмотреть сообщение
Этот синтаксис - единый для ВСЕХ архитектур
AT&T ? Он более кроссплатформенный чем Intel-синтаксис ?

Цитата Сообщение от Evg Посмотреть сообщение
Отличие идёт только в constraint'ах
Что это такое ? constraint ?

Я вот нарыл на одном форуме, как сделать чтобы g++ компилил intel-синтаксис.
Надо в консоли делать так: g++ имя_сорца.cpp -masm=intel
http://www.google.ru/search?hl=ru&ne...ng_ru&aq=f&oq=
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,669
Записей в блоге: 26
11.11.2009, 13:48     Ошибка компиляции ассемблерной вставки #13
Сразу на всякий случай скажу: есть два понятия:
- "синтаксис ассемблера" - зависит от архитектуры
- "формат ассемблерной вставки" (ассемблерная вставка это конструкция ЯЗЫКА GNU-C) - от архитектуры не зависит

По поводу документации. Я её нашёл, но хз насколько она окажется полезной. Дело было так, что партия сказала "надо", комсомол сказал "есть" и сделал абы как, лишь бы отстали. Т.е. документация скорее "чтоб было", чем "чтоб можно было пользоваться". Реально она больше введёт в заблуждение, т.к. описано на примере sparc. В общем я дла начала закину, а ты хоть базу почитай

=================================

GNU ассемблерная вставка по замыслу разработчиков является чёрным ящиком с параметрами, т.е. компилятор НЕ видит ассемблерного текста вставки, но видит описание всех ресурсов, которые подаются на вход вставки (input arguments), принимаются с выхода вставки (output arguments) и неявным образом портятся внутри вставки (clobbers)

Формат вставки такой:

C
1
asm ("<asm text>" : <input arguments> : <output arguments> : <clobbers>);
Рассмотрим сначала просто пример, как построить выражение 'x = y + z' при помощи
gnu ассемблерной вставки:

C
1
2
3
4
5
{
  int x, y, z;
  ...
  asm ("add %1, %2, %0" : "=r"(x) : "r"(y), "r"(z));
}
в данном случае:
* "add %1, %2, %0" - текст вставки,
* "=r"(x) - ВЫХодной аргумент (одна штука),
* "r"(y), "r"(z) - ВХодные аргументы (две штуки, перечисленные через запятую).
* clobber'ы в данной вставке отсутствуют, а потому не написаны

Описание аргументов вставки состоит из двух частей - в кавычках пишется модификатор (FIXME КАК ПРАВИЛЬНО НАЗЫВАЕТСЯ???) (только для output аргументов) и описание аппаратного ресурса, на который должен быть загружен аргумент вставки (это называют словом constraint). В круглых скобках пишется значение (value) аргумента: для input аргумента это rvalue expression (выражение, которое может стоять в правой части присваивания), для output аргумента - это lvalue expression (соответственно, выражение, которое может стоять в левой части присваивания)

Более детально будет расписано ниже, а пока только применительно к данному примеру. У output аргумента "=r"(x) в качестве модификатора стоИт символ '=', что означает аргумент строго на запись. В качестве constraint стоИт символ 'r', что означает целочисленный регистр, доступный компилятору для распределения. В качестве value стоИт x, это означает, что после кода вставки значение упомянутого регистра будет записано в переменную x. У input аргумента "r"(y) в качестве constraint так же стоит целочисленный регистр, в качестве value стоИт y, что означает, что перед кодом вставки значение переменной y будет загружено на регистр, который затем будет использоваться во вставке.

Текст вставки - это то, что в итоге попадает в выходной ассемблерный код, который строит компилятор. Символ % является управляющим. %0, %1 и %2 соответсвуют номерам аргументов в порядке их перечисления в конструкции asm начиная с нуля. В данном случае %0 соответствует аргументу "=r"(x), %1 соответствует аргументу "r"(y), а %2 соответствует аргументу "r"(z).

Добавлено через 56 секунд
Ну и в добавок, ты всегда можешь запустить gcc/g++ с опцией -S и посмотреть результирующий ассемблерный файл (чтобы визуально оценить, насколько правильный код построился)
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
11.11.2009, 15:04  [ТС]     Ошибка компиляции ассемблерной вставки #14
Цитата Сообщение от Evg Посмотреть сообщение
asm ("add %1, %2, %0" : "=r"(x) : "r"(y), "r"(z));
Ты кажется перепутал порядок управляющих символов. Я правильно поправил ?

C++
1
asm ("add %0, %1, %2" : "=r"(x) : "r"(y), "r"(z));
Я попробовал скомпилировать твой код, выдается ошибка Error: suffix or operands invalid for `add' в строке 119. Такой строки в моем коротеньком исходнике нет.

C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
 
int main()
{
    int x=0, y=6, z=7;
    asm ("add %1, %2, %0" : "=r"(x) : "r"(y), "r"(z));
    cout << x;
    return 0;
}
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,669
Записей в блоге: 26
11.11.2009, 15:16     Ошибка компиляции ассемблерной вставки #15
> Ты кажется перепутал порядок управляющих символов. Я правильно поправил ?

У меня всё правильно. Для sparc'овской операции формат такой "add src1, src2, dst"

Добавлено через 1 минуту
> Я попробовал скомпилировать твой код

Это для sparc'а, а не для intel'а. Скажи мне, как на intel'е делается сложение, и я тебе исходник напишу. Эту ошибку выдаёт ассемблер, а не компилятор. gcc вовнутрь вставки вообще не лезет, только подставляет операнды на нужные позиции
Gravity
562 / 556 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
11.11.2009, 15:21     Ошибка компиляции ассемблерной вставки #16
Для интела будет так выглядеть
C++
1
asm ("add %0, %1" : "=m"(x) : "r"(y));
add принимает два операнда. Компилировать надо с флагом intel, иначе не фкурит.

Мне кажется, что проще писать процедуру на асме отдельным файлом и собирать вместе с основным проектом на си, если так хочется поюзать ассемблер.
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,669
Записей в блоге: 26
11.11.2009, 15:30     Ошибка компиляции ассемблерной вставки #17
Gravity, у тебя задан двухоперандный случай. К тому же правильно помечать "+m", а не "=m". Вариант с оформлением в виде отдельной процедуры (для трёхаргументного вычитания):

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
int
asm_sub (int src1, int src2)
{
  register int dst;
 
  asm ("subl %2, %0" : "=&r" (dst) : "0" (src1), "r" (src2));
 
  return dst;
}
 
int main (void)
{
  printf ("%d\n", asm_sub (15, 23));
  return 0;
}
Добавлено через 25 секунд
Цитата Сообщение от Gravity Посмотреть сообщение
Мне кажется, что проще писать процедуру на асме отдельным файлом и собирать вместе с основным проектом на си, если так хочется поюзать ассемблер.
В этом случае ты зарубаешь возможность inline'а
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
11.11.2009, 15:59  [ТС]     Ошибка компиляции ассемблерной вставки #18
Подскажите пожалуйста книжки или статьи, где можно основательно почитать про то, как делать ассемблерные вставки в C/C++.
Evg
Эксперт CАвтор FAQ
17469 / 5707 / 362
Регистрация: 30.03.2009
Сообщений: 15,669
Записей в блоге: 26
11.11.2009, 16:10     Ошибка компиляции ассемблерной вставки #19
Сообщение было отмечено автором темы, экспертом или модератором как ответ
По поводу inline'а лучше поясню на более конкретном примере. Допустим, мы имеем интерфейс для некоторых небольших действий. Что-то мудрённое писатьне будем, а ограничимся операциями сложения и вычитания (чтобы меньше было в коде текста и проще было понять суть). Пусть интерфейсы называются asm_add и asm_sub соотвественно. Таким образом мы реализуем некие кубики, из которых можно будет строить более объёмные блоки. В данном примере в качестве блока реализуем функцию func от трёх параметров, которая реализует свёртку "x+y-z"

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* Файл t.h */
 
static inline int
asm_add (int src1, int src2)
{
  register int dst;
 
  asm ("addl %2, %0" : "=&r" (dst) : "0" (src1), "r" (src2));
 
  return dst;
}
 
static inline int
asm_sub (int src1, int src2)
{
  register int dst;
 
  asm ("subl %2, %0" : "=&r" (dst) : "0" (src1), "r" (src2));
 
  return dst;
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* Файл t.c */
 
#include <stdio.h>
#include "t.h"
 
int
func (int x, int y, int z)
{
  int a, b;
  
  a = asm_add (x, y);
  b = asm_sub (a, z);
  
  return b;
}
В итоге, имеем следующий код:

Код
$ gcc t.c -O2 -S
$ cat t.s
        .file   "t.c"
        .text
        .p2align 4,,15
.globl func
        .type   func, @function
func:
        pushl   %ebp
        movl    %esp, %ebp
        movl    12(%ebp), %edx
        movl    16(%ebp), %ecx
        movl    8(%ebp), %eax
        popl    %ebp
#APP
        addl %edx, %eax
        subl %ecx, %eax
#NO_APP
        ret
        .size   func, .-func
        .ident  "GCC: (GNU) 4.1.2 (Gentoo 4.1.2 p1.1)"
        .section        .note.GNU-stack,"",@progbits
В итоге компилятор все наши static inline процедуры подставил (а коды самих процедур удалил) и мы получили "быструю" функцию func, в которой функциональная часть - это две наши операции addl и subl, всё остальное - это работа по перенесению параметров из стека на регистр и сохранение frame-pointer'а. Если бы мы функции asm_add и asm_sub написале в виде процедур на ассемблере в отдельном ассемблерном файле, то компилятор бы подстановку в принципе не смог сделать и быстрый "блок из кубиков" реализовать бы не получилось

В данном случае весь интерфейс у нас реализован в виде процедур на языке GNU-C, который другие компиляторы не понимают. При использовании другого компилятора нам бы нужно было подхачить только "кубиковый" файл t.h и как-то на языке или каким-либо другим способом написать функции, которые выполняют нужные действия. Пусть они будут не на ассемблере, пусть они получатся медленными, но мы исправили только самый нижний уровень, не трогая при этом весь остальной код. В итоге программу заставили работать, пусть и медленнее, чем можно было бы, но для первого шага этого оказалось бы достаточно. Этот абзац уже относится не столько к ассемблерным вставкам, сколько к технике программирования и реализации архитектурно-зависимых частей в виде маленьких кубиков

Добавлено через 1 минуту
Цитата Сообщение от RNT Посмотреть сообщение
Подскажите пожалуйста книжки или статьи, где можно основательно почитать про то, как делать ассемблерные вставки в C/C++.
Анус состоит в том, что по этому поводу по большому счёту нигде нет внятной литературы. Есть техническая документация по gcc, но она слишком ублюдочная. Это хорошая тема для FAQ'а, но чтоды описать доступно, надо будет попотеть и придумать хотя бы с какого боку начать пояснения. Я имею в виду gcc. А общего механизма нет, в каждом компиляторе он реализован по-своему
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2009, 16:15     Ошибка компиляции ассемблерной вставки
Еще ссылки по теме:

Ассемблерные вставки, ошибка - C++
Ошибка: 0xC0000095: Integer overflow. Код: mov eax,x sub eax,a mov ebx,x sub ebx,c div ebx - здесь ошибка mov f,ebx

Ошибка вставки библиотеки ctype - C++
Делаю упражнение на наследование #include&lt;iostream&gt; using namespace std; #include&lt;string&gt; #include&lt;sstream&gt; #include&lt;ctype&gt; ...

ошибка в процедуре вставки в упор. массив - C++
void insert (int a,int &amp;n,int x) { int i=n; int j=n+1; while (a&gt;x) a=a; a=x; if (j!=0) while (j&gt;=0) a=a; ...

ошибка компиляции - C++
Задача Даны действительная матрица размера действительные числа , натуральные числа р, q . Образовать новую матрицу размера ...

Ошибка компиляции - C++ Builder
Доброго времени суток, недоустановил компонент до конца и начались глюки выдаёт такую ошибку


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
RNT
Автор FAQ
3133 / 353 / 3
Регистрация: 08.08.2009
Сообщений: 1,126
11.11.2009, 16:15  [ТС]     Ошибка компиляции ассемблерной вставки #20
Цитата Сообщение от Evg Посмотреть сообщение
Анус состоит в том, что по этому поводу по большому счёту нигде нет внятной литературы.
Evg, а как ты это изучил ?
Yandex
Объявления
11.11.2009, 16:15     Ошибка компиляции ассемблерной вставки
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru