Помогите пожалуйста разобраться. задача состоит в написании dll использовать 32 бита-это использовать 2 элемента? и сложить элементы массива по минимуму. Заранее спасибо. .586 .XMM .MODEL FLAT PUBLIC _dMMX@12 .CODE _dMMX@12 PROC push ebp mov ebp, esp mov ebx, [ebp+08h];результат сложения mov eax, [ebp+0ch] ;в eax - размер массивов mov esi, [ebp+10h] ;в esi - адрес массива left mov edi, [ebp+14h] ;в edi - адрес массива right the_loop: movq mm0, [esi] ;поместить в регистр mm0 ;элемент массива left movq mm1, [edi] ;поместить в регистр mm1 ;элемент массива right paddb mm0, mm1 ;сложить регистры mm0 и mm1 add ebx, 8 ;следующие 4-ре элемента add esi, 8 ;следующие 4-ре элемента add edi, 8 ;следующие 4-ре элемента sub eax, 4 ;уменьшить значения счетчика jnz short the_loop ;конец цикла? emms pop ebp ret _dMMX@12 ENDP
так же бы хотелось разобраться вот с этим. Может я чего то недопонимаю но эта функция складывает у меня только начальные элементы а остальное выводит не понятно что! unsigned int matrix(unsigned int*rez,unsigned int*left,unsigned int*right,unsigned int n) { unsigned int e,f,h; e=int(&rez[0]); f=int(&left[0]); h=int(&right[0]); asm{ mov ecx, [e] mov esi, [f] mov edi, [h] mov eax, [n] l1: movq mm0, [esi] movq mm1, [edi] paddb mm0, mm1 movq [ecx],mm0 inc esi inc edi inc ecx dec eax jnz l1 emms } return *rez; } Вывод 30 элементов массива: -----all massive------ 0 2 4 6 8 10 12 14 16 1074480402 9403272 9402620 0 536870912 0 9402496 9402496 284 1073897101 0 0 0 0 0 1 1074480507 9402836 9403020 0 536870912 ----end all massive------- 30 Результат должен быть таким: -----all massive------ 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 ----end all massive------- 30
Так этот код нам дал препод.%-) у нас всего несколько лекций было. И я не особо понимаю в нем и сроки сдачи поджимают
А результат ни куда не сохраняется? Наверно надо добавить после сложения movq [ebx],mm0 И что надо складывать байты, слова или двойные слова? В твоем случае складываются байты, а счетчик ты похоже уменьшаешь на количество слов.
складывать надо содержимое элементов массива. Видимо надо складывать dword ptr. И разве он не по адресу сохраняет movq [ecx],mm0?
Ассемблерная функция должна быть похожа на эту и использовать регистры mmx unsigned int matr(unsigned int n,unsigned int * rez,unsigned int *left,unsigned int *right) { unsigned int e; for (e=0;e<n;e++) { rez[e]=left[e]+right[e]; } return *rez; }
Все сделал.Спасибо al79! Осталось сделать сравнение по минимуму pfmin. Для элементов массива и поместить весь код в dll. mov ecx,dword ptr [e]; mov esi,dword ptr [f]; mov edi,dword ptr [h]; mov eax,dword ptr [n]; l1: movq mm0, [esi]; movq mm1, [edi]; paddb mm0, mm1; movq [ecx],dword ptr mm0; add esi,4; add edi,4; add ecx,4; dec eax; jnz short l1; emms;
Тогда наверно должно быть так: Код (Text): mov ecx,dword ptr [e]; mov esi,dword ptr [f]; mov edi,dword ptr [h]; mov eax,dword ptr [n]; l1: movq mm0, [esi]; movq mm1, [edi]; [b]paddw[/b] mm0, mm1; [b]movq [ecx],mm0; [/b] Сохраняем все четыре слова [b]add esi,8; add edi,8; add ecx,8; Смещение на 4 слова sub eax,4;[/b] если в eax у тебя количество переменных то за раз мы складываем 4 слова [b]jnc short l1;[/b] а здесь я думаю лучше сделать так, вдруг количество не кратно 4 emms
Верните редактирование!!! mov ecx,dword ptr [e]; mov esi,dword ptr [f]; mov edi,dword ptr [h]; mov eax,dword ptr [n]; l1: movq mm0, [esi]; movq mm1, [edi]; paddw mm0, mm1; Складываем сразу четыре слова movq [ecx],mm0; Сохраняем все четыре слова add esi,8; add edi,8; add ecx,8; Смещение на 4 слова sub eax,4; если в eax у тебя количество переменных то за раз мы складываем 4 слова jnc short l1; а здесь я думаю лучше сделать так, вдруг количество не кратно 4 emms
Спасибо. Проверил на 1000 элементах выдает результат сходный с функцией на си. for(int i=0;i<n;i++) rez=left+right; //--------------------------- mov eax,dword ptr [e]; //массив куда складываем левый и правый массивы mov esi,dword ptr [l];//массив левый mov edi,dword ptr [r];//массив правый mov ecx,dword ptr [n];//переменная определяющее количество элементов массива. l1: movq mm0, [esi]; movq mm1, [edi]; paddw mm0,mm1; movq [eax],dword ptr mm0; add esi,4; add edi,4; add eax,4;//а разве не 4?если я понял верно то это int и занимает 4? dec ecx;//здесь у меня число n (количество элементов массива). jnz short l1; emms;
paddw складывает 16 битные числа paddd - 32 в mmx регистре 64 бит, paddd за раз складывает два 32-х битных числа . Значит, указатели надо увеличивать на 8, а счетчик уменьшать на 2.
А я думал, что это unsigned long int DWORD занимает 4 байта. А вообще меня ставит в тупик вот эта команда: movq [eax],dword ptr mm0 Неужели она еще и копилируется?
компилируется. Я этот код вытащил при компиляции с параметром -S для с++ builder, на других компиляторах не проверял. А если входящие массивы имеют тип char? rez= (char*)malloc(n*sizeof(char)); left= (char*)malloc(n*sizeof(chart)); right= (char*)malloc(n*sizeof(char));
Наверно будет так: mov eax,dword ptr [e]; //массив куда складываем левый и правый массивы mov edx,dword ptr [l];//массив левый mov edi,dword ptr [r];//массив правый mov ecx,dword ptr [n];//переменная определяющее количество элементов массива. l1: movq mm0, [edx]; paddb mm0,[edi]; - это для CHAR paddw mm0,[edi]; - это для INT paddd mm0,[edi]; - это для LONG INT movq [eax],mm0; add edx,8; add edi,8; add eax,8; смещение делаем 8, MMX регистр 8 байт!!!!!! sub ecx,8; - это для CHAR sub ecx,4; - это для INT sub ecx,2; - это для LONG INT jc l2; это так перестраховаться jnz short l1; l2: emms;