Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.98/47: Рейтинг темы: голосов - 47, средняя оценка - 4.98
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 49

C++ и ассемблерная вставка

16.09.2012, 16:16. Показов 9783. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток.

Необходимо было написать программу, которая складывает попарно числа из 2х массивов обычным способом и с помощью ассемблерной вставки с использованием технологии mmx. Всё казалось бы просто, но я столкнулся с проблемой при компиляции. Вот код самой программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h>
 
int main(){
  int frst_arr[100],scnd_arr[100],res_arr_cpp[100],res_arr_asm[100]; 
  
  clock_t start, end;
  srand(time(0));//заполняю массивы случайными числами
  for(int i=0;i<=99;++i){
    frst_arr[i] = rand() % 10001 - 5000;
    scnd_arr[i] = rand() % 10001 - 5000;
  }
  
  //обычный способ суммирования
  
  start = clock(); 
  for(long int j=0;j<=9999999;++j)//этот цикл необходим, что бы лучше было видно какой способ работает быстрее
    for(int i=0;i<=99;++i)
      res_arr_cpp[i]=frst_arr[i]+scnd_arr[i];
  end = clock();
  float time_cpp = (end - start);
  time_cpp = time_cpp / 1000000;
  printf("%f seconds\n",time_cpp);
  
  //mmx
  
  asm(
      "xor %eax,%eax;"
    "s:cmp %eax,10000000;"
      "je e;"
      "xor %ecx,%ecx;"
    "l:movq %mm0,frst_arr[ecx*8];"
      "movq %mm1,scnd_arr[ecx*8];"
      "paddq %mm0,%mm1;"
      "movq res_arr_asm[ecx*8],%mm0;"
      "inc %ecx;"
      "cmp %ecx,51;"
      "jne l;"
      "inc %eax;"
      "jmp s;"
    "e:emms;"
  );
    
  for(int i=0;i<=99;++i)
    printf("%d %d\n",res_arr_cpp[i],res_arr_asm[i]);
}
А вот что мне "отвечает" компилятор:
Bash
1
2
3
4
5
xxxx@xxxxxxxx:~$ g++ workspace/laba1.cpp -o workspace/zar
workspace/laba1.cpp: Assembler messages:
workspace/laba1.cpp:43: Error: junk `[ecx*8]' after expression
workspace/laba1.cpp:43: Error: junk `[ecx*8]' after expression
workspace/laba1.cpp:43: Error: junk `[ecx*8]' after expression
Подскажите пожалуйста в чем косяк.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.09.2012, 16:16
Ответы с готовыми решениями:

Не работает ассемблерная вставка
Здравствуйте. Захотелось мне как-то отловить переполнения, возникающие во время выполнения арифметических операций. Написал код, с...

Ассемблерная вставка
Товарищи!! кто знает, подскажите как сделать ассемблерную вставку в cи-проекте в среде Turbo C?? я пытался скормить ему asm...,но...

С++ и Ассемблерная вставка/чтение SPD ОЗУ
Добрый день форумчане, делаю программу на подобии CPU-Z, необходимо узнать тайминги и прочую информацию из SPD оперативной памяти. Нашел...

14
539 / 399 / 99
Регистрация: 18.08.2012
Сообщений: 1,024
16.09.2012, 17:35
Ошибся адресом
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 49
16.09.2012, 17:41  [ТС]
Цитата Сообщение от Dmitrinik Посмотреть сообщение
Вот таким образом [ecx*8] процессор не умеет вычислять адреса. Нужно делать add %ecx,<размер элемента массива>
я на самом деле об этом знал, но если даже оставить [ecx], то всё равно выходит ошибка
Bash
1
2
3
workspace/laba1.cpp:43: Error: junk `[ecx]' after expression
workspace/laba1.cpp:43: Error: junk `[ecx]' after expression
workspace/laba1.cpp:43: Error: junk `[ecx]' after expression
0
4189 / 1837 / 220
Регистрация: 06.10.2010
Сообщений: 4,124
17.09.2012, 13:12
[frst_arr+ecx*8]
0
539 / 399 / 99
Регистрация: 18.08.2012
Сообщений: 1,024
17.09.2012, 15:42
Во-первых извиняюсь за сообщение о невозможности адресации вида [ecx*8].
Во-вторых, вот этот код не дает ошибок. Правда, в "Сервис>Параметры>Добавить следующие команды в запуск компилятора" я вставил -masm=intel. Еще описание переменных я вынес над int main(), а в самой ассемблерной вставке их имена надо предварять символом "_" (подчеркивание).

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h>
int frst_arr[100],scnd_arr[100],res_arr_cpp[100],res_arr_asm[100]; 
int main()
{
//  int frst_arr[100],scnd_arr[100],res_arr_cpp[100],res_arr_asm[100]; 
  
  clock_t start, end;
  srand(time(0));//заполняю массивы случайными числами
  for(int i=0;i<=99;++i)
  {
    frst_arr[i] = rand() % 10001 - 5000;
    scnd_arr[i] = rand() % 10001 - 5000;
  }
  
  
  //обычный способ суммирования
  
  start = clock(); 
  for(long int j=0;j<=9999999;++j)//этот цикл необходим, что бы лучше было видно какой способ работает быстрее
    for(int i=0;i<=99;++i)
      res_arr_cpp[i]=frst_arr[i]+scnd_arr[i];
  end = clock();
  float time_cpp = (end - start);
  time_cpp = time_cpp / 1000000;
  printf("%f seconds\n",time_cpp);
  //mmx
  
  __asm(
      "xor %eax,%eax;"
    "s:"
      "cmp %eax,10000000;"
      "je e;"
      "xor %ecx,%ecx;"
    "l:"
      "movq %mm0,_frst_arr[ecx*8];"
      "movq %mm1,_scnd_arr[ecx*8];"
      "paddq %mm0,%mm1;"
      "movq _res_arr_asm[ecx*8],%mm0;"
      "inc %ecx;"
      "cmp %ecx,51;"
      "jne l;"
      "inc %eax;"
      "jmp s;"
    "e:emms;"
  );
 
    
  for(int i=0;i<=99;++i)
    printf("%d %d\n",res_arr_cpp[i],res_arr_asm[i]);
}
0
337 / 4 / 1
Регистрация: 29.11.2011
Сообщений: 39
17.09.2012, 15:51
оригинальный at&t синтаксис выглядит так
Assembler
1
2
3
asm(
    "l: movq %mm0,frst_arr(, %ecx, 8) \n\t"
  );
вот так нормально будет с точки зрения синтаксиса, но линкер такой код не пропустит через себя, потому что frst_arr у тебя локальная переменная, то есть по сути такого имени в программе нет, только в уме компилятора. Поэтому нужно переписать полностью вставку в соответствии с синтаксисом extended asm'a, или делать переменные глобальными
2
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 49
17.09.2012, 22:39  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h>
#include "TPerfMeter.h"
 
int main(){
  int frst_arr[100],scnd_arr[100],res_arr_cpp[100],res_arr_asm[100];
  double t;
  TPerfMeter m;
 
  srand(time(0));
  for(int i=0;i<=99;++i){
    frst_arr[i] = rand() % 5001;
    scnd_arr[i] = rand() % 5001;
  }
  
  //обычный способ сумирования
  
  m.Start();
  for(long int j=0;j<=9999999;++j)
    for(int i=0;i<=99;++i)
      res_arr_cpp[i]=frst_arr[i]+scnd_arr[i];
  t = m.Stop();
  printf("Time: %f ms\n",t);  
    
  //mmx
  
  m.Start();
  for(long int j=0;j<=9999999;++j){
    _asm{
            lea ebx,frst_arr
            lea esi,scnd_arr
            lea edi,res_arr_asm
            mov eax,0
          l:MOVQ mm0,word ptr [ebx]
            PADDD mm0,word ptr [esi]
            MOVQ word ptr [edi],mm0
            add ebx,8
            add esi,8
            add edi,8
            inc eax
            cmp eax,50
            jne l
            emms
       
    }
  }
  t = m.Stop();
  printf("Time: %f ms\n\n",t);  
 
  for(int i=0;i<=99;++i)
    printf("%d) %d %d\n",i+1,res_arr_cpp[i],res_arr_asm[i]);
}
решил не взрывать себе мозг и в visual studio сделал так. всё работает как надо
0
337 / 4 / 1
Регистрация: 29.11.2011
Сообщений: 39
18.09.2012, 15:50
Цитата Сообщение от Armind Посмотреть сообщение
mov eax,0
Цитата Сообщение от Armind Посмотреть сообщение
inc eax
cmp eax,50
jne l
Assembler
1
2
mov $50, %ecx
loop l
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 49
18.09.2012, 18:43  [ТС]
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
asm(
         "lea frst_arr,%ebx;"
         "lea scnd_arr,%esi;"
         "lea res_arr_asm,%edi;"
         "mov $0,%eax;"
       "l:MOVQ (%ebx),%mm0;"
         "PADDD (%esi),%mm0;"
         "MOVQ %mm0,(%edi);"
         "add $8,%ebx;"
         "add $8,%esi;"
         "add $8,%edi;"
         "inc %eax;"
         "cmp $50,%eax;"
         "jne l;"
         "emms;"
    );
полностью рабочее с AT&T синтаксисом
0
337 / 4 / 1
Регистрация: 29.11.2011
Сообщений: 39
18.09.2012, 19:31
нет, не рабочее

Добавлено через 14 минут
с вариантом программы из стартового сообщения это ошибка линковки, как уже было сказано ранее, но даже если сделать переменные глобальными, то всё равно есть ещё одна серьёзная проблема. В extended asm'e есть clobbered list во вставке, затираемые регистры, компилятор например может положить в eax какую-нибудь переменную и работать с ней, когда он встретит правильную асм вставку, в которой указано, что еах затирается, то он после неё снова загрузит переменную в еах, а если он встретит твою вставку, то он будет работать с еах так, будто там до сих лежит его переменная, хотя это уже и неправда, так работает gcc

и после слова асм нужно добавить volatile
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 49
18.09.2012, 19:41  [ТС]
Цитата Сообщение от Super-Windоws Посмотреть сообщение
нет, не рабочее

Добавлено через 14 минут
с вариантом программы из стартового сообщения это ошибка линковки, как уже было сказано ранее, но даже если сделать переменные глобальными, то всё равно есть ещё одна серьёзная проблема. В extended asm'e есть clobbered list во вставке, затираемые регистры, компилятор например может положить в eax какую-нибудь переменную и работать с ней, когда он встретит правильную асм вставку, в которой указано, что еах затирается, то он после неё снова загрузит переменную в еах, а если он встретит твою вставку, то он будет работать с еах так, будто там до сих лежит его переменная, хотя это уже и неправда, так работает gcc

и после слова асм нужно добавить volatile
ога не рабочее) запускаю компилятор, компилирует, запускаю программу и выходят ожидаемые результаты)
0
337 / 4 / 1
Регистрация: 29.11.2011
Сообщений: 39
18.09.2012, 20:20
Цитата Сообщение от Armind Посмотреть сообщение
ога не рабочее) запускаю компилятор, компилирует, запускаю программу и выходят ожидаемые результаты)
а я компилирую, не компилируется, запускаю и вылазит синий экран. Работоспособность твоей программы целиком зависит от опций компилятора, его версии и настроения. Программа, работающая через раз хуже просто неработающей программы. Если не веришь можешь выложить свой код на более компетентный сайт, например stackoverflow и спросить какие проблемы есть в этом коде и тебе ответят тоже самое что и я выше, только по английски
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 49
18.09.2012, 22:22  [ТС]
Bash
1
2
3
xxxxx@xxxxxxxxxx:~$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
и про какой синий экран речь идёт? вы компилируете, у вас может или скомпилироваться или нет, выдав ошибки. или я чего-то не знаю/не понимаю
0
337 / 4 / 1
Регистрация: 29.11.2011
Сообщений: 39
19.09.2012, 14:16
мне не нужен компилятор, ведь и так видно что здесь ошибки линковки будут, символы frst_arr[100],scnd_arr[100],res_arr_cpp[100],res_arr_asm[100] не определены, они выделяются на стеке и недоступны из твоей ассемблерной вставки по имени, и уж тем более эта программа не могла запуститься, как ты говоришь. Это первая ошибка, и вторую я уже озвучивал изменение регистров посреди сишного кода, без уведомления об этом компилятора, соответственно программа может работать правильно, а может и нет, это уж как бог на душу положит. Обе проблемы решаются использованием расширенного ассемблера, вторую можно ещё решить вынесением вставки в отдельную процедуру
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
25.09.2012, 22:45
Цитата Сообщение от Super-Windоws Посмотреть сообщение
вот так нормально будет с точки зрения синтаксиса
В gnu'шных вставках использовать регистры напрямую - плохой стиль. Ну а если всё-таки их использовать, то надо в обязательном порядке их в clobber'ах указывать. А то есть хороший шанс, что компилятор сгенерит неправильный код
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.09.2012, 22:45
Помогаю со студенческими работами здесь

Ассемблерная вставка
Всем доброй ночи!!! Я хочу попросить помощи в решении вот такой функции: Найти целое значение аргумента, при котором значение функции ...

Ассемблерная вставка на С++
Написал сегодня код. int x, y; //Исходные числа float res = 0; //Результат расчетов cin &gt;&gt; x &gt;&gt; y;//Вводи операнды ...

Ассемблерная Вставка
Добрый день. начал изучать ассемблер(начал со вставок, на этом основание пишу здесь). Должен был написать программу, где на Си++ задается...

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

Ассемблерная вставка
#include &lt;iostream&gt; #include &lt;cstdlib&gt; using namespace std; int main() { int x, y; cout &lt;&lt; &quot;Vvedite znachenie x, y: &quot; ; ...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru