Консультация № 143382
08.09.2008, 18:12
0.00 руб.
0 4 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 происходит.

Обсуждение

Неизвестный
09.09.2008, 09:52
общий
это ответ
Пример:
#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;
}
Неизвестный
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;
}
Неизвестный
11.09.2008, 11:17
общий
Подскажите пожалуйста рессурс или документ (желательно на русском), где понятно описываются все команды SSE1,SSE2,SSE3,SSE4
а то, у меня есть смешанные-не полные документы, и боюсь, что на компьютерах, где есть только SEE1 мои процедуры будут давать сбои, т.к. там могут присутствовать команды SSE2 и SSE3
Неизвестный
11.09.2008, 16:15
общий
все здесь
http://www.intel.com/products/processor/manuals/
на русском Н.Голубь "Искусство программирования на ассемблере" 3-е издание, SSE/SSE2/SSE3 - средне описано.

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