19.07.2019, 04:03 [+3 UTC]
в нашей команде: 3 748 чел. | участники онлайн: 0 (рекорд: 21)

:: РЕГИСТРАЦИЯ

задать вопрос

все разделы

правила

новости

участники

доска почёта

форум

блоги

поиск

статистика

наш журнал

наши встречи

наша галерея

отзывы о нас

поддержка

руководство

Версия системы:
7.77 (31.05.2019)
JS-v.1.34 | CSS-v.3.35

Общие новости:
28.04.2019, 09:13

Форум:
18.07.2019, 12:26

Последний вопрос:
19.07.2019, 02:41
Всего: 149939

Последний ответ:
18.07.2019, 12:04
Всего: 258705

Последняя рассылка:
17.07.2019, 22:15

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
18.09.2009, 10:56 »
Rem88-72
Отличный ответ на мой вопрос! Весь ответ представленн в полном виде. Огромное спасибо! [вопрос № 172285, ответ № 254321]

РАЗДЕЛ • Assembler

Создание программ на языке Assembler.

[администратор рассылки: Лысков Игорь Витальевич (Старший модератор)]

Лучшие эксперты в этом разделе

Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 196
Коцюрбенко Алексей Владимирович
Статус: Модератор
Рейтинг: 141
Лысков Игорь Витальевич
Статус: Старший модератор
Рейтинг: 47

Перейти к консультации №:
 

Консультация онлайн # 143382
Раздел: • Assembler
Автор вопроса: Andrik77
Отправлена: 08.09.2008, 18:12
Поступило ответов: 1

День добрый! Помогите пожалуйста обратиться к элкменту массива из ассемблерной вставки. Задача на с++ перевести float в integer при помощи SSE. Помогите написать её максимально просто.
У меня получается только так:
extern int __stdcall SSE1ConvertR4ToI4(float *p_data, int p_offset, int p_count, int *p_ret)
{
float f;
int result;
do
{
f = p_data[i];
__asm
{
cvttss2si eax, dword ptr[f]
mov dword ptr[result], eax
}
p_ret[i] = result;
i ++;
} while(i < p_count);
return p_count;
}

Помогите мне напрямую обратится к элементам массива, чтобы не делать f = p_data[i]; и p_ret[i] = result;
я как не пробовал, всё время AccessViolation происходит.

Состояние: Консультация закрыта

Ответ # 228838 от Airyashov

Пример:
#include <iostream>

#define N 5

using namespace std;

void main(void)
{
float a[N];
__int32 b[N],i ;
for(i=0;i<N;i++){
cout<<"a["<<i<<"]=";
cin>>a[i];
}

_asm{
MOV eax,N
mov ecx,N
SHR ecx,1
LEA esi, a
LEA edi, b
next:
CVTPS2PI mm0,[esi]
MOVQ [edi],mm0
ADD esi,8
ADD edi,8
LOOP next
TEST eax,1
JZ parity
CVTTSS2SI eax,[esi]
MOV [edi],eax
parity:
}


for(i=0;i<N;i++){
cout<<"b["<<i<<"]="<<b[i]<<endl;
}
cin>>i;
}


Консультировал: Airyashov
Дата отправки: 09.09.2008, 09:52

Рейтинг ответа:

0

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 143382
неизвестный

# 1

= общий = | 10.09.2008, 15:00

большое спасибо, я в принципе уже понял, что для доступа к массиву нужно использовать регистр, но ваш пример делает даже больше чем я предполагал изначально, т.к. у вас идет преобразование сразу по 2 числа.
если кому интересно, привожу получившийся код:

extern int __stdcall SSE1ConvertR4ToI4(float *p_data, int p_offset, int p_count, int *p_ret)
{
if(p_count < 1)
return 0;
if(p_count == 1)
{
p_ret[0] = (int)p_data[p_offset]
return 1;
}

__asm
{
mov eax, dword ptr[p_data] ; берем адрес p_data
mov edx, dword ptr[p_ret] ; берем адрес p_ret
mov ecx, dword ptr[p_offset] ; offset
lea eax, [eax+ecx*4] ; получаем адрес p_data[p_offset]
mov ecx, p_count ; берем p_count
shr ecx, 1 ; делим на 2
_do:
cvttps2pi mm0, [eax] ; переводит 2 float в 2 int (прходится использовать MMX регистры)
movq [edx],mm0 ; записывает результат
add eax, 8 ; += 8 (2 числа по 4 байта)
add edx, 8 ; += 8 (2 числа по 4 байта)
loop _do ; if((ecx --) != 0) goto _do
emms ; нужно отключить работу ММХ (дебагер настаивает)
mov ecx, dword ptr[p_count] ; реальное кол-во
test ecx, 1 ; #result = (ecx&0x01)
jz _end ; if(#result == 0) goto _end //значит четное количество
cvttss2si eax, [eax] ; переводит последнее число float в int
mov [edx], eax ; записывем результат
_end:
}
return p_count;
}


extern int __stdcall SSE1ConvertI4ToR4(int *p_data, int p_offset, int p_count, float *p_ret)
{
if(p_count < 1)
return 0;
if(p_count == 1)
{
p_ret[0] = (float)p_data[p_offset]
return 1;
}

__asm
{
mov eax, dword ptr[p_data] ; берем адрес p_data
mov edx, dword ptr[p_ret] ; берем адрес p_ret
mov ecx, dword ptr[p_offset] ; offset
lea eax, [eax+ecx*4] ; получаем адрес p_data[p_offset]
mov ecx, p_count ; берем p_count
shr ecx, 1 ; делим на 2
_do:
cvtpi2ps xmm0, mmword ptr[eax] ; переводит 2 int в 2 float
movlps [edx],xmm0 ; записывает результат (только младшие 64 бита, т.к. старшие не участвуют)
add eax, 8 ; += 8 (2 числа по 4 байта)
add edx, 8 ; += 8 (2 числа по 4 байта)
loop _do ; if((ecx --) != 0) goto _do
mov ecx, dword ptr[p_count] ; реальное кол-во
test ecx, 1 ; #result = (ecx&0x01)
jz _end ; if(#result == 0) goto _end //значит четное количество
cvtsi2ss xmm0, [eax] ; переводит последнее число int в float
movd [edx], xmm0 ; записывем результат
_end:
}

return p_count;
}

неизвестный

# 2

= общий = | 11.09.2008, 11:17

Подскажите пожалуйста рессурс или документ (желательно на русском), где понятно описываются все команды SSE1,SSE2,SSE3,SSE4
а то, у меня есть смешанные-не полные документы, и боюсь, что на компьютерах, где есть только SEE1 мои процедуры будут давать сбои, т.к. там могут присутствовать команды SSE2 и SSE3

Airyashov

# 3

= общий = | 11.09.2008, 16:15

все здесь
http://www.intel.com/products/processor/manuals/
на русском Н.Голубь "Искусство программирования на ассемблере" 3-е издание, SSE/SSE2/SSE3 - средне описано.

SSE4.1 SSE4.2 - наверное тольку у Интела в c++ компиляторе работает, на 7 делфе и 2005 студии без внешних библитек не пашет.

 

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

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.14621 сек.

© 2001-2019, Портал RFPRO.RU, Россия
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.77 от 31.05.2019
Версия JS: 1.34 | Версия CSS: 3.35