большое спасибо, я в принципе уже понял, что для доступа к массиву нужно использовать регистр, но ваш пример делает даже больше чем я предполагал изначально, т.к. у вас идет преобразование сразу по 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;
}