Форум: "Потрепаться";
Текущий архив: 2003.09.25;
Скачать: [xml.tar.bz2];
ВнизAssembler - NOT с регистром Найти похожие ветки
← →
cyborg (2003-09-06 20:38) [0]Подскажите пожалуйста, чего-то никак не найду выход :(
Нужно сделать подобие булёвского NOT.
Если регистр не ноль, то обнулить, если ноль, то регистр = 1;
Как это сделать быстро?
← →
NightAngel (2003-09-06 22:41) [1]Так?
asm
test eax, eax // if eax!=0
jz @1
xor eax, eax // then eax==0
jmp @2
@1:
inc al // else eax==1
@2:
end;
← →
cyborg (2003-09-06 23:25) [2]Заинтересовался ассамблером, ММХ смотрю, чего-то функция никак не получится у меня по расчёту столкновений прямоугольников:
Function Collision(Rect1,Rect2 : PRect) : LongBool; assembler;
{
Result := (2X2 > 1X1) and
(2Y2 > 1Y1) and
(1X2 > 2X1) and
(1Y2 > 2Y1);
}
asm
movq mm1,[edx]; //Rect1 X1Y1
movq mm2,[edx+$08]; //Rect1 X2Y2
movq mm3,[ecx]; //Rect2 X1Y1
movq mm4,[ecx+$08]; //Rect2 X2Y2
pcmpgtd mm4,mm1; //(2X2 > 1X1) and (2Y2 > 1Y1)
pcmpgtd mm3,mm2; //(1X2 > 2X1) and (1Y2 > 2Y1)
pxor mm5,mm5; //Обнуление регистра mm5
pand mm3,mm4; //Если выполнилось условие что больше, то mm3 будет не ноль.
pcmpeqd mm3,mm5 //Если ноль, то = 1, нет = 0
movd eax,mm3;
psrlq mm3,32;
movd edx,mm3;
or eax,edx;
emms;
end;
Чего-то криво работает :), толи формула неправильная столкновения прямоугольника, толи инструкции не так делаю, помогите пожалуйста.
← →
cyborg (2003-09-07 11:50) [3]Странно, чего-то не то :)
function GetCPUTick: int64; assembler; //Получить значение счётчика тактов процессора
asm
db 0fh,31h; //rdtsc
end;
Function Collision(Rect1,Rect2 : PRect) : LongBool;
begin
{$B-}
Result := (Rect2.Right > Rect1.Left) and
(Rect2.Bottom > Rect1.Top) and
(Rect1.Right > Rect2.Left) and
(Rect1.Bottom > Rect2.Top);
end;
Function CollisionMMX(Rect1,Rect2 : PRect) : LongBool; assembler;
{
Result := (2X2 > 1X1) and
(2Y2 > 1Y1) and
(1X2 > 2X1) and
(1Y2 > 2Y1);
}
asm
movq mm1,[edx]; //Rect1 X1Y1
movq mm2,[edx+$08]; //Rect1 X2Y2
movq mm3,[eax]; //Rect2 X1Y1
movq mm4,[eax+$08]; //Rect2 X2Y2
pcmpgtd mm4,mm1; //(2X2 > 1X1) and (2Y2 > 1Y1)
pcmpgtd mm2,mm3; //(1X2 > 2X1) and (1Y2 > 2Y1)
pxor mm5,mm5; //Обнуление регистра mm5
pand mm2,mm4; //Если выполнилось условие, что больше, то mm2 будет не ноль.
pcmpeqd mm2,mm5 //Если ноль, то = 1, нет = 0
movd eax,mm2;
psrlq mm2,32;
movd edx,mm2;
emms;
or eax,edx;
end;
procedure TForm1.Button1Click(Sender: TObject);
Var
Time1,Time2 : Int64;
I : Integer;
B : LongBool;
PriorityClass, Priority: Integer;
begin
r1.Left:=SpinEdit1.Value;
r1.Top:=SpinEdit2.Value;
r1.Right:=SpinEdit3.Value;
r1.Bottom:=SpinEdit4.Value;
r2.Left:=SpinEdit5.Value;
r2.Top:=SpinEdit6.Value;
r2.Right:=SpinEdit7.Value;
r2.Bottom:=SpinEdit8.Value;
if CollisionMMX(@R1,@R2) then caption:="Есть столкновение!" else caption:="Нет столкновения!";
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
Time1:=GetCPUTick;
For I:=1 to 1000000 do B:=Collision(@R1,@R2);
Time2:=GetCPUTick;
показывает 11 тиков процессора на исполнение
Label5.Caption:=IntToStr((Time2-Time1) div 1000000);
Time1:=GetCPUTick;
For I:=1 to 1000000 do B:=CollisionMMX(@R1,@R2);
Time2:=GetCPUTick;
показывает 2 тика процессора на исполнение (???) странно, не может быть!
Label6.Caption:=IntToStr((Time2-Time1) div 1000000);
Time1:=GetCPUTick;
For I:=1 to 1000000 do
begin
B:=(R2.Right > R1.Left) and
(R2.Bottom > R1.Top) and
(R1.Right > R2.Left) and
(R1.Bottom > R2.Top);
end;
Time2:=GetCPUTick;
показывает 12 тиков процессора на исполнение, почему-то дольше, чем вызов функции!!!
Label7.Caption:=IntToStr((Time2-Time1) div 1000000);
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
end;
И всё равно неправильно определяет столкновение :(.
← →
cyborg (2003-09-07 12:25) [4]Вроде сделал :), работает в 6 раз быстрее, чем паскалевская функция, на моём Дурике 800 функция выполняется 2 такта процессора :).
Function CollisionMMX(Rect1,Rect2 : PRect) : LongBool; assembler;
{ Result := (Rect2.Right > Rect1.Left) and
(Rect2.Bottom > Rect1.Top) and
(Rect1.Right > Rect2.Left) and
(Rect1.Bottom > Rect2.Top);}
asm
movq mm1,[edx]; //Rect1 X1Y1
movq mm2,[edx+$08]; //Rect1 X2Y2
movq mm3,[eax]; //Rect2 X1Y1
movq mm4,[eax+$08]; //Rect2 X2Y2
pcmpgtd mm4,mm1; //(2X2 > 1X1) and (2Y2 > 1Y1)
pcmpgtd mm2,mm3; //(1X2 > 2X1) and (1Y2 > 2Y1)
pand mm2,mm4; //Если выполнилось условие, что больше, то mm2 будет не ноль.
movd eax,mm2;
psrlq mm2,32;
movd edx,mm2;
emms;
or eax,edx;
end;
← →
Anatoly Podgoretsky (2003-09-07 12:28) [5]ADD reg,-1
SBB reg,reg
inc reg
← →
cyborg (2003-09-07 12:43) [6]Это куда? :)
← →
cyborg (2003-09-07 12:49) [7]Ошибку нашёл
вместо or eax,edx;
нужно and eax,edx;
← →
Anatoly Podgoretsky (2003-09-07 12:56) [8]Это сюда cyborg © (06.09.03 20:38)
← →
cyborg (2003-09-07 13:34) [9]Понятно.
А со скоростью облом, я не туда смотрел :), наоборот ММХ самое долго выполняется :(, а 2 тика была обычное сравнение без функции.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2003.09.25;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.012 c